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