intel_tex.c revision 019c9ee2204723a9a041316e055e0602e514cad4
1#include "swrast/swrast.h" 2#include "main/renderbuffer.h" 3#include "main/texobj.h" 4#include "main/teximage.h" 5#include "main/mipmap.h" 6#include "drivers/common/meta.h" 7#include "intel_context.h" 8#include "intel_mipmap_tree.h" 9#include "intel_tex.h" 10 11#define FILE_DEBUG_FLAG DEBUG_TEXTURE 12 13static struct gl_texture_image * 14intelNewTextureImage(struct gl_context * ctx) 15{ 16 DBG("%s\n", __FUNCTION__); 17 (void) ctx; 18 return (struct gl_texture_image *) CALLOC_STRUCT(intel_texture_image); 19} 20 21static void 22intelDeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img) 23{ 24 /* nothing special (yet) for intel_texture_image */ 25 _mesa_delete_texture_image(ctx, img); 26} 27 28 29static struct gl_texture_object * 30intelNewTextureObject(struct gl_context * ctx, GLuint name, GLenum target) 31{ 32 struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object); 33 34 (void) ctx; 35 36 DBG("%s\n", __FUNCTION__); 37 _mesa_initialize_texture_object(&obj->base, name, target); 38 39 return &obj->base; 40} 41 42static void 43intelDeleteTextureObject(struct gl_context *ctx, 44 struct gl_texture_object *texObj) 45{ 46 struct intel_texture_object *intelObj = intel_texture_object(texObj); 47 48 intel_miptree_release(&intelObj->mt); 49 _mesa_delete_texture_object(ctx, texObj); 50} 51 52 53static void 54intel_free_texture_image_buffer(struct gl_context * ctx, 55 struct gl_texture_image *texImage) 56{ 57 struct intel_texture_image *intelImage = intel_texture_image(texImage); 58 59 DBG("%s\n", __FUNCTION__); 60 61 intel_miptree_release(&intelImage->mt); 62 63 if (texImage->Data) { 64 _mesa_free_texmemory(texImage->Data); 65 texImage->Data = NULL; 66 } 67 68 _mesa_reference_renderbuffer(&intelImage->depth_rb, NULL); 69 _mesa_reference_renderbuffer(&intelImage->stencil_rb, NULL); 70} 71 72/** 73 * Map texture memory/buffer into user space. 74 * Note: the region of interest parameters are ignored here. 75 * \param mapOut returns start of mapping of region of interest 76 * \param rowStrideOut returns row stride in bytes 77 */ 78static void 79intel_map_texture_image(struct gl_context *ctx, 80 struct gl_texture_image *tex_image, 81 GLuint slice, 82 GLuint x, GLuint y, GLuint w, GLuint h, 83 GLbitfield mode, 84 GLubyte **map, 85 GLint *stride) 86{ 87 struct intel_context *intel = intel_context(ctx); 88 struct intel_texture_image *intel_image = intel_texture_image(tex_image); 89 struct intel_mipmap_tree *mt = intel_image->mt; 90 unsigned int bw, bh; 91 92 if (intel_image->stencil_rb) { 93 /* 94 * The texture has packed depth/stencil format, but uses separate 95 * stencil. The texture's embedded stencil buffer contains the real 96 * stencil data, so copy that into the miptree. 97 */ 98 intel_tex_image_s8z24_gather(intel, intel_image); 99 } 100 101 /* For compressed formats, the stride is the number of bytes per 102 * row of blocks. intel_miptree_get_image_offset() already does 103 * the divide. 104 */ 105 _mesa_get_format_block_size(tex_image->TexFormat, &bw, &bh); 106 assert(y % bh == 0); 107 y /= bh; 108 109 if (likely(mt)) { 110 void *base = intel_region_map(intel, mt->region); 111 unsigned int image_x, image_y; 112 113 intel_miptree_get_image_offset(mt, tex_image->Level, tex_image->Face, 114 slice, &image_x, &image_y); 115 x += image_x; 116 y += image_y; 117 118 *stride = mt->region->pitch * mt->cpp; 119 *map = base + y * *stride + x * mt->cpp; 120 } else { 121 /* texture data is in malloc'd memory */ 122 GLuint width = tex_image->Width; 123 GLuint height = ALIGN(tex_image->Height, bh) / bh; 124 GLuint texelSize = _mesa_get_format_bytes(tex_image->TexFormat); 125 126 assert(map); 127 128 *stride = _mesa_format_row_stride(tex_image->TexFormat, width); 129 *map = tex_image->Data + (slice * height + y) * *stride + x * texelSize; 130 131 return; 132 } 133} 134 135static void 136intel_unmap_texture_image(struct gl_context *ctx, 137 struct gl_texture_image *tex_image, GLuint slice) 138{ 139 struct intel_context *intel = intel_context(ctx); 140 struct intel_texture_image *intel_image = intel_texture_image(tex_image); 141 142 if (intel_image->mt) 143 intel_region_unmap(intel, intel_image->mt->region); 144 145 if (intel_image->stencil_rb) { 146 /* 147 * The texture has packed depth/stencil format, but uses separate 148 * stencil. The texture's embedded stencil buffer contains the real 149 * stencil data, so copy that into the miptree. 150 */ 151 intel_tex_image_s8z24_scatter(intel, intel_image); 152 } 153} 154 155/** 156 * Called via ctx->Driver.GenerateMipmap() 157 * This is basically a wrapper for _mesa_meta_GenerateMipmap() which checks 158 * if we'll be using software mipmap generation. In that case, we need to 159 * map/unmap the base level texture image. 160 */ 161static void 162intelGenerateMipmap(struct gl_context *ctx, GLenum target, 163 struct gl_texture_object *texObj) 164{ 165 if (_mesa_meta_check_generate_mipmap_fallback(ctx, target, texObj)) { 166 /* sw path: need to map texture images */ 167 struct intel_context *intel = intel_context(ctx); 168 struct intel_texture_object *intelObj = intel_texture_object(texObj); 169 struct gl_texture_image *first_image = texObj->Image[0][texObj->BaseLevel]; 170 171 fallback_debug("%s - fallback to swrast\n", __FUNCTION__); 172 173 if (_mesa_is_format_compressed(first_image->TexFormat)) { 174 _mesa_generate_mipmap(ctx, target, texObj); 175 } else { 176 intel_tex_map_level_images(intel, intelObj, texObj->BaseLevel); 177 _mesa_generate_mipmap(ctx, target, texObj); 178 intel_tex_unmap_level_images(intel, intelObj, texObj->BaseLevel); 179 } 180 181 if (!_mesa_is_format_compressed(first_image->TexFormat)) { 182 GLuint nr_faces = (texObj->Target == GL_TEXTURE_CUBE_MAP) ? 6 : 1; 183 GLuint face, i; 184 for (face = 0; face < nr_faces; face++) { 185 for (i = texObj->BaseLevel + 1; i < texObj->MaxLevel; i++) { 186 struct intel_texture_image *intelImage = 187 intel_texture_image(texObj->Image[face][i]); 188 if (!intelImage) 189 break; 190 /* Unreference the miptree to signal that the new Data is a 191 * bare pointer from mesa. 192 */ 193 intel_miptree_release(&intelImage->mt); 194 } 195 } 196 } 197 } 198 else { 199 _mesa_meta_GenerateMipmap(ctx, target, texObj); 200 } 201} 202 203 204void 205intelInitTextureFuncs(struct dd_function_table *functions) 206{ 207 functions->GenerateMipmap = intelGenerateMipmap; 208 209 functions->NewTextureObject = intelNewTextureObject; 210 functions->NewTextureImage = intelNewTextureImage; 211 functions->DeleteTextureImage = intelDeleteTextureImage; 212 functions->DeleteTexture = intelDeleteTextureObject; 213 functions->FreeTextureImageBuffer = intel_free_texture_image_buffer; 214 functions->MapTextureImage = intel_map_texture_image; 215 functions->UnmapTextureImage = intel_unmap_texture_image; 216} 217