mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-05 09:00:08 +01:00
st/mesa: optimize 4-component ubyte glDrawPixels
If we didn't find a gallium surface format that exactly matched the glDrawPixels format/type combination, we used some other 32-bit packed RGBA format and swizzled the whole image in the mesa texstore/format code. That slow path can be avoided in some common cases by using the pipe_samper_view's swizzle terms to do the swizzling at texture sampling time instead. For now, only GL_RGBA/ubyte and GL_BGRA/ubyte combinations are supported. In the future other formats and types like GL_UNSIGNED_INT_8_8_8_8 could be added. v2: fix incorrect swizzle setup (need to invert the tex format's swizzle) Reviewed by: Jose Fonseca <jfonseca@vmware.com>
This commit is contained in:
parent
cf405922eb
commit
d11fefa961
1 changed files with 95 additions and 9 deletions
|
|
@ -395,15 +395,35 @@ make_texture(struct st_context *st,
|
|||
* Note that the image is actually going to be upside down in
|
||||
* the texture. We deal with that with texcoords.
|
||||
*/
|
||||
success = _mesa_texstore(ctx, 2, /* dims */
|
||||
baseInternalFormat, /* baseInternalFormat */
|
||||
mformat, /* mesa_format */
|
||||
transfer->stride, /* dstRowStride, bytes */
|
||||
&dest, /* destSlices */
|
||||
width, height, 1, /* size */
|
||||
format, type, /* src format/type */
|
||||
pixels, /* data source */
|
||||
unpack);
|
||||
if ((format == GL_RGBA || format == GL_BGRA)
|
||||
&& type == GL_UNSIGNED_BYTE) {
|
||||
/* Use a memcpy-based texstore to avoid software pixel swizzling.
|
||||
* We'll do the necessary swizzling with the pipe_sampler_view to
|
||||
* give much better performance.
|
||||
* XXX in the future, expand this to accomodate more format and
|
||||
* type combinations.
|
||||
*/
|
||||
_mesa_memcpy_texture(ctx, 2,
|
||||
mformat, /* mesa_format */
|
||||
transfer->stride, /* dstRowStride, bytes */
|
||||
&dest, /* destSlices */
|
||||
width, height, 1, /* size */
|
||||
format, type, /* src format/type */
|
||||
pixels, /* data source */
|
||||
unpack);
|
||||
success = GL_TRUE;
|
||||
}
|
||||
else {
|
||||
success = _mesa_texstore(ctx, 2, /* dims */
|
||||
baseInternalFormat, /* baseInternalFormat */
|
||||
mformat, /* mesa_format */
|
||||
transfer->stride, /* dstRowStride, bytes */
|
||||
&dest, /* destSlices */
|
||||
width, height, 1, /* size */
|
||||
format, type, /* src format/type */
|
||||
pixels, /* data source */
|
||||
unpack);
|
||||
}
|
||||
|
||||
/* unmap */
|
||||
pipe_transfer_unmap(pipe, transfer);
|
||||
|
|
@ -957,6 +977,69 @@ clamp_size(struct pipe_context *pipe, GLsizei *width, GLsizei *height,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Search the array of 4 swizzle components for the named component and return
|
||||
* its position.
|
||||
*/
|
||||
static unsigned
|
||||
search_swizzle(const unsigned char swizzle[4], unsigned component)
|
||||
{
|
||||
unsigned i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (swizzle[i] == component)
|
||||
return i;
|
||||
}
|
||||
assert(!"search_swizzle() failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the sampler view's swizzle terms. This is used to handle RGBA
|
||||
* swizzling when the incoming image format isn't an exact match for
|
||||
* the actual texture format. For example, if we have glDrawPixels(
|
||||
* GL_RGBA, GL_UNSIGNED_BYTE) and we chose the texture format
|
||||
* PIPE_FORMAT_B8G8R8A8 then we can do use the sampler view swizzle to
|
||||
* avoid swizzling all the pixels in software in the texstore code.
|
||||
*/
|
||||
static void
|
||||
setup_sampler_swizzle(struct pipe_sampler_view *sv, GLenum format, GLenum type)
|
||||
{
|
||||
if ((format == GL_RGBA || format == GL_BGRA) && type == GL_UNSIGNED_BYTE) {
|
||||
const struct util_format_description *desc =
|
||||
util_format_description(sv->texture->format);
|
||||
unsigned c0, c1, c2, c3;
|
||||
|
||||
/* Every gallium driver supports at least one 32-bit packed RGBA format.
|
||||
* We must have chosen one for (GL_RGBA, GL_UNSIGNED_BYTE).
|
||||
*/
|
||||
assert(desc->block.bits == 32);
|
||||
|
||||
/* invert the format's swizzle to setup the sampler's swizzle */
|
||||
if (format == GL_RGBA) {
|
||||
c0 = UTIL_FORMAT_SWIZZLE_X;
|
||||
c1 = UTIL_FORMAT_SWIZZLE_Y;
|
||||
c2 = UTIL_FORMAT_SWIZZLE_Z;
|
||||
c3 = UTIL_FORMAT_SWIZZLE_W;
|
||||
}
|
||||
else {
|
||||
assert(format == GL_BGRA);
|
||||
c0 = UTIL_FORMAT_SWIZZLE_Z;
|
||||
c1 = UTIL_FORMAT_SWIZZLE_Y;
|
||||
c2 = UTIL_FORMAT_SWIZZLE_X;
|
||||
c3 = UTIL_FORMAT_SWIZZLE_W;
|
||||
}
|
||||
sv->swizzle_r = search_swizzle(desc->swizzle, c0);
|
||||
sv->swizzle_g = search_swizzle(desc->swizzle, c1);
|
||||
sv->swizzle_b = search_swizzle(desc->swizzle, c2);
|
||||
sv->swizzle_a = search_swizzle(desc->swizzle, c3);
|
||||
}
|
||||
else {
|
||||
/* use the default sampler swizzle */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called via ctx->Driver.DrawPixels()
|
||||
*/
|
||||
|
|
@ -1046,6 +1129,9 @@ st_DrawPixels(struct gl_context *ctx, GLint x, GLint y,
|
|||
return;
|
||||
}
|
||||
|
||||
/* Set up the sampler view's swizzle */
|
||||
setup_sampler_swizzle(sv[0], format, type);
|
||||
|
||||
/* Create a second sampler view to read stencil. The stencil is
|
||||
* written using the shader stencil export functionality.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue