st/mesa: Do GL_RGBA->GL_RGB texsubimage on hardware
State tracker currently backs GL_RGB textures with RGBA almost always. This means we need to maintain A==1 in these textures to give correct GL_RGB sampling results. This change offloads the RGBA->RGB copy to hardware using the new writemask version of u_blit_pixels. More src/dstLogical/dstActual triples could be shifted to hardware by this technique in future patches.
This commit is contained in:

committed by
Brian Paul

parent
862724d3c2
commit
8fc945cd84
@@ -56,6 +56,7 @@
|
|||||||
#include "pipe/p_context.h"
|
#include "pipe/p_context.h"
|
||||||
#include "pipe/p_defines.h"
|
#include "pipe/p_defines.h"
|
||||||
#include "pipe/p_inlines.h"
|
#include "pipe/p_inlines.h"
|
||||||
|
#include "pipe/p_shader_tokens.h"
|
||||||
#include "util/u_tile.h"
|
#include "util/u_tile.h"
|
||||||
#include "util/u_blit.h"
|
#include "util/u_blit.h"
|
||||||
#include "util/u_surface.h"
|
#include "util/u_surface.h"
|
||||||
@@ -1393,6 +1394,36 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned
|
||||||
|
compatible_src_dst_formats(const struct gl_renderbuffer *src,
|
||||||
|
const struct gl_texture_image *dst)
|
||||||
|
{
|
||||||
|
const GLenum srcFormat = src->_BaseFormat;
|
||||||
|
const GLenum dstLogicalFormat = dst->_BaseFormat;
|
||||||
|
|
||||||
|
if (srcFormat == dstLogicalFormat) {
|
||||||
|
/* This is the same as matching_base_formats, which should
|
||||||
|
* always pass, as it did previously.
|
||||||
|
*/
|
||||||
|
return TGSI_WRITEMASK_XYZW;
|
||||||
|
}
|
||||||
|
else if (srcFormat == GL_RGBA &&
|
||||||
|
dstLogicalFormat == GL_RGB) {
|
||||||
|
/* Add a single special case to cope with RGBA->RGB transfers,
|
||||||
|
* setting A to 1.0 to cope with situations where the RGB
|
||||||
|
* destination is actually stored as RGBA.
|
||||||
|
*/
|
||||||
|
return TGSI_WRITEMASK_XYZ; /* A ==> 1.0 */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Otherwise fail.
|
||||||
|
*/
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.
|
* Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.
|
||||||
* Note that the region to copy has already been clipped so we know we
|
* Note that the region to copy has already been clipped so we know we
|
||||||
@@ -1422,6 +1453,9 @@ st_copy_texsubimage(GLcontext *ctx,
|
|||||||
enum pipe_format dest_format, src_format;
|
enum pipe_format dest_format, src_format;
|
||||||
GLboolean use_fallback = GL_TRUE;
|
GLboolean use_fallback = GL_TRUE;
|
||||||
GLboolean matching_base_formats;
|
GLboolean matching_base_formats;
|
||||||
|
GLuint format_writemask;
|
||||||
|
struct pipe_surface *dest_surface = NULL;
|
||||||
|
GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
|
||||||
|
|
||||||
/* any rendering in progress must flushed before we grab the fb image */
|
/* any rendering in progress must flushed before we grab the fb image */
|
||||||
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
|
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
|
||||||
@@ -1492,13 +1526,14 @@ st_copy_texsubimage(GLcontext *ctx,
|
|||||||
* textured-quad paths.
|
* textured-quad paths.
|
||||||
*/
|
*/
|
||||||
matching_base_formats = (strb->Base._BaseFormat == texImage->_BaseFormat);
|
matching_base_formats = (strb->Base._BaseFormat == texImage->_BaseFormat);
|
||||||
|
format_writemask = compatible_src_dst_formats(&strb->Base, texImage);
|
||||||
|
|
||||||
if (matching_base_formats && ctx->_ImageTransferState == 0x0) {
|
if (ctx->_ImageTransferState == 0x0) {
|
||||||
/* try potential hardware path */
|
|
||||||
struct pipe_surface *dest_surface = NULL;
|
|
||||||
boolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
|
|
||||||
|
|
||||||
if (src_format == dest_format && !do_flip) {
|
if (matching_base_formats &&
|
||||||
|
src_format == dest_format &&
|
||||||
|
!do_flip)
|
||||||
|
{
|
||||||
/* use surface_copy() / blit */
|
/* use surface_copy() / blit */
|
||||||
|
|
||||||
dest_surface = screen->get_tex_surface(screen, stImage->pt,
|
dest_surface = screen->get_tex_surface(screen, stImage->pt,
|
||||||
@@ -1518,7 +1553,8 @@ st_copy_texsubimage(GLcontext *ctx,
|
|||||||
width, height);
|
width, height);
|
||||||
use_fallback = GL_FALSE;
|
use_fallback = GL_FALSE;
|
||||||
}
|
}
|
||||||
else if (screen->is_format_supported(screen, src_format,
|
else if (format_writemask &&
|
||||||
|
screen->is_format_supported(screen, src_format,
|
||||||
PIPE_TEXTURE_2D,
|
PIPE_TEXTURE_2D,
|
||||||
PIPE_TEXTURE_USAGE_SAMPLER,
|
PIPE_TEXTURE_USAGE_SAMPLER,
|
||||||
0) &&
|
0) &&
|
||||||
@@ -1542,14 +1578,15 @@ st_copy_texsubimage(GLcontext *ctx,
|
|||||||
srcY0 = srcY;
|
srcY0 = srcY;
|
||||||
srcY1 = srcY0 + height;
|
srcY1 = srcY0 + height;
|
||||||
}
|
}
|
||||||
util_blit_pixels(ctx->st->blit,
|
util_blit_pixels_writemask(ctx->st->blit,
|
||||||
strb->surface,
|
strb->surface,
|
||||||
srcX, srcY0,
|
srcX, srcY0,
|
||||||
srcX + width, srcY1,
|
srcX + width, srcY1,
|
||||||
dest_surface,
|
dest_surface,
|
||||||
destX, destY,
|
destX, destY,
|
||||||
destX + width, destY + height,
|
destX + width, destY + height,
|
||||||
0.0, PIPE_TEX_MIPFILTER_NEAREST);
|
0.0, PIPE_TEX_MIPFILTER_NEAREST,
|
||||||
|
format_writemask);
|
||||||
use_fallback = GL_FALSE;
|
use_fallback = GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user