intel_tex.c revision 80513ec8b4c812b9c6249cc5824337a5f04ab34c
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 52static GLboolean 53intel_alloc_texture_image_buffer(struct gl_context *ctx, 54 struct gl_texture_image *image, 55 gl_format format, GLsizei width, 56 GLsizei height, GLsizei depth) 57{ 58 struct intel_context *intel = intel_context(ctx); 59 struct intel_texture_image *intel_image = intel_texture_image(image); 60 struct gl_texture_object *texobj = image->TexObject; 61 struct intel_texture_object *intel_texobj = intel_texture_object(texobj); 62 GLuint slices; 63 64 assert(image->Border == 0); 65 66 /* Because the driver uses AllocTextureImageBuffer() internally, it may end 67 * up mismatched with FreeTextureImageBuffer(), but that is safe to call 68 * multiple times. 69 */ 70 ctx->Driver.FreeTextureImageBuffer(ctx, image); 71 72 /* Allocate the swrast_texture_image::ImageOffsets array now */ 73 switch (texobj->Target) { 74 case GL_TEXTURE_3D: 75 case GL_TEXTURE_2D_ARRAY: 76 slices = image->Depth; 77 break; 78 case GL_TEXTURE_1D_ARRAY: 79 slices = image->Height; 80 break; 81 default: 82 slices = 1; 83 } 84 assert(!intel_image->base.ImageOffsets); 85 intel_image->base.ImageOffsets = malloc(slices * sizeof(GLuint)); 86 87 _swrast_init_texture_image(image, width, height, depth); 88 89 if (intel_texobj->mt && 90 intel_miptree_match_image(intel_texobj->mt, image)) { 91 intel_miptree_reference(&intel_image->mt, intel_texobj->mt); 92 DBG("%s: alloc obj %p level %d %dx%dx%d using object's miptree %p\n", 93 __FUNCTION__, texobj, image->Level, 94 width, height, depth, intel_texobj->mt); 95 } else { 96 intel_image->mt = intel_miptree_create_for_teximage(intel, intel_texobj, 97 intel_image, 98 false); 99 100 /* Even if the object currently has a mipmap tree associated 101 * with it, this one is a more likely candidate to represent the 102 * whole object since our level didn't fit what was there 103 * before, and any lower levels would fit into our miptree. 104 */ 105 intel_miptree_reference(&intel_texobj->mt, intel_image->mt); 106 107 DBG("%s: alloc obj %p level %d %dx%dx%d using new miptree %p\n", 108 __FUNCTION__, texobj, image->Level, 109 width, height, depth, intel_image->mt); 110 } 111 112 return true; 113} 114 115static void 116intel_free_texture_image_buffer(struct gl_context * ctx, 117 struct gl_texture_image *texImage) 118{ 119 struct intel_texture_image *intelImage = intel_texture_image(texImage); 120 121 DBG("%s\n", __FUNCTION__); 122 123 intel_miptree_release(&intelImage->mt); 124 125 if (intelImage->base.Buffer) { 126 _mesa_align_free(intelImage->base.Buffer); 127 intelImage->base.Buffer = NULL; 128 } 129 130 if (intelImage->base.ImageOffsets) { 131 free(intelImage->base.ImageOffsets); 132 intelImage->base.ImageOffsets = NULL; 133 } 134} 135 136/** 137 * Map texture memory/buffer into user space. 138 * Note: the region of interest parameters are ignored here. 139 * \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT 140 * \param mapOut returns start of mapping of region of interest 141 * \param rowStrideOut returns row stride in bytes 142 */ 143static void 144intel_map_texture_image(struct gl_context *ctx, 145 struct gl_texture_image *tex_image, 146 GLuint slice, 147 GLuint x, GLuint y, GLuint w, GLuint h, 148 GLbitfield mode, 149 GLubyte **map, 150 GLint *stride) 151{ 152 struct intel_context *intel = intel_context(ctx); 153 struct intel_texture_image *intel_image = intel_texture_image(tex_image); 154 struct intel_mipmap_tree *mt = intel_image->mt; 155 156 /* Our texture data is always stored in a miptree. */ 157 assert(mt); 158 159 /* Check that our caller wasn't confused about how to map a 1D texture. */ 160 assert(tex_image->TexObject->Target != GL_TEXTURE_1D_ARRAY || 161 h == 1); 162 163 /* intel_miptree_map operates on a unified "slice" number that references the 164 * cube face, since it's all just slices to the miptree code. 165 */ 166 if (tex_image->TexObject->Target == GL_TEXTURE_CUBE_MAP) 167 slice = tex_image->Face; 168 169 intel_miptree_map(intel, mt, tex_image->Level, slice, x, y, w, h, mode, 170 (void **)map, stride); 171} 172 173static void 174intel_unmap_texture_image(struct gl_context *ctx, 175 struct gl_texture_image *tex_image, GLuint slice) 176{ 177 struct intel_context *intel = intel_context(ctx); 178 struct intel_texture_image *intel_image = intel_texture_image(tex_image); 179 struct intel_mipmap_tree *mt = intel_image->mt; 180 181 if (tex_image->TexObject->Target == GL_TEXTURE_CUBE_MAP) 182 slice = tex_image->Face; 183 184 intel_miptree_unmap(intel, mt, tex_image->Level, slice); 185} 186 187void 188intelInitTextureFuncs(struct dd_function_table *functions) 189{ 190 functions->NewTextureObject = intelNewTextureObject; 191 functions->NewTextureImage = intelNewTextureImage; 192 functions->DeleteTextureImage = intelDeleteTextureImage; 193 functions->DeleteTexture = intelDeleteTextureObject; 194 functions->AllocTextureImageBuffer = intel_alloc_texture_image_buffer; 195 functions->FreeTextureImageBuffer = intel_free_texture_image_buffer; 196 functions->MapTextureImage = intel_map_texture_image; 197 functions->UnmapTextureImage = intel_unmap_texture_image; 198} 199