[Mesa-dev] [PATCH 2/2] st/mesa: overhaul texture / sample swizzle code
Brian Paul
brianp at vmware.com
Wed Mar 26 16:17:10 PDT 2014
I haven't investigated fbo-blending-formats but if it's like
fbo-clear-formats, this fixes the piglit_draw_rect_tex() rendering which
displays the texture on a test quad.
-Brian
On 03/26/2014 03:52 PM, Marek Olšák wrote:
> Is this just a workaround for the fbo-blending-formats test? It should
> test if GL_DST_ALPHA is equivalent to GL_ONE if the format is RGBX. I
> don't think the test has anything to do with texturing.
>
> Marek
>
> On Wed, Mar 26, 2014 at 8:58 PM, Brian Paul <brianp at vmware.com> wrote:
>> Previously we only examined the GL_DEPTH_MODE state to determine the
>> sampler view swizzle for depth textures. Now we also consider the
>> texture base format for color textures too.
>>
>> The basic idea is if we're sampling from a RGB texture we always
>> want to get A=1, even if the actual hardware format might be RGBA.
>> We had assumed that the texture's A values were always one since that's
>> what Mesa's texstore code does. But if we render to the RGBA texture,
>> the A values might not be 1. Subsequent sampling didn't return the
>> right values.
>>
>> Now we examine the user-specified texture base format vs. the actual
>> gallium format to determine the right swizzle.
>>
>> Fixes several fbo-blending-formats, fbo-clear-formats and fbo-tex-rgbx
>> failures with VMware/svga driver (and possibly other drivers).
>> No other piglit regressions with softpipe or VMware/svga.
>> ---
>> src/mesa/state_tracker/st_atom_texture.c | 167 ++++++++++++++++++++----------
>> 1 file changed, 114 insertions(+), 53 deletions(-)
>>
>> diff --git a/src/mesa/state_tracker/st_atom_texture.c b/src/mesa/state_tracker/st_atom_texture.c
>> index c445213..c9bffce 100644
>> --- a/src/mesa/state_tracker/st_atom_texture.c
>> +++ b/src/mesa/state_tracker/st_atom_texture.c
>> @@ -83,67 +83,132 @@ swizzle_swizzle(unsigned swizzle1, unsigned swizzle2)
>>
>>
>> /**
>> - * Combine depth texture mode with "swizzle" so that depth mode swizzling
>> - * takes place before texture swizzling, and return the resulting swizzle.
>> - * If the format is not a depth format, return "swizzle" unchanged.
>> + * Given a user-specified texture base format, the actual gallium texture
>> + * format and the current GL_DEPTH_MODE, return a texture swizzle.
>> *
>> - * \param format PIPE_FORMAT_*.
>> - * \param swizzle Texture swizzle, a bitmask computed using MAKE_SWIZZLE4.
>> - * \param depthmode One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA, GL_RED.
>> + * Consider the case where the user requests a GL_RGB internal texture
>> + * format the driver actually uses an RGBA format. The A component should
>> + * be ignored and sampling from the texture should always return (r,g,b,1).
>> + * But if we rendered to the texture we might have written A values != 1.
>> + * By sampling the texture with a ".xyz1" swizzle we'll get the expected A=1.
>> + * This function computes the texture swizzle needed to get the expected
>> + * values.
>> + *
>> + * In the case of depth textures, the GL_DEPTH_MODE state determines the
>> + * texture swizzle.
>> + *
>> + * This result must be composed with the user-specified swizzle to get
>> + * the final swizzle.
>> */
>> -static GLuint
>> -apply_depthmode(enum pipe_format format, GLuint swizzle, GLenum depthmode)
>> +static unsigned
>> +compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode,
>> + enum pipe_format actualFormat)
>> {
>> - const struct util_format_description *desc =
>> - util_format_description(format);
>> - unsigned swz;
>> -
>> - if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS ||
>> - desc->swizzle[0] == UTIL_FORMAT_SWIZZLE_NONE) {
>> - /* Not a depth format. */
>> - return swizzle;
>> - }
>> -
>> - switch (depthmode) {
>> + switch (baseFormat) {
>> + case GL_RGBA:
>> + return SWIZZLE_XYZW;
>> + case GL_RGB:
>> + if (util_format_has_alpha(actualFormat))
>> + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
>> + else
>> + return SWIZZLE_XYZW;
>> + case GL_RG:
>> + if (util_format_get_nr_components(actualFormat) > 2)
>> + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE);
>> + else
>> + return SWIZZLE_XYZW;
>> + case GL_RED:
>> + if (util_format_get_nr_components(actualFormat) > 1)
>> + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
>> + SWIZZLE_ZERO, SWIZZLE_ONE);
>> + else
>> + return SWIZZLE_XYZW;
>> + case GL_ALPHA:
>> + if (util_format_get_nr_components(actualFormat) > 1)
>> + return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
>> + SWIZZLE_ZERO, SWIZZLE_W);
>> + else
>> + return SWIZZLE_XYZW;
>> case GL_LUMINANCE:
>> - swz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
>> - break;
>> + if (util_format_get_nr_components(actualFormat) > 1)
>> + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
>> + else
>> + return SWIZZLE_XYZW;
>> + case GL_LUMINANCE_ALPHA:
>> + if (util_format_get_nr_components(actualFormat) > 2)
>> + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_W);
>> + else
>> + return SWIZZLE_XYZW;
>> case GL_INTENSITY:
>> - swz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
>> - break;
>> - case GL_ALPHA:
>> - swz = MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_X);
>> - break;
>> - case GL_RED:
>> - swz = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE);
>> - break;
>> + if (util_format_get_nr_components(actualFormat) > 1)
>> + return SWIZZLE_XXXX;
>> + else
>> + return SWIZZLE_XYZW;
>> + case GL_STENCIL_INDEX:
>> + return SWIZZLE_XYZW;
>> + case GL_DEPTH_STENCIL:
>> + /* fall-through */
>> + case GL_DEPTH_COMPONENT:
>> + /* Now examine the depth mode */
>> + switch (depthMode) {
>> + case GL_LUMINANCE:
>> + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE);
>> + case GL_INTENSITY:
>> + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
>> + case GL_ALPHA:
>> + return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO,
>> + SWIZZLE_ZERO, SWIZZLE_X);
>> + case GL_RED:
>> + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO,
>> + SWIZZLE_ZERO, SWIZZLE_ONE);
>> + default:
>> + assert(!"Unexpected depthMode");
>> + return SWIZZLE_XYZW;
>> + }
>> + default:
>> + assert(!"Unexpected baseFormat");
>> + return SWIZZLE_XYZW;
>> }
>> -
>> - return swizzle_swizzle(swizzle, swz);
>> }
>>
>>
>> +static unsigned
>> +get_texture_format_swizzle(const struct st_texture_object *stObj)
>> +{
>> + const struct gl_texture_image *texImage =
>> + stObj->base.Image[0][stObj->base.BaseLevel];
>> + unsigned tex_swizzle;
>> +
>> + if (texImage) {
>> + tex_swizzle = compute_texture_format_swizzle(texImage->_BaseFormat,
>> + stObj->base.DepthMode,
>> + stObj->pt->format);
>> + }
>> + else {
>> + tex_swizzle = SWIZZLE_XYZW;
>> + }
>> +
>> + /* Combine the texture format swizzle with user's swizzle */
>> + return swizzle_swizzle(stObj->base._Swizzle, tex_swizzle);
>> +}
>> +
>> +
>> /**
>> - * Return TRUE if the swizzling described by "swizzle" and
>> - * "depthmode" (for depth textures only) is different from the swizzling
>> - * set in the given sampler view.
>> + * Return TRUE if the texture's sampler view swizzle is equal to
>> + * the texture's swizzle.
>> *
>> - * \param sv A sampler view.
>> - * \param swizzle Texture swizzle, a bitmask computed using MAKE_SWIZZLE4.
>> - * \param depthmode One of GL_LUMINANCE, GL_INTENSITY, GL_ALPHA.
>> + * \param stObj the st texture object,
>> */
>> static boolean
>> -check_sampler_swizzle(struct pipe_sampler_view *sv,
>> - GLuint swizzle, GLenum depthmode)
>> +check_sampler_swizzle(const struct st_texture_object *stObj)
>> {
>> - swizzle = apply_depthmode(sv->texture->format, swizzle, depthmode);
>> -
>> - if ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
>> - (sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
>> - (sv->swizzle_b != GET_SWZ(swizzle, 2)) ||
>> - (sv->swizzle_a != GET_SWZ(swizzle, 3)))
>> - return TRUE;
>> - return FALSE;
>> + const struct pipe_sampler_view *sv = stObj->sampler_view;
>> + unsigned swizzle = get_texture_format_swizzle(stObj);
>> +
>> + return ((sv->swizzle_r != GET_SWZ(swizzle, 0)) ||
>> + (sv->swizzle_g != GET_SWZ(swizzle, 1)) ||
>> + (sv->swizzle_b != GET_SWZ(swizzle, 2)) ||
>> + (sv->swizzle_a != GET_SWZ(swizzle, 3)));
>> }
>>
>>
>> @@ -154,9 +219,7 @@ st_create_texture_sampler_view_from_stobj(struct pipe_context *pipe,
>> enum pipe_format format)
>> {
>> struct pipe_sampler_view templ;
>> - GLuint swizzle = apply_depthmode(stObj->pt->format,
>> - stObj->base._Swizzle,
>> - stObj->base.DepthMode);
>> + unsigned swizzle = get_texture_format_swizzle(stObj);
>>
>> u_sampler_view_default_template(&templ,
>> stObj->pt,
>> @@ -269,9 +332,7 @@ update_single_texture(struct st_context *st,
>>
>> /* if sampler view has changed dereference it */
>> if (stObj->sampler_view) {
>> - if (check_sampler_swizzle(stObj->sampler_view,
>> - stObj->base._Swizzle,
>> - stObj->base.DepthMode) ||
>> + if (check_sampler_swizzle(stObj) ||
>> (view_format != stObj->sampler_view->format) ||
>> stObj->base.BaseLevel != stObj->sampler_view->u.tex.first_level) {
>> pipe_sampler_view_release(pipe, &stObj->sampler_view);
>> --
>> 1.7.10.4
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> https://urldefense.proofpoint.com/v1/url?u=http://lists.freedesktop.org/mailman/listinfo/mesa-dev&k=oIvRg1%2BdGAgOoM1BIlLLqw%3D%3D%0A&r=lGQMzzTgII0I7jefp2FHq7WtZ%2BTLs8wadB%2BiIj9xpBY%3D%0A&m=sXz9YdJT4PP545fmo2CytUHCpH6BhyGKPB9eYCZ7G04%3D%0A&s=dc146584aafc81ec2b72a97e3fb2b0deecb937fc7c28d4f0e8413e8c143bd358
More information about the mesa-dev
mailing list