[Mesa-dev] [PATCH 4/4] st/mesa: optimize 4-component ubyte glDrawPixels
Brian Paul
brianp at vmware.com
Fri Oct 16 19:30:07 PDT 2015
On 10/16/2015 05:53 PM, Jose Fonseca wrote:
> On 15/10/15 20:01, Brian Paul wrote:
>> 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.
>> ---
>> src/mesa/state_tracker/st_cb_drawpixels.c | 73
>> +++++++++++++++++++++++++++----
>> 1 file changed, 64 insertions(+), 9 deletions(-)
>>
>> diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c
>> b/src/mesa/state_tracker/st_cb_drawpixels.c
>> index 05f6e6b..a135761 100644
>> --- a/src/mesa/state_tracker/st_cb_drawpixels.c
>> +++ b/src/mesa/state_tracker/st_cb_drawpixels.c
>> @@ -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);
>> @@ -958,6 +978,38 @@ clamp_size(struct pipe_context *pipe, GLsizei
>> *width, GLsizei *height,
>>
>>
>> /**
>> + * 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);
>> + /* 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);
>> + /* use the format's swizzle to setup the sampler swizzle */
>> + sv->swizzle_r = desc->swizzle[0];
>> + sv->swizzle_g = desc->swizzle[1];
>> + sv->swizzle_b = desc->swizzle[2];
>> + sv->swizzle_a = desc->swizzle[3];
>
> I think it should be the other way around: the sampler view's swizzle
> should _undo_ the format swizzle, not apply it again.
>
> This indeed works for RGBA8_URNOM / BGRA8_UNORM, but by mere
> coincidence. It will fail for something like ABGR8_UNORM.
>
> If you don't want to deal with the swizzle inversion now, it might be
> better to explicitly check that the texture->format is RGBA8_URNOM /
> BGRA8_UNORM
I'll rework it. I think I just got lucky with my testing.
-Brian
More information about the mesa-dev
mailing list