[Mesa-dev] [PATCH 2/2] st/mesa: overhaul texture / sample swizzle code
Marek Olšák
maraeo at gmail.com
Wed Mar 26 17:06:02 PDT 2014
The patch looks good to me. There is hardware which doesn't support
swizzling, but it sure isn't radeon.
Marek
On Thu, Mar 27, 2014 at 12:17 AM, Brian Paul <brianp at vmware.com> wrote:
>
> 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