intel_tex_validate.c revision 6547253bd138db815173c00ca2dc220e8ad20ab1
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 * When validating, we only care about the texture images that could 12 * be seen, so for non-mipmapped modes we want to ignore everything 13 * but BaseLevel. 14 */ 15static void 16intel_update_max_level(struct intel_context *intel, 17 struct intel_texture_object *intelObj) 18{ 19 struct gl_texture_object *tObj = &intelObj->base; 20 21 if (tObj->MinFilter == GL_NEAREST || tObj->MinFilter == GL_LINEAR) { 22 intelObj->_MaxLevel = tObj->BaseLevel; 23 } else { 24 intelObj->_MaxLevel = tObj->_MaxLevel; 25 } 26} 27 28/** 29 * Copies the image's contents at its level into the object's miptree, 30 * and updates the image to point at the object's miptree. 31 */ 32static void 33copy_image_data_to_tree(struct intel_context *intel, 34 struct intel_texture_object *intelObj, 35 struct intel_texture_image *intelImage) 36{ 37 if (intelImage->mt) { 38 /* Copy potentially with the blitter: 39 */ 40 intel_miptree_image_copy(intel, 41 intelObj->mt, 42 intelImage->face, 43 intelImage->level, intelImage->mt); 44 45 intel_miptree_release(intel, &intelImage->mt); 46 } 47 else { 48 assert(intelImage->base.Data != NULL); 49 50 /* More straightforward upload. 51 */ 52 intel_miptree_image_data(intel, 53 intelObj->mt, 54 intelImage->face, 55 intelImage->level, 56 intelImage->base.Data, 57 intelImage->base.RowStride, 58 intelImage->base.RowStride * 59 intelImage->base.Height); 60 _mesa_align_free(intelImage->base.Data); 61 intelImage->base.Data = NULL; 62 } 63 64 intel_miptree_reference(&intelImage->mt, intelObj->mt); 65} 66 67 68/* 69 */ 70GLuint 71intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) 72{ 73 struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current; 74 struct intel_texture_object *intelObj = intel_texture_object(tObj); 75 int comp_byte = 0; 76 int cpp; 77 GLuint face, i; 78 GLuint nr_faces = 0; 79 struct intel_texture_image *firstImage; 80 81 /* We know/require this is true by now: 82 */ 83 assert(intelObj->base._Complete); 84 85 /* What levels must the tree include at a minimum? 86 */ 87 intel_update_max_level(intel, intelObj); 88 firstImage = intel_texture_image(tObj->Image[0][tObj->BaseLevel]); 89 90 /* Fallback case: 91 */ 92 if (firstImage->base.Border) { 93 if (intelObj->mt) { 94 intel_miptree_release(intel, &intelObj->mt); 95 } 96 return GL_FALSE; 97 } 98 99 if (_mesa_is_format_compressed(firstImage->base.TexFormat)) { 100 comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat); 101 cpp = comp_byte; 102 } 103 else 104 cpp = _mesa_get_format_bytes(firstImage->base.TexFormat); 105 106 /* Check tree can hold all active levels. Check tree matches 107 * target, imageFormat, etc. 108 * 109 * For pre-gen4, we have to match first_level == tObj->BaseLevel, 110 * because we don't have the control that gen4 does to make min/mag 111 * determination happen at a nonzero (hardware) baselevel. Because 112 * of that, we just always relayout on baselevel change. 113 */ 114 if (intelObj->mt && 115 (intelObj->mt->target != intelObj->base.Target || 116 intelObj->mt->internal_format != firstImage->base.InternalFormat || 117 intelObj->mt->first_level != tObj->BaseLevel || 118 intelObj->mt->last_level < intelObj->_MaxLevel || 119 intelObj->mt->width0 != firstImage->base.Width || 120 intelObj->mt->height0 != firstImage->base.Height || 121 intelObj->mt->depth0 != firstImage->base.Depth || 122 intelObj->mt->cpp != cpp || 123 intelObj->mt->compressed != _mesa_is_format_compressed(firstImage->base.TexFormat))) { 124 intel_miptree_release(intel, &intelObj->mt); 125 } 126 127 128 /* May need to create a new tree: 129 */ 130 if (!intelObj->mt) { 131 intelObj->mt = intel_miptree_create(intel, 132 intelObj->base.Target, 133 firstImage->base._BaseFormat, 134 firstImage->base.InternalFormat, 135 tObj->BaseLevel, 136 intelObj->_MaxLevel, 137 firstImage->base.Width, 138 firstImage->base.Height, 139 firstImage->base.Depth, 140 cpp, 141 comp_byte, 142 GL_TRUE); 143 if (!intelObj->mt) 144 return GL_FALSE; 145 } 146 147 /* Pull in any images not in the object's tree: 148 */ 149 nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 150 for (face = 0; face < nr_faces; face++) { 151 for (i = tObj->BaseLevel; i <= intelObj->_MaxLevel; i++) { 152 struct intel_texture_image *intelImage = 153 intel_texture_image(intelObj->base.Image[face][i]); 154 /* skip too small size mipmap */ 155 if (intelImage == NULL) 156 break; 157 /* Need to import images in main memory or held in other trees. 158 * If it's a render target, then its data isn't needed to be in 159 * the object tree (otherwise we'd be FBO incomplete), and we need 160 * to keep track of the image's MT as needing to be pulled in still, 161 * or we'll lose the rendering that's done to it. 162 */ 163 if (intelObj->mt != intelImage->mt && 164 !intelImage->used_as_render_target) { 165 copy_image_data_to_tree(intel, intelObj, intelImage); 166 } 167 } 168 } 169 170 return GL_TRUE; 171} 172 173void 174intel_tex_map_level_images(struct intel_context *intel, 175 struct intel_texture_object *intelObj, 176 int level) 177{ 178 GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 179 GLuint face; 180 181 for (face = 0; face < nr_faces; face++) { 182 struct intel_texture_image *intelImage = 183 intel_texture_image(intelObj->base.Image[face][level]); 184 185 if (intelImage && intelImage->mt) { 186 intelImage->base.Data = 187 intel_miptree_image_map(intel, 188 intelImage->mt, 189 intelImage->face, 190 intelImage->level, 191 &intelImage->base.RowStride, 192 intelImage->base.ImageOffsets); 193 /* convert stride to texels, not bytes */ 194 intelImage->base.RowStride /= intelImage->mt->cpp; 195 /* intelImage->base.ImageStride /= intelImage->mt->cpp; */ 196 } 197 } 198} 199 200void 201intel_tex_unmap_level_images(struct intel_context *intel, 202 struct intel_texture_object *intelObj, 203 int level) 204{ 205 GLuint nr_faces = (intelObj->base.Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 206 GLuint face; 207 208 for (face = 0; face < nr_faces; face++) { 209 struct intel_texture_image *intelImage = 210 intel_texture_image(intelObj->base.Image[face][level]); 211 212 if (intelImage && intelImage->mt) { 213 intel_miptree_image_unmap(intel, intelImage->mt); 214 intelImage->base.Data = NULL; 215 } 216 } 217} 218 219void 220intel_tex_map_images(struct intel_context *intel, 221 struct intel_texture_object *intelObj) 222{ 223 int i; 224 225 DBG("%s\n", __FUNCTION__); 226 227 for (i = intelObj->base.BaseLevel; i <= intelObj->_MaxLevel; i++) 228 intel_tex_map_level_images(intel, intelObj, i); 229} 230 231void 232intel_tex_unmap_images(struct intel_context *intel, 233 struct intel_texture_object *intelObj) 234{ 235 int i; 236 237 for (i = intelObj->base.BaseLevel; i <= intelObj->_MaxLevel; i++) 238 intel_tex_unmap_level_images(intel, intelObj, i); 239} 240