meta: Refactor the BlitFramebuffer depth CopyTexImage fallback.
This avoids a ReadPixels() if there's accelerated CopyTexImage present. It now requires GLSL as opposed to just fragment programs, but we don't have any drivers that do ARB_fp but not GLSL. Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
parent
b702233f53
commit
4cc42805e7
|
@ -250,7 +250,6 @@ struct blit_state
|
|||
{
|
||||
GLuint VAO;
|
||||
GLuint VBO;
|
||||
GLuint DepthFP;
|
||||
struct blit_shader_table shaders;
|
||||
GLuint msaa_shaders[BLIT_MSAA_SHADER_COUNT];
|
||||
struct temp_texture depthTex;
|
||||
|
|
|
@ -52,37 +52,6 @@
|
|||
/** Return offset in bytes of the field within a vertex struct */
|
||||
#define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD))
|
||||
|
||||
/**
|
||||
* One-time init for drawing depth pixels.
|
||||
*/
|
||||
static void
|
||||
init_blit_depth_pixels(struct gl_context *ctx)
|
||||
{
|
||||
static const char *program =
|
||||
"!!ARBfp1.0\n"
|
||||
"TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
|
||||
"END \n";
|
||||
char program2[200];
|
||||
struct blit_state *blit = &ctx->Meta->Blit;
|
||||
struct temp_texture *tex = _mesa_meta_get_temp_texture(ctx);
|
||||
const char *texTarget;
|
||||
|
||||
assert(blit->DepthFP == 0);
|
||||
|
||||
/* replace %s with "RECT" or "2D" */
|
||||
assert(strlen(program) + 4 < sizeof(program2));
|
||||
if (tex->Target == GL_TEXTURE_RECTANGLE)
|
||||
texTarget = "RECT";
|
||||
else
|
||||
texTarget = "2D";
|
||||
_mesa_snprintf(program2, sizeof(program2), program, texTarget);
|
||||
|
||||
_mesa_GenProgramsARB(1, &blit->DepthFP);
|
||||
_mesa_BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
|
||||
_mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
|
||||
strlen(program2), (const GLubyte *) program2);
|
||||
}
|
||||
|
||||
static void
|
||||
setup_glsl_msaa_blit_shader(struct gl_context *ctx,
|
||||
struct blit_state *blit,
|
||||
|
@ -454,7 +423,8 @@ blitframebuffer_texture(struct gl_context *ctx,
|
|||
return false;
|
||||
|
||||
if (do_depth) {
|
||||
return false;
|
||||
meta_temp_texture = _mesa_meta_get_temp_depth_texture(ctx);
|
||||
tex_base_format = GL_DEPTH_COMPONENT;
|
||||
} else {
|
||||
meta_temp_texture = _mesa_meta_get_temp_texture(ctx);
|
||||
tex_base_format =
|
||||
|
@ -626,25 +596,10 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx,
|
|||
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
|
||||
GLbitfield mask, GLenum filter)
|
||||
{
|
||||
struct blit_state *blit = &ctx->Meta->Blit;
|
||||
struct temp_texture *depthTex = _mesa_meta_get_temp_depth_texture(ctx);
|
||||
const GLint srcX = MIN2(srcX0, srcX1);
|
||||
const GLint srcY = MIN2(srcY0, srcY1);
|
||||
const GLint srcW = abs(srcX1 - srcX0);
|
||||
const GLint srcH = abs(srcY1 - srcY0);
|
||||
const GLint dstX = MIN2(dstX0, dstX1);
|
||||
const GLint dstY = MIN2(dstY0, dstY1);
|
||||
const GLint dstW = abs(dstX1 - dstX0);
|
||||
const GLint dstH = abs(dstY1 - dstY0);
|
||||
const GLint srcFlipX = (srcX1 - srcX0) / srcW;
|
||||
const GLint srcFlipY = (srcY1 - srcY0) / srcH;
|
||||
const GLint dstFlipX = (dstX1 - dstX0) / dstW;
|
||||
const GLint dstFlipY = (dstY1 - dstY0) / dstH;
|
||||
const GLint flipX = srcFlipX * dstFlipX;
|
||||
const GLint flipY = srcFlipY * dstFlipY;
|
||||
|
||||
struct vertex verts[4];
|
||||
GLboolean newTex;
|
||||
const GLboolean use_glsl_version = ctx->Extensions.ARB_vertex_shader &&
|
||||
ctx->Extensions.ARB_fragment_shader;
|
||||
|
||||
|
@ -684,96 +639,10 @@ _mesa_meta_BlitFramebuffer(struct gl_context *ctx,
|
|||
}
|
||||
}
|
||||
|
||||
/* Choose between glsl version and fixed function version of
|
||||
* BlitFramebuffer function.
|
||||
*/
|
||||
if (use_glsl_version) {
|
||||
setup_glsl_blit_framebuffer(ctx, blit, NULL, depthTex->Target);
|
||||
}
|
||||
else {
|
||||
_mesa_meta_setup_ff_tnl_for_blit(&blit->VAO, &blit->VBO, 2);
|
||||
}
|
||||
|
||||
/* Silence valgrind warnings about reading uninitialized stack. */
|
||||
memset(verts, 0, sizeof(verts));
|
||||
|
||||
/* Continue with "normal" approach which involves copying the src rect
|
||||
* into a temporary texture and is "blitted" by drawing a textured quad.
|
||||
*/
|
||||
{
|
||||
/* setup vertex positions */
|
||||
verts[0].x = -1.0F * flipX;
|
||||
verts[0].y = -1.0F * flipY;
|
||||
verts[1].x = 1.0F * flipX;
|
||||
verts[1].y = -1.0F * flipY;
|
||||
verts[2].x = 1.0F * flipX;
|
||||
verts[2].y = 1.0F * flipY;
|
||||
verts[3].x = -1.0F * flipX;
|
||||
verts[3].y = 1.0F * flipY;
|
||||
|
||||
}
|
||||
|
||||
if (!use_glsl_version)
|
||||
_mesa_set_enable(ctx, depthTex->Target, GL_TRUE);
|
||||
|
||||
if ((mask & GL_DEPTH_BUFFER_BIT) &&
|
||||
_mesa_is_desktop_gl(ctx) &&
|
||||
ctx->Extensions.ARB_depth_texture &&
|
||||
ctx->Extensions.ARB_fragment_program) {
|
||||
|
||||
GLuint *tmp = malloc(srcW * srcH * sizeof(GLuint));
|
||||
|
||||
if (tmp) {
|
||||
|
||||
newTex = _mesa_meta_alloc_texture(depthTex, srcW, srcH,
|
||||
GL_DEPTH_COMPONENT);
|
||||
_mesa_ReadPixels(srcX, srcY, srcW, srcH, GL_DEPTH_COMPONENT,
|
||||
GL_UNSIGNED_INT, tmp);
|
||||
_mesa_meta_setup_drawpix_texture(ctx, depthTex, newTex,
|
||||
srcW, srcH, GL_DEPTH_COMPONENT,
|
||||
GL_UNSIGNED_INT, tmp);
|
||||
|
||||
/* texcoords (after texture allocation!) */
|
||||
{
|
||||
verts[0].tex[0] = 0.0F;
|
||||
verts[0].tex[1] = 0.0F;
|
||||
verts[1].tex[0] = depthTex->Sright;
|
||||
verts[1].tex[1] = 0.0F;
|
||||
verts[2].tex[0] = depthTex->Sright;
|
||||
verts[2].tex[1] = depthTex->Ttop;
|
||||
verts[3].tex[0] = 0.0F;
|
||||
verts[3].tex[1] = depthTex->Ttop;
|
||||
|
||||
/* upload new vertex data */
|
||||
_mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
|
||||
}
|
||||
|
||||
if (!blit->DepthFP)
|
||||
init_blit_depth_pixels(ctx);
|
||||
|
||||
_mesa_BindProgramARB(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
|
||||
_mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
|
||||
_mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
|
||||
_mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
|
||||
_mesa_DepthFunc(GL_ALWAYS);
|
||||
_mesa_DepthMask(GL_TRUE);
|
||||
|
||||
_mesa_set_viewport(ctx, 0, dstX, dstY, dstW, dstH);
|
||||
_mesa_BufferSubData(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
|
||||
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
|
||||
mask &= ~GL_DEPTH_BUFFER_BIT;
|
||||
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if (mask & GL_STENCIL_BUFFER_BIT) {
|
||||
/* XXX can't easily do stencil */
|
||||
}
|
||||
|
||||
if (!use_glsl_version)
|
||||
_mesa_set_enable(ctx, depthTex->Target, GL_FALSE);
|
||||
|
||||
_mesa_meta_end(ctx);
|
||||
|
||||
fallback:
|
||||
|
@ -792,10 +661,6 @@ _mesa_meta_glsl_blit_cleanup(struct blit_state *blit)
|
|||
_mesa_DeleteBuffers(1, &blit->VBO);
|
||||
blit->VBO = 0;
|
||||
}
|
||||
if (blit->DepthFP) {
|
||||
_mesa_DeleteProgramsARB(1, &blit->DepthFP);
|
||||
blit->DepthFP = 0;
|
||||
}
|
||||
|
||||
_mesa_meta_blit_shader_table_cleanup(&blit->shaders);
|
||||
|
||||
|
|
Loading…
Reference in New Issue