meta: Add an accelerated glCopyTexSubImage using glBlitFramebuffer.
You'll note from the previous commits that there's something of a loop here: You call CTSI, which calls BlitFB, then if things go wrong that falls back to CTSI. As a result, meta CTSI reaches over into blitfb to tell it "no, don't try that fallback". v2: Drop the _mesa_update_state(), which was only necessary due to use of _mesa_clip_blit() in _mesa_meta_BlitFramebuffer() in another patch series. v3: Drop an _EXT suffix I copy-and-pasted. Reviewed-by: Ian Romanick <ian.d.romanick@intel.com> (v2) Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
This commit is contained in:
parent
70961c032f
commit
234db60954
|
@ -37,6 +37,7 @@
|
|||
#include "main/arbprogram.h"
|
||||
#include "main/arrayobj.h"
|
||||
#include "main/blend.h"
|
||||
#include "main/blit.h"
|
||||
#include "main/bufferobj.h"
|
||||
#include "main/buffers.h"
|
||||
#include "main/colortab.h"
|
||||
|
@ -94,7 +95,8 @@ static void meta_decompress_cleanup(struct decompress_state *decompress);
|
|||
static void meta_drawpix_cleanup(struct drawpix_state *drawpix);
|
||||
|
||||
void
|
||||
_mesa_meta_bind_fbo_image(struct gl_texture_image *texImage, GLuint layer)
|
||||
_mesa_meta_bind_fbo_image(GLenum attachment,
|
||||
struct gl_texture_image *texImage, GLuint layer)
|
||||
{
|
||||
struct gl_texture_object *texObj = texImage->TexObject;
|
||||
int level = texImage->Level;
|
||||
|
@ -103,17 +105,18 @@ _mesa_meta_bind_fbo_image(struct gl_texture_image *texImage, GLuint layer)
|
|||
switch (target) {
|
||||
case GL_TEXTURE_1D:
|
||||
_mesa_FramebufferTexture1D(GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
attachment,
|
||||
target,
|
||||
texObj->Name,
|
||||
level);
|
||||
break;
|
||||
case GL_TEXTURE_1D_ARRAY:
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
case GL_TEXTURE_2D_MULTISAMPLE_ARRAY:
|
||||
case GL_TEXTURE_CUBE_MAP_ARRAY:
|
||||
case GL_TEXTURE_3D:
|
||||
_mesa_FramebufferTextureLayer(GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
attachment,
|
||||
texObj->Name,
|
||||
level,
|
||||
layer);
|
||||
|
@ -123,7 +126,7 @@ _mesa_meta_bind_fbo_image(struct gl_texture_image *texImage, GLuint layer)
|
|||
target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face;
|
||||
|
||||
_mesa_FramebufferTexture2D(GL_FRAMEBUFFER,
|
||||
GL_COLOR_ATTACHMENT0,
|
||||
attachment,
|
||||
target,
|
||||
texObj->Name,
|
||||
level);
|
||||
|
@ -2728,6 +2731,77 @@ get_temp_image_type(struct gl_context *ctx, mesa_format format)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to wrap the destination texture in an FBO and use
|
||||
* glBlitFramebuffer() to implement glCopyTexSubImage().
|
||||
*/
|
||||
static bool
|
||||
copytexsubimage_using_blit_framebuffer(struct gl_context *ctx, GLuint dims,
|
||||
struct gl_texture_image *texImage,
|
||||
GLint xoffset,
|
||||
GLint yoffset,
|
||||
GLint zoffset,
|
||||
struct gl_renderbuffer *rb,
|
||||
GLint x, GLint y,
|
||||
GLsizei width, GLsizei height)
|
||||
{
|
||||
struct gl_texture_object *texObj = texImage->TexObject;
|
||||
GLuint fbo;
|
||||
bool success = false;
|
||||
GLbitfield mask;
|
||||
GLenum status;
|
||||
|
||||
if (!ctx->Extensions.ARB_framebuffer_object)
|
||||
return false;
|
||||
|
||||
_mesa_unlock_texture(ctx, texObj);
|
||||
|
||||
_mesa_meta_begin(ctx, MESA_META_ALL);
|
||||
|
||||
_mesa_GenFramebuffers(1, &fbo);
|
||||
_mesa_BindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo);
|
||||
|
||||
if (rb->_BaseFormat == GL_DEPTH_STENCIL ||
|
||||
rb->_BaseFormat == GL_DEPTH_COMPONENT) {
|
||||
_mesa_meta_bind_fbo_image(GL_DEPTH_ATTACHMENT, texImage, zoffset);
|
||||
mask = GL_DEPTH_BUFFER_BIT;
|
||||
|
||||
if (rb->_BaseFormat == GL_DEPTH_STENCIL &&
|
||||
texImage->_BaseFormat == GL_DEPTH_STENCIL) {
|
||||
_mesa_meta_bind_fbo_image(GL_STENCIL_ATTACHMENT, texImage, zoffset);
|
||||
mask |= GL_STENCIL_BUFFER_BIT;
|
||||
}
|
||||
_mesa_DrawBuffer(GL_NONE);
|
||||
} else {
|
||||
_mesa_meta_bind_fbo_image(GL_COLOR_ATTACHMENT0, texImage, zoffset);
|
||||
mask = GL_COLOR_BUFFER_BIT;
|
||||
_mesa_DrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||
}
|
||||
|
||||
status = _mesa_CheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE)
|
||||
goto out;
|
||||
|
||||
ctx->Meta->Blit.no_ctsi_fallback = true;
|
||||
/* We skip the core BlitFramebuffer checks for format consistency, which
|
||||
* are too strict for CopyTexImage. We know meta will be fine with format
|
||||
* changes.
|
||||
*/
|
||||
_mesa_meta_BlitFramebuffer(ctx, x, y,
|
||||
x + width, y + height,
|
||||
xoffset, yoffset,
|
||||
xoffset + width, yoffset + height,
|
||||
mask, GL_NEAREST);
|
||||
ctx->Meta->Blit.no_ctsi_fallback = false;
|
||||
success = true;
|
||||
|
||||
out:
|
||||
_mesa_lock_texture(ctx, texObj);
|
||||
_mesa_DeleteFramebuffers(1, &fbo);
|
||||
_mesa_meta_end(ctx);
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions.
|
||||
* Have to be careful with locking and meta state for pixel transfer.
|
||||
|
@ -2745,11 +2819,14 @@ _mesa_meta_CopyTexSubImage(struct gl_context *ctx, GLuint dims,
|
|||
GLint bpp;
|
||||
void *buf;
|
||||
|
||||
/* The gl_renderbuffer is part of the interface for
|
||||
* dd_function_table::CopyTexSubImage, but this implementation does not use
|
||||
* it.
|
||||
*/
|
||||
(void) rb;
|
||||
if (copytexsubimage_using_blit_framebuffer(ctx, dims,
|
||||
texImage,
|
||||
xoffset, yoffset, zoffset,
|
||||
rb,
|
||||
x, y,
|
||||
width, height)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Choose format/type for temporary image buffer */
|
||||
format = _mesa_get_format_base_format(texImage->TexFormat);
|
||||
|
|
|
@ -253,6 +253,7 @@ struct blit_state
|
|||
struct blit_shader_table shaders;
|
||||
GLuint msaa_shaders[BLIT_MSAA_SHADER_COUNT];
|
||||
struct temp_texture depthTex;
|
||||
bool no_ctsi_fallback;
|
||||
};
|
||||
|
||||
|
||||
|
@ -505,6 +506,7 @@ void
|
|||
_mesa_meta_glsl_generate_mipmap_cleanup(struct gen_mipmap_state *mipmap);
|
||||
|
||||
void
|
||||
_mesa_meta_bind_fbo_image(struct gl_texture_image *texImage, GLuint layer);
|
||||
_mesa_meta_bind_fbo_image(GLenum attachment,
|
||||
struct gl_texture_image *texImage, GLuint layer);
|
||||
|
||||
#endif /* META_H */
|
||||
|
|
|
@ -419,6 +419,9 @@ blitframebuffer_texture(struct gl_context *ctx,
|
|||
/* Fall back to doing a CopyTexSubImage to get the destination
|
||||
* renderbuffer into a texture.
|
||||
*/
|
||||
if (ctx->Meta->Blit.no_ctsi_fallback)
|
||||
return false;
|
||||
|
||||
if (rb->NumSamples > 1)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ fallback_required(struct gl_context *ctx, GLenum target,
|
|||
_mesa_GenFramebuffers(1, &mipmap->FBO);
|
||||
_mesa_BindFramebuffer(GL_FRAMEBUFFER_EXT, mipmap->FBO);
|
||||
|
||||
_mesa_meta_bind_fbo_image(baseImage, 0);
|
||||
_mesa_meta_bind_fbo_image(GL_COLOR_ATTACHMENT0, baseImage, 0);
|
||||
|
||||
status = _mesa_CheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
|
||||
|
||||
|
@ -317,7 +317,7 @@ _mesa_meta_GenerateMipmap(struct gl_context *ctx, GLenum target,
|
|||
_mesa_BufferData(GL_ARRAY_BUFFER_ARB, sizeof(verts),
|
||||
verts, GL_DYNAMIC_DRAW_ARB);
|
||||
|
||||
_mesa_meta_bind_fbo_image(dstImage, layer);
|
||||
_mesa_meta_bind_fbo_image(GL_COLOR_ATTACHMENT0, dstImage, layer);
|
||||
|
||||
/* sanity check */
|
||||
if (_mesa_CheckFramebufferStatus(GL_FRAMEBUFFER) !=
|
||||
|
|
Loading…
Reference in New Issue