1
/**************************************************************************
3
* Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
6
* Permission is hereby granted, free of charge, to any person obtaining a
7
* copy of this software and associated documentation files (the
8
* "Software"), to deal in the Software without restriction, including
9
* without limitation the rights to use, copy, modify, merge, publish,
10
* distribute, sub license, and/or sell copies of the Software, and to
11
* permit persons to whom the Software is furnished to do so, subject to
12
* the following conditions:
14
* The above copyright notice and this permission notice (including the
15
* next paragraph) shall be included in all copies or substantial portions
18
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21
* IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
22
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
**************************************************************************/
31
#include "intel_context.h"
32
#include "intel_mipmap_tree.h"
33
#include "intel_tex.h"
37
* Compute which mipmap levels that really need to be sent to the hardware.
38
* This depends on the base image size, GL_TEXTURE_MIN_LOD,
39
* GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL.
41
static void intel_calculate_first_last_level( struct intel_texture_object *intelObj )
43
struct gl_texture_object *tObj = &intelObj->base;
44
const struct gl_texture_image * const baseImage =
45
tObj->Image[0][tObj->BaseLevel];
47
/* These must be signed values. MinLod and MaxLod can be negative numbers,
48
* and having firstLevel and lastLevel as signed prevents the need for
54
/* Yes, this looks overly complicated, but it's all needed.
56
switch (tObj->Target) {
60
case GL_TEXTURE_CUBE_MAP:
61
if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) {
62
/* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL.
64
firstLevel = lastLevel = tObj->BaseLevel;
67
/* Currently not taking min/max lod into account here, those
68
* values are programmed as sampler state elsewhere and we
69
* upload the same mipmap levels regardless. Not sure if
70
* this makes sense as it means it isn't possible for the app
71
* to use min/max lod to reduce texture memory pressure:
73
firstLevel = tObj->BaseLevel;
74
lastLevel = MIN2(tObj->BaseLevel + baseImage->MaxLog2,
76
lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
79
case GL_TEXTURE_RECTANGLE_NV:
80
case GL_TEXTURE_4D_SGIS:
81
firstLevel = lastLevel = 0;
87
/* save these values */
88
intelObj->firstLevel = firstLevel;
89
intelObj->lastLevel = lastLevel;
92
static GLboolean copy_image_data_to_tree( struct intel_context *intel,
93
struct intel_texture_object *intelObj,
94
struct gl_texture_image *texImage,
98
return intel_miptree_image_data(intel,
104
(texImage->RowStride *
106
texImage->TexFormat->TexelBytes));
109
static void intel_texture_invalidate( struct intel_texture_object *intelObj )
111
GLint nr_faces, face;
112
intelObj->dirty = ~0;
114
nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
115
for (face = 0; face < nr_faces; face++)
116
intelObj->dirty_images[face] = ~0;
119
static void intel_texture_invalidate_cb( struct intel_context *intel,
122
intel_texture_invalidate( (struct intel_texture_object *) ptr );
128
GLuint intel_finalize_mipmap_tree( struct intel_context *intel,
129
struct gl_texture_object *tObj )
131
struct intel_texture_object *intelObj = intel_texture_object(tObj);
134
struct gl_texture_image *firstImage;
136
if( tObj == intel->frame_buffer_texobj )
139
/* We know/require this is true by now:
141
assert(intelObj->base.Complete);
143
/* What levels must the tree include at a minimum?
145
if (intelObj->dirty) {
146
intel_calculate_first_last_level( intelObj );
147
/* intel_miptree_destroy(intel, intelObj->mt); */
148
/* intelObj->mt = NULL; */
151
firstImage = intelObj->base.Image[0][intelObj->firstLevel];
155
if (firstImage->Border) {
157
intel_miptree_destroy(intel, intelObj->mt);
159
/* Set all images dirty:
161
intel_texture_invalidate(intelObj);
168
/* Check tree can hold all active levels. Check tree matches
169
* target, imageFormat, etc.
172
(intelObj->mt->target != intelObj->base.Target ||
173
intelObj->mt->internal_format != firstImage->InternalFormat ||
174
intelObj->mt->first_level != intelObj->firstLevel ||
175
intelObj->mt->last_level != intelObj->lastLevel ||
176
intelObj->mt->width0 != firstImage->Width ||
177
intelObj->mt->height0 != firstImage->Height ||
178
intelObj->mt->depth0 != firstImage->Depth ||
179
intelObj->mt->cpp != firstImage->TexFormat->TexelBytes ||
180
intelObj->mt->compressed != firstImage->IsCompressed))
182
intel_miptree_destroy(intel, intelObj->mt);
185
/* Set all images dirty:
187
intel_texture_invalidate(intelObj);
191
/* May need to create a new tree:
194
intelObj->mt = intel_miptree_create(intel,
195
intelObj->base.Target,
196
firstImage->InternalFormat,
197
intelObj->firstLevel,
202
firstImage->TexFormat->TexelBytes,
203
firstImage->IsCompressed);
205
/* Tell the buffer manager that we will manage the backing
206
* store, but we still want it to do fencing for us.
208
bmBufferSetInvalidateCB(intel,
209
intelObj->mt->region->buffer,
210
intel_texture_invalidate_cb,
215
/* Pull in any images not in the object's tree:
217
if (intelObj->dirty) {
218
nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1;
219
for (face = 0; face < nr_faces; face++) {
220
if (intelObj->dirty_images[face]) {
221
for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) {
222
struct gl_texture_image *texImage = intelObj->base.Image[face][i];
224
/* Need to import images in main memory or held in other trees.
226
if (intelObj->dirty_images[face] & (1<<i) &&
229
if (INTEL_DEBUG & DEBUG_TEXTURE)
230
_mesa_printf("copy data from image %d (%p) into object miptree\n",
234
if (!copy_image_data_to_tree(intel,
246
/* Only clear the dirty flags if everything went ok:
248
for (face = 0; face < nr_faces; face++) {
249
intelObj->dirty_images[face] = 0;