On 03/06/2014 12:47 PM, Kenneth Graunke wrote: > 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.
A future todo (maybe a NewbieProject?) is to do this in one pass using GL_AMD_vertex_shader_layer + instanced rendering. > Signed-off-by: Kenneth Graunke <[email protected]> > --- > src/mesa/drivers/common/meta_generate_mipmap.c | 69 > +++++++++++++------------- > 1 file changed, 34 insertions(+), 35 deletions(-) > > diff --git a/src/mesa/drivers/common/meta_generate_mipmap.c > b/src/mesa/drivers/common/meta_generate_mipmap.c > index 6ca6f22..d9535d9 100644 > --- a/src/mesa/drivers/common/meta_generate_mipmap.c > +++ b/src/mesa/drivers/common/meta_generate_mipmap.c > @@ -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_DrawArrays(GL_TRIANGLE_FAN, 0, 4); > + _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0); > + > + 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 */ _______________________________________________ mesa-dev mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-dev
