intel_tex.c revision e0304180c32227342dbb67b707bfae446543bb48
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 fallback_debug("%s - fallback to swrast\n", __FUNCTION__); 167 168 _mesa_generate_mipmap(ctx, target, texObj); 169 } 170 else { 171 _mesa_meta_GenerateMipmap(ctx, target, texObj); 172 } 173} 174 175 176void 177intelInitTextureFuncs(struct dd_function_table *functions) 178{ 179 functions->GenerateMipmap = intelGenerateMipmap; 180 181 functions->NewTextureObject = intelNewTextureObject; 182 functions->NewTextureImage = intelNewTextureImage; 183 functions->DeleteTextureImage = intelDeleteTextureImage; 184 functions->DeleteTexture = intelDeleteTextureObject; 185 functions->FreeTextureImageBuffer = intel_free_texture_image_buffer; 186 functions->MapTextureImage = intel_map_texture_image; 187 functions->UnmapTextureImage = intel_unmap_texture_image; 188} 189