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 "brw_context.h" 8#include "brw_defines.h" 9#include "intel_buffer_objects.h" 10#include "intel_mipmap_tree.h" 11#include "intel_tex.h" 12#include "intel_fbo.h" 13 14#define FILE_DEBUG_FLAG DEBUG_TEXTURE 15 16static struct gl_texture_image * 17intelNewTextureImage(struct gl_context * ctx) 18{ 19 DBG("%s\n", __func__); 20 (void) ctx; 21 return (struct gl_texture_image *) CALLOC_STRUCT(intel_texture_image); 22} 23 24static void 25intelDeleteTextureImage(struct gl_context * ctx, struct gl_texture_image *img) 26{ 27 /* nothing special (yet) for intel_texture_image */ 28 _mesa_delete_texture_image(ctx, img); 29} 30 31 32static struct gl_texture_object * 33intelNewTextureObject(struct gl_context * ctx, GLuint name, GLenum target) 34{ 35 struct intel_texture_object *obj = CALLOC_STRUCT(intel_texture_object); 36 37 (void) ctx; 38 39 DBG("%s\n", __func__); 40 41 if (obj == NULL) 42 return NULL; 43 44 _mesa_initialize_texture_object(ctx, &obj->base, name, target); 45 46 obj->needs_validate = true; 47 48 return &obj->base; 49} 50 51static void 52intelDeleteTextureObject(struct gl_context *ctx, 53 struct gl_texture_object *texObj) 54{ 55 struct intel_texture_object *intelObj = intel_texture_object(texObj); 56 57 intel_miptree_release(&intelObj->mt); 58 _mesa_delete_texture_object(ctx, texObj); 59} 60 61static GLboolean 62intel_alloc_texture_image_buffer(struct gl_context *ctx, 63 struct gl_texture_image *image) 64{ 65 struct brw_context *brw = brw_context(ctx); 66 struct intel_texture_image *intel_image = intel_texture_image(image); 67 struct gl_texture_object *texobj = image->TexObject; 68 struct intel_texture_object *intel_texobj = intel_texture_object(texobj); 69 70 assert(image->Border == 0); 71 72 /* Quantize sample count */ 73 if (image->NumSamples) { 74 image->NumSamples = intel_quantize_num_samples(brw->screen, image->NumSamples); 75 if (!image->NumSamples) 76 return false; 77 } 78 79 /* Because the driver uses AllocTextureImageBuffer() internally, it may end 80 * up mismatched with FreeTextureImageBuffer(), but that is safe to call 81 * multiple times. 82 */ 83 ctx->Driver.FreeTextureImageBuffer(ctx, image); 84 85 if (!_swrast_init_texture_image(image)) 86 return false; 87 88 if (intel_texobj->mt && 89 intel_miptree_match_image(intel_texobj->mt, image)) { 90 intel_miptree_reference(&intel_image->mt, intel_texobj->mt); 91 DBG("%s: alloc obj %p level %d %dx%dx%d using object's miptree %p\n", 92 __func__, texobj, image->Level, 93 image->Width, image->Height, image->Depth, intel_texobj->mt); 94 } else { 95 intel_image->mt = intel_miptree_create_for_teximage(brw, intel_texobj, 96 intel_image, 97 MIPTREE_CREATE_DEFAULT); 98 if (!intel_image->mt) 99 return false; 100 101 /* Even if the object currently has a mipmap tree associated 102 * with it, this one is a more likely candidate to represent the 103 * whole object since our level didn't fit what was there 104 * before, and any lower levels would fit into our miptree. 105 */ 106 intel_miptree_reference(&intel_texobj->mt, intel_image->mt); 107 108 DBG("%s: alloc obj %p level %d %dx%dx%d using new miptree %p\n", 109 __func__, texobj, image->Level, 110 image->Width, image->Height, image->Depth, intel_image->mt); 111 } 112 113 intel_texobj->needs_validate = true; 114 115 return true; 116} 117 118/** 119 * ctx->Driver.AllocTextureStorage() handler. 120 * 121 * Compare this to _mesa_AllocTextureStorage_sw, which would call into 122 * intel_alloc_texture_image_buffer() above. 123 */ 124static GLboolean 125intel_alloc_texture_storage(struct gl_context *ctx, 126 struct gl_texture_object *texobj, 127 GLsizei levels, GLsizei width, 128 GLsizei height, GLsizei depth) 129{ 130 struct brw_context *brw = brw_context(ctx); 131 struct intel_texture_object *intel_texobj = intel_texture_object(texobj); 132 struct gl_texture_image *first_image = texobj->Image[0][0]; 133 int num_samples = intel_quantize_num_samples(brw->screen, 134 first_image->NumSamples); 135 const int numFaces = _mesa_num_tex_faces(texobj->Target); 136 int face; 137 int level; 138 139 /* If the object's current miptree doesn't match what we need, make a new 140 * one. 141 */ 142 if (!intel_texobj->mt || 143 !intel_miptree_match_image(intel_texobj->mt, first_image) || 144 intel_texobj->mt->last_level != levels - 1) { 145 intel_miptree_release(&intel_texobj->mt); 146 147 intel_get_image_dims(first_image, &width, &height, &depth); 148 intel_texobj->mt = intel_miptree_create(brw, texobj->Target, 149 first_image->TexFormat, 150 0, levels - 1, 151 width, height, depth, 152 MAX2(num_samples, 1), 153 MIPTREE_CREATE_DEFAULT); 154 155 if (intel_texobj->mt == NULL) { 156 return false; 157 } 158 } 159 160 for (face = 0; face < numFaces; face++) { 161 for (level = 0; level < levels; level++) { 162 struct gl_texture_image *image = texobj->Image[face][level]; 163 struct intel_texture_image *intel_image = intel_texture_image(image); 164 165 image->NumSamples = num_samples; 166 167 _swrast_free_texture_image_buffer(ctx, image); 168 if (!_swrast_init_texture_image(image)) 169 return false; 170 171 intel_miptree_reference(&intel_image->mt, intel_texobj->mt); 172 } 173 } 174 175 /* The miptree is in a validated state, so no need to check later. */ 176 intel_texobj->needs_validate = false; 177 intel_texobj->validated_first_level = 0; 178 intel_texobj->validated_last_level = levels - 1; 179 intel_texobj->_Format = first_image->TexFormat; 180 181 return true; 182} 183 184 185static void 186intel_free_texture_image_buffer(struct gl_context * ctx, 187 struct gl_texture_image *texImage) 188{ 189 struct intel_texture_image *intelImage = intel_texture_image(texImage); 190 191 DBG("%s\n", __func__); 192 193 intel_miptree_release(&intelImage->mt); 194 195 _swrast_free_texture_image_buffer(ctx, texImage); 196} 197 198/** 199 * Map texture memory/buffer into user space. 200 * Note: the region of interest parameters are ignored here. 201 * \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT 202 * \param mapOut returns start of mapping of region of interest 203 * \param rowStrideOut returns row stride in bytes 204 */ 205static void 206intel_map_texture_image(struct gl_context *ctx, 207 struct gl_texture_image *tex_image, 208 GLuint slice, 209 GLuint x, GLuint y, GLuint w, GLuint h, 210 GLbitfield mode, 211 GLubyte **map, 212 GLint *out_stride) 213{ 214 struct brw_context *brw = brw_context(ctx); 215 struct intel_texture_image *intel_image = intel_texture_image(tex_image); 216 struct intel_mipmap_tree *mt = intel_image->mt; 217 ptrdiff_t stride; 218 219 /* Our texture data is always stored in a miptree. */ 220 assert(mt); 221 222 /* Check that our caller wasn't confused about how to map a 1D texture. */ 223 assert(tex_image->TexObject->Target != GL_TEXTURE_1D_ARRAY || 224 h == 1); 225 226 /* intel_miptree_map operates on a unified "slice" number that references the 227 * cube face, since it's all just slices to the miptree code. 228 */ 229 if (tex_image->TexObject->Target == GL_TEXTURE_CUBE_MAP) 230 slice = tex_image->Face; 231 232 intel_miptree_map(brw, mt, 233 tex_image->Level + tex_image->TexObject->MinLevel, 234 slice + tex_image->TexObject->MinLayer, 235 x, y, w, h, mode, 236 (void **)map, &stride); 237 238 *out_stride = stride; 239} 240 241static void 242intel_unmap_texture_image(struct gl_context *ctx, 243 struct gl_texture_image *tex_image, GLuint slice) 244{ 245 struct brw_context *brw = brw_context(ctx); 246 struct intel_texture_image *intel_image = intel_texture_image(tex_image); 247 struct intel_mipmap_tree *mt = intel_image->mt; 248 249 if (tex_image->TexObject->Target == GL_TEXTURE_CUBE_MAP) 250 slice = tex_image->Face; 251 252 intel_miptree_unmap(brw, mt, 253 tex_image->Level + tex_image->TexObject->MinLevel, 254 slice + tex_image->TexObject->MinLayer); 255} 256 257static GLboolean 258intel_texture_view(struct gl_context *ctx, 259 struct gl_texture_object *texObj, 260 struct gl_texture_object *origTexObj) 261{ 262 struct brw_context *brw = brw_context(ctx); 263 struct intel_texture_object *intel_tex = intel_texture_object(texObj); 264 struct intel_texture_object *intel_orig_tex = intel_texture_object(origTexObj); 265 266 assert(intel_orig_tex->mt); 267 intel_miptree_reference(&intel_tex->mt, intel_orig_tex->mt); 268 269 /* Since we can only make views of immutable-format textures, 270 * we can assume that everything is in origTexObj's miptree. 271 * 272 * Mesa core has already made us a copy of all the teximage objects, 273 * except it hasn't copied our mt pointers, etc. 274 */ 275 const int numFaces = _mesa_num_tex_faces(texObj->Target); 276 const int numLevels = texObj->NumLevels; 277 278 int face; 279 int level; 280 281 for (face = 0; face < numFaces; face++) { 282 for (level = 0; level < numLevels; level++) { 283 struct gl_texture_image *image = texObj->Image[face][level]; 284 struct intel_texture_image *intel_image = intel_texture_image(image); 285 286 intel_miptree_reference(&intel_image->mt, intel_orig_tex->mt); 287 } 288 } 289 290 /* The miptree is in a validated state, so no need to check later. */ 291 intel_tex->needs_validate = false; 292 intel_tex->validated_first_level = 0; 293 intel_tex->validated_last_level = numLevels - 1; 294 295 /* Set the validated texture format, with the same adjustments that 296 * would have been applied to determine the underlying texture's 297 * mt->format. 298 */ 299 intel_tex->_Format = intel_depth_format_for_depthstencil_format( 300 intel_lower_compressed_format(brw, texObj->Image[0][0]->TexFormat)); 301 302 return GL_TRUE; 303} 304 305static void 306intel_texture_barrier(struct gl_context *ctx) 307{ 308 struct brw_context *brw = brw_context(ctx); 309 const struct gen_device_info *devinfo = &brw->screen->devinfo; 310 311 if (devinfo->gen >= 6) { 312 brw_emit_pipe_control_flush(brw, 313 PIPE_CONTROL_DEPTH_CACHE_FLUSH | 314 PIPE_CONTROL_RENDER_TARGET_FLUSH | 315 PIPE_CONTROL_CS_STALL); 316 317 brw_emit_pipe_control_flush(brw, 318 PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE); 319 } else { 320 brw_emit_mi_flush(brw); 321 } 322} 323 324void 325intelInitTextureFuncs(struct dd_function_table *functions) 326{ 327 functions->NewTextureObject = intelNewTextureObject; 328 functions->NewTextureImage = intelNewTextureImage; 329 functions->DeleteTextureImage = intelDeleteTextureImage; 330 functions->DeleteTexture = intelDeleteTextureObject; 331 functions->AllocTextureImageBuffer = intel_alloc_texture_image_buffer; 332 functions->FreeTextureImageBuffer = intel_free_texture_image_buffer; 333 functions->AllocTextureStorage = intel_alloc_texture_storage; 334 functions->MapTextureImage = intel_map_texture_image; 335 functions->UnmapTextureImage = intel_unmap_texture_image; 336 functions->TextureView = intel_texture_view; 337 functions->TextureBarrier = intel_texture_barrier; 338} 339