/** * ctx->Driver.AllocTextureStorage() handler. * * Compare this to _mesa_AllocTextureStorage_sw, which would call into * intel_alloc_texture_image_buffer() above. */ static GLboolean intel_alloc_texture_storage(struct gl_context *ctx, struct gl_texture_object *texobj, GLsizei levels, GLsizei width, GLsizei height, GLsizei depth) { struct brw_context *brw = brw_context(ctx); struct intel_texture_object *intel_texobj = intel_texture_object(texobj); struct gl_texture_image *first_image = texobj->Image[0][0]; int num_samples = intel_quantize_num_samples(brw->screen, first_image->NumSamples); const int numFaces = _mesa_num_tex_faces(texobj->Target); int face; int level; /* If the object's current miptree doesn't match what we need, make a new * one. */ if (!intel_texobj->mt || !intel_miptree_match_image(intel_texobj->mt, first_image) || intel_texobj->mt->last_level != levels - 1) { intel_miptree_release(&intel_texobj->mt); intel_get_image_dims(first_image, &width, &height, &depth); intel_texobj->mt = intel_miptree_create(brw, texobj->Target, first_image->TexFormat, 0, levels - 1, width, height, depth, MAX2(num_samples, 1), MIPTREE_CREATE_DEFAULT); if (intel_texobj->mt == NULL) { return false; } } for (face = 0; face < numFaces; face++) { for (level = 0; level < levels; level++) { struct gl_texture_image *image = texobj->Image[face][level]; struct intel_texture_image *intel_image = intel_texture_image(image); image->NumSamples = num_samples; _swrast_free_texture_image_buffer(ctx, image); if (!_swrast_init_texture_image(image)) return false; intel_miptree_reference(&intel_image->mt, intel_texobj->mt); } } /* The miptree is in a validated state, so no need to check later. */ intel_texobj->needs_validate = false; intel_texobj->validated_first_level = 0; intel_texobj->validated_last_level = levels - 1; intel_texobj->_Format = first_image->TexFormat; return true; }
/* Work back from the specified level of the image to the baselevel and create a * miptree of that size. */ struct intel_mipmap_tree * intel_miptree_create_for_teximage(struct brw_context *brw, struct intel_texture_object *intelObj, struct intel_texture_image *intelImage, uint32_t layout_flags) { GLuint lastLevel; int width, height, depth; GLuint i; intel_get_image_dims(&intelImage->base.Base, &width, &height, &depth); DBG("%s\n", __func__); /* Figure out image dimensions at start level. */ for (i = intelImage->base.Base.Level; i > 0; i--) { width <<= 1; if (height != 1) height <<= 1; if (depth != 1) depth <<= 1; } /* Guess a reasonable value for lastLevel. This is probably going * to be wrong fairly often and might mean that we have to look at * resizable buffers, or require that buffers implement lazy * pagetable arrangements. */ if ((intelObj->base.Sampler.MinFilter == GL_NEAREST || intelObj->base.Sampler.MinFilter == GL_LINEAR) && intelImage->base.Base.Level == 0 && !intelObj->base.GenerateMipmap) { lastLevel = 0; } else { lastLevel = _mesa_get_tex_max_num_levels(intelObj->base.Target, width, height, depth) - 1; } return intel_miptree_create(brw, intelObj->base.Target, intelImage->base.Base.TexFormat, 0, lastLevel, width, height, depth, intelImage->base.Base.NumSamples, layout_flags | MIPTREE_LAYOUT_TILING_ANY); }
/* Work back from the specified level of the image to the baselevel and create a * miptree of that size. */ struct intel_mipmap_tree * intel_miptree_create_for_teximage(struct brw_context *brw, struct intel_texture_object *intelObj, struct intel_texture_image *intelImage, uint32_t layout_flags) { GLuint lastLevel; int width, height, depth; intel_get_image_dims(&intelImage->base.Base, &width, &height, &depth); DBG("%s\n", __func__); /* Figure out image dimensions at start level. */ switch(intelObj->base.Target) { case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: case GL_TEXTURE_RECTANGLE: case GL_TEXTURE_EXTERNAL_OES: assert(intelImage->base.Base.Level == 0); break; case GL_TEXTURE_3D: depth <<= intelImage->base.Base.Level; /* Fall through */ case GL_TEXTURE_2D: case GL_TEXTURE_2D_ARRAY: case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP_ARRAY: height <<= intelImage->base.Base.Level; /* Fall through */ case GL_TEXTURE_1D: case GL_TEXTURE_1D_ARRAY: width <<= intelImage->base.Base.Level; break; default: unreachable("Unexpected target"); } /* Guess a reasonable value for lastLevel. This is probably going * to be wrong fairly often and might mean that we have to look at * resizable buffers, or require that buffers implement lazy * pagetable arrangements. */ if ((intelObj->base.Sampler.MinFilter == GL_NEAREST || intelObj->base.Sampler.MinFilter == GL_LINEAR) && intelImage->base.Base.Level == 0 && !intelObj->base.GenerateMipmap) { lastLevel = 0; } else { lastLevel = _mesa_get_tex_max_num_levels(intelObj->base.Target, width, height, depth) - 1; } return intel_miptree_create(brw, intelObj->base.Target, intelImage->base.Base.TexFormat, 0, lastLevel, width, height, depth, intelImage->base.Base.NumSamples, layout_flags | MIPTREE_LAYOUT_TILING_ANY); }