intel_tex_validate.c revision 973e821a633031fe5a8608b50beabb10af21430e
1#include "main/mtypes.h" 2#include "main/macros.h" 3 4#include "intel_context.h" 5#include "intel_mipmap_tree.h" 6#include "intel_tex.h" 7 8#define FILE_DEBUG_FLAG DEBUG_TEXTURE 9 10/** 11 * Compute which mipmap levels that really need to be sent to the hardware. 12 * This depends on the base image size, GL_TEXTURE_MIN_LOD, 13 * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. 14 */ 15static void 16intel_calculate_first_last_level(struct intel_context *intel, 17 struct intel_texture_object *intelObj) 18{ 19 struct gl_texture_object *tObj = &intelObj->base; 20 const struct gl_texture_image *const baseImage = 21 tObj->Image[0][tObj->BaseLevel]; 22 23 /* These must be signed values. MinLod and MaxLod can be negative numbers, 24 * and having firstLevel and lastLevel as signed prevents the need for 25 * extra sign checks. 26 */ 27 int firstLevel = tObj->BaseLevel; 28 int lastLevel; 29 30 /* Yes, this looks overly complicated, but it's all needed. 31 */ 32 if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { 33 /* GL_NEAREST and GL_LINEAR only care about GL_TEXTURE_BASE_LEVEL. 34 */ 35 lastLevel = tObj->BaseLevel; 36 } else { 37 /* Min/max LOD are taken into account in sampler state. We don't 38 * want to re-layout textures just because clamping has been applied 39 * since it means a bunch of blitting around and probably no memory 40 * savings (since we have to keep the other levels around anyway). 41 */ 42 lastLevel = MIN2(tObj->BaseLevel + baseImage->MaxLog2, 43 tObj->MaxLevel); 44 /* need at least one level */ 45 lastLevel = MAX2(firstLevel, lastLevel); 46 } 47 48 /* save these values */ 49 intelObj->firstLevel = firstLevel; 50 intelObj->lastLevel = lastLevel; 51} 52 53/** 54 * Copies the image's contents at its level into the object's miptree, 55 * and updates the image to point at the object's miptree. 56 */ 57static void 58copy_image_data_to_tree(struct intel_context *intel, 59 struct intel_texture_object *intelObj, 60 struct intel_texture_image *intelImage) 61{ 62 if (intelImage->mt) { 63 /* Copy potentially with the blitter: 64 */ 65 intel_miptree_image_copy(intel, 66 intelObj->mt, 67 intelImage->face, 68 intelImage->level, intelImage->mt); 69 70 intel_miptree_release(intel, &intelImage->mt); 71 } 72 else { 73 assert(intelImage->base.Data != NULL); 74 75 /* More straightforward upload. 76 */ 77 intel_miptree_image_data(intel, 78 intelObj->mt, 79 intelImage->face, 80 intelImage->level, 81 intelImage->base.Data, 82 intelImage->base.RowStride, 83 intelImage->base.RowStride * 84 intelImage->base.Height); 85 _mesa_align_free(intelImage->base.Data); 86 intelImage->base.Data = NULL; 87 } 88 89 intel_miptree_reference(&intelImage->mt, intelObj->mt); 90} 91 92 93/* 94 */ 95GLuint 96intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) 97{ 98 struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current; 99 struct intel_texture_object *intelObj = intel_texture_object(tObj); 100 int comp_byte = 0; 101 int cpp; 102 GLuint face, i; 103 GLuint nr_faces = 0; 104 struct intel_texture_image *firstImage; 105 106 /* We know/require this is true by now: 107 */ 108 assert(intelObj->base._Complete); 109 110 /* What levels must the tree include at a minimum? 111 */ 112 intel_calculate_first_last_level(intel, intelObj); 113 firstImage = intel_texture_image(tObj->Image[0][intelObj->firstLevel]); 114 115 /* Fallback case: 116 */ 117 if (firstImage->base.Border) { 118 if (intelObj->mt) { 119 intel_miptree_release(intel, &intelObj->mt); 120 } 121 return GL_FALSE; 122 } 123 124 125 /* If both firstImage and intelObj have a tree which can contain 126 * all active images, favour firstImage. Note that because of the 127 * completeness requirement, we know that the image dimensions 128 * will match. 129 */ 130 if (firstImage->mt && 131 firstImage->mt != intelObj->mt && 132 firstImage->mt->first_level <= intelObj->firstLevel && 133 firstImage->mt->last_level >= intelObj->lastLevel) { 134 135 if (intelObj->mt) 136 intel_miptree_release(intel, &intelObj->mt); 137 138 intel_miptree_reference(&intelObj->mt, firstImage->mt); 139 } 140 141 if (_mesa_is_format_compressed(firstImage->base.TexFormat)) { 142 comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat); 143 cpp = comp_byte; 144 } 145 else 146 cpp = _mesa_get_format_bytes(firstImage->base.TexFormat); 147 148 /* Check tree can hold all active levels. Check tree matches 149 * target, imageFormat, etc. 150 * 151 * XXX: For some layouts (eg i945?), the test might have to be 152 * first_level == firstLevel, as the tree isn't valid except at the 153 * original start level. Hope to get around this by 154 * programming minLod, maxLod, baseLevel into the hardware and 155 * leaving the tree alone. 156 */ 157 if (intelObj->mt && 158 (intelObj->mt->target != intelObj->base.Target || 159 intelObj->mt->internal_format != firstImage->base.InternalFormat || 160 intelObj->mt->first_level != intelObj->firstLevel || 161 intelObj->mt->last_level != intelObj->lastLevel || 162 intelObj->mt->width0 != firstImage->base.Width || 163 intelObj->mt->height0 != firstImage->base.Height || 164 intelObj->mt->depth0 != firstImage->base.Depth || 165 intelObj->mt->cpp != cpp || 166 intelObj->mt->compressed != _mesa_is_format_compressed(firstImage->base.TexFormat))) { 167 intel_miptree_release(intel, &intelObj->mt); 168 } 169 170 171 /* May need to create a new tree: 172 */ 173 if (!intelObj->mt) { 174 intelObj->mt = intel_miptree_create(intel, 175 intelObj->base.Target, 176 firstImage->base._BaseFormat, 177 firstImage->base.InternalFormat, 178 intelObj->firstLevel, 179 intelObj->lastLevel, 180 firstImage->base.Width, 181 firstImage->base.Height, 182 firstImage->base.Depth, 183 cpp, 184 comp_byte, 185 GL_TRUE); 186 } 187 188 /* Pull in any images not in the object's tree: 189 */ 190 nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 191 for (face = 0; face < nr_faces; face++) { 192 for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) { 193 struct intel_texture_image *intelImage = 194 intel_texture_image(intelObj->base.Image[face][i]); 195 196 /* Need to import images in main memory or held in other trees. 197 * If it's a render target, then its data isn't needed to be in 198 * the object tree (otherwise we'd be FBO incomplete), and we need 199 * to keep track of the image's MT as needing to be pulled in still, 200 * or we'll lose the rendering that's done to it. 201 */ 202 if (intelObj->mt != intelImage->mt && 203 !intelImage->used_as_render_target) { 204 copy_image_data_to_tree(intel, intelObj, intelImage); 205 } 206 } 207 } 208 209 return GL_TRUE; 210} 211 212void 213intel_tex_map_level_images(struct intel_context *intel, 214 struct intel_texture_object *intelObj, 215 int level) 216{ 217 GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 218 GLuint face; 219 220 for (face = 0; face < nr_faces; face++) { 221 struct intel_texture_image *intelImage = 222 intel_texture_image(intelObj->base.Image[face][level]); 223 224 if (intelImage && intelImage->mt) { 225 intelImage->base.Data = 226 intel_miptree_image_map(intel, 227 intelImage->mt, 228 intelImage->face, 229 intelImage->level, 230 &intelImage->base.RowStride, 231 intelImage->base.ImageOffsets); 232 /* convert stride to texels, not bytes */ 233 intelImage->base.RowStride /= intelImage->mt->cpp; 234 /* intelImage->base.ImageStride /= intelImage->mt->cpp; */ 235 } 236 } 237} 238 239void 240intel_tex_unmap_level_images(struct intel_context *intel, 241 struct intel_texture_object *intelObj, 242 int level) 243{ 244 GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 245 GLuint face; 246 247 for (face = 0; face < nr_faces; face++) { 248 struct intel_texture_image *intelImage = 249 intel_texture_image(intelObj->base.Image[face][level]); 250 251 if (intelImage && intelImage->mt) { 252 intel_miptree_image_unmap(intel, intelImage->mt); 253 intelImage->base.Data = NULL; 254 } 255 } 256} 257 258void 259intel_tex_map_images(struct intel_context *intel, 260 struct intel_texture_object *intelObj) 261{ 262 int i; 263 264 DBG("%s\n", __FUNCTION__); 265 266 for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) 267 intel_tex_map_level_images(intel, intelObj, i); 268} 269 270void 271intel_tex_unmap_images(struct intel_context *intel, 272 struct intel_texture_object *intelObj) 273{ 274 int i; 275 276 for (i = intelObj->firstLevel; i <= intelObj->lastLevel; i++) 277 intel_tex_unmap_level_images(intel, intelObj, i); 278} 279