meta: Support GenerateMipmaps on 2DArray textures.
This is largely a matter of looping over the number of slices/layers, and not minifying depth (presumably that code exists for the unfinished 3D texture support). Normally, I would have made the loop over array slices the outermost loop. I suspect that would make it trickier to support 3D textures someday, though, so I didn't. The advantage is that we would only have one BufferData call per slice, rather than one per miplevel and slice. However, a GenerateMipmaps microbenchmark indicates that either way is basically just as fast. So I'm not sure it's worth bothering. Improves performance in a GenerateMipmaps microbenchmark by nearly 5x. Signed-off-by: Kenneth Graunke <kenneth@whitecape.org> Reviewed-by: Matt Turner <mattst88@gmail.com> Reviewed-by: Anuj Phogat <anuj.phogat@gmail.com> Reviewed-by: Ian Romanick <ian.d.romanick@intel.com>
This commit is contained in:
parent
15b2f69b9c
commit
ec23d5197e
|
@ -94,9 +94,7 @@ fallback_required(struct gl_context *ctx, GLenum target,
|
|||
GLenum status;
|
||||
|
||||
/* check for fallbacks */
|
||||
if (target == GL_TEXTURE_3D ||
|
||||
target == GL_TEXTURE_1D_ARRAY ||
|
||||
target == GL_TEXTURE_2D_ARRAY) {
|
||||
if (target == GL_TEXTURE_3D || target == GL_TEXTURE_1D_ARRAY) {
|
||||
_mesa_perf_debug(ctx, MESA_DEBUG_SEVERITY_HIGH,
|
||||
"glGenerateMipmap() to %s target\n",
|
||||
_mesa_lookup_enum_by_nr(target));
|
||||
|
@ -186,7 +184,6 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
|
|||
ctx->Extensions.ARB_fragment_shader;
|
||||
GLenum faceTarget;
|
||||
GLuint dstLevel;
|
||||
const GLint slice = 0;
|
||||
GLuint samplerSave;
|
||||
|
||||
if (fallback_required(ctx, target, texObj)) {
|
||||
|
@ -254,15 +251,6 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
|
|||
/* Silence valgrind warnings about reading uninitialized stack. */
|
||||
memset(verts, 0, sizeof(verts));
|
||||
|
||||
/* Setup texture coordinates */
|
||||
_mesa_meta_setup_texture_coords(faceTarget,
|
||||
slice,
|
||||
0, 0, 1, /* width, height never used here */
|
||||
verts[0].tex,
|
||||
verts[1].tex,
|
||||
verts[2].tex,
|
||||
verts[3].tex);
|
||||
|
||||
/* setup vertex positions */
|
||||
verts[0].x = -1.0F;
|
||||
verts[0].y = -1.0F;
|
||||
|
@ -273,16 +261,13 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
|
|||
verts[3].x = -1.0F;
|
||||
verts[3].y = 1.0F;
|
||||
|
||||
/* upload vertex data */
|
||||
_mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts),
|
||||
verts, GL_DYNAMIC_DRAW_ARB);
|
||||
|
||||
/* texture is already locked, unlock now */
|
||||
_mesa_unlock_texture(ctx, texObj);
|
||||
|
||||
for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) {
|
||||
const struct gl_texture_image *srcImage;
|
||||
const GLuint srcLevel = dstLevel - 1;
|
||||
GLuint layer;
|
||||
GLsizei srcWidth, srcHeight, srcDepth;
|
||||
GLsizei dstWidth, dstHeight, dstDepth;
|
||||
|
||||
|
@ -297,7 +282,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
|
|||
/* new dst size */
|
||||
dstWidth = minify(srcWidth, 1);
|
||||
dstHeight = minify(srcHeight, 1);
|
||||
dstDepth = minify(srcDepth, 1);
|
||||
dstDepth = target == GL_TEXTURE_3D ? minify(srcDepth, 1) : srcDepth;
|
||||
|
||||
if (dstWidth == srcImage->Width &&
|
||||
dstHeight == srcImage->Height &&
|
||||
|
@ -325,25 +310,39 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
|
|||
/* limit minification to src level */
|
||||
_mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
|
||||
|
||||
bind_fbo_image(texObj, faceTarget, dstLevel, 0);
|
||||
|
||||
_mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
|
||||
|
||||
/* sanity check */
|
||||
if (_mesa_CheckFramebufferStatus(GL_FRAMEBUFFER) !=
|
||||
GL_FRAMEBUFFER_COMPLETE) {
|
||||
_mesa_problem(ctx, "Unexpected incomplete framebuffer in "
|
||||
"_mesa_meta_GenerateMipmap()");
|
||||
break;
|
||||
}
|
||||
|
||||
assert(dstWidth == ctx->DrawBuffer->Width);
|
||||
assert(dstHeight == ctx->DrawBuffer->Height);
|
||||
|
||||
/* setup viewport */
|
||||
_mesa_set_viewport(ctx, 0, 0, 0, dstWidth, dstHeight);
|
||||
_mesa_DrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
|
||||
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
for (layer = 0; layer < dstDepth; ++layer) {
|
||||
/* Setup texture coordinates */
|
||||
_mesa_meta_setup_texture_coords(faceTarget,
|
||||
layer,
|
||||
0, 0, 1, /* width, height never used here */
|
||||
verts[0].tex,
|
||||
verts[1].tex,
|
||||
verts[2].tex,
|
||||
verts[3].tex);
|
||||
|
||||
/* upload vertex data */
|
||||
_mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts),
|
||||
verts, GL_DYNAMIC_DRAW_ARB);
|
||||
|
||||
bind_fbo_image(texObj, faceTarget, dstLevel, layer);
|
||||
|
||||
/* sanity check */
|
||||
if (_mesa_CheckFramebufferStatus(GL_FRAMEBUFFER) !=
|
||||
GL_FRAMEBUFFER_COMPLETE) {
|
||||
_mesa_problem(ctx, "Unexpected incomplete framebuffer in "
|
||||
"_mesa_meta_GenerateMipmap()");
|
||||
break;
|
||||
}
|
||||
|
||||
assert(dstWidth == ctx->DrawBuffer->Width);
|
||||
assert(dstHeight == ctx->DrawBuffer->Height);
|
||||
|
||||
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
}
|
||||
}
|
||||
|
||||
_mesa_lock_texture(ctx, texObj); /* relock */
|
||||
|
|
Loading…
Reference in New Issue