[Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color v2
Jose Fonseca
jfonseca at vmware.com
Tue Apr 16 13:38:26 PDT 2013
Thanks for the update.
Looks good to me FWIW.
Jose
----- Original Message -----
> From: Christoph Bumiller <christoph.bumiller at speed.at>
>
> This is the only sane solution for nv50 and nvc0 (really, trust me),
> but since on other hardware the border colour is tightly coupled with
> texture state they'd have to undo the swizzle, so I've added a cap.
>
> The dependency of update_sampler on the texture updates was
> introduced to avoid doing the apply_depthmode to the swizzle twice.
>
> v2: Moved swizzling helper to u_format.c, extended the CAP to
> provide more accurate information.
> ---
> src/gallium/auxiliary/util/u_format.c | 34
> ++++++++++++++++++++++
> src/gallium/auxiliary/util/u_format.h | 12 ++++++++
> src/gallium/docs/source/cso/sampler.rst | 6 ++-
> src/gallium/docs/source/screen.rst | 11 +++++++
> src/gallium/drivers/freedreno/freedreno_screen.c | 1 +
> src/gallium/drivers/i915/i915_screen.c | 1 +
> src/gallium/drivers/llvmpipe/lp_screen.c | 2 +
> src/gallium/drivers/nv30/nv30_screen.c | 1 +
> src/gallium/drivers/nv50/nv50_screen.c | 2 +
> src/gallium/drivers/nvc0/nvc0_screen.c | 2 +
> src/gallium/drivers/r300/r300_screen.c | 1 +
> src/gallium/drivers/r600/r600_pipe.c | 3 ++
> src/gallium/drivers/radeonsi/radeonsi_pipe.c | 1 +
> src/gallium/drivers/softpipe/sp_screen.c | 2 +
> src/gallium/drivers/svga/svga_screen.c | 2 +
> src/gallium/include/pipe/p_defines.h | 7 ++++-
> src/mesa/state_tracker/st_atom.c | 2 +-
> src/mesa/state_tracker/st_atom_sampler.c | 27 +++++++++++++++--
> src/mesa/state_tracker/st_context.c | 3 ++
> src/mesa/state_tracker/st_context.h | 1 +
> 20 files changed, 114 insertions(+), 7 deletions(-)
>
> diff --git a/src/gallium/auxiliary/util/u_format.c
> b/src/gallium/auxiliary/util/u_format.c
> index 1845637..9bdc2ea 100644
> --- a/src/gallium/auxiliary/util/u_format.c
> +++ b/src/gallium/auxiliary/util/u_format.c
> @@ -632,6 +632,40 @@ void util_format_compose_swizzles(const unsigned char
> swz1[4],
> }
> }
>
> +void util_format_apply_color_swizzle(union pipe_color_union *dst,
> + const union pipe_color_union *src,
> + const unsigned char swz[4],
> + const boolean is_integer)
> +{
> + unsigned c;
> +
> + if (is_integer) {
> + for (c = 0; c < 4; ++c) {
> + switch (swz[c]) {
> + case PIPE_SWIZZLE_RED: dst->ui[c] = src->ui[0]; break;
> + case PIPE_SWIZZLE_GREEN: dst->ui[c] = src->ui[1]; break;
> + case PIPE_SWIZZLE_BLUE: dst->ui[c] = src->ui[2]; break;
> + case PIPE_SWIZZLE_ALPHA: dst->ui[c] = src->ui[3]; break;
> + default:
> + dst->ui[c] = (swz[c] == PIPE_SWIZZLE_ONE) ? 1 : 0;
> + break;
> + }
> + }
> + } else {
> + for (c = 0; c < 4; ++c) {
> + switch (swz[c]) {
> + case PIPE_SWIZZLE_RED: dst->f[c] = src->f[0]; break;
> + case PIPE_SWIZZLE_GREEN: dst->f[c] = src->f[1]; break;
> + case PIPE_SWIZZLE_BLUE: dst->f[c] = src->f[2]; break;
> + case PIPE_SWIZZLE_ALPHA: dst->f[c] = src->f[3]; break;
> + default:
> + dst->f[c] = (swz[c] == PIPE_SWIZZLE_ONE) ? 1.0f : 0.0f;
> + break;
> + }
> + }
> + }
> +}
> +
> void util_format_swizzle_4f(float *dst, const float *src,
> const unsigned char swz[4])
> {
> diff --git a/src/gallium/auxiliary/util/u_format.h
> b/src/gallium/auxiliary/util/u_format.h
> index ed942fb..e4b9c36 100644
> --- a/src/gallium/auxiliary/util/u_format.h
> +++ b/src/gallium/auxiliary/util/u_format.h
> @@ -33,6 +33,9 @@
> #include "pipe/p_format.h"
> #include "util/u_debug.h"
>
> +union pipe_color_union;
> +
> +
> #ifdef __cplusplus
> extern "C" {
> #endif
> @@ -1117,6 +1120,15 @@ void util_format_compose_swizzles(const unsigned char
> swz1[4],
> const unsigned char swz2[4],
> unsigned char dst[4]);
>
> +/* Apply the swizzle provided in \param swz (which is one of PIPE_SWIZZLE_x)
> + * to \param src and store the result in \param dst.
> + * \param is_integer determines the value written for PIPE_SWIZZLE_ONE.
> + */
> +void util_format_apply_color_swizzle(union pipe_color_union *dst,
> + const union pipe_color_union *src,
> + const unsigned char swz[4],
> + const boolean is_integer);
> +
> void util_format_swizzle_4f(float *dst, const float *src,
> const unsigned char swz[4]);
>
> diff --git a/src/gallium/docs/source/cso/sampler.rst
> b/src/gallium/docs/source/cso/sampler.rst
> index 26ffc18..9959793 100644
> --- a/src/gallium/docs/source/cso/sampler.rst
> +++ b/src/gallium/docs/source/cso/sampler.rst
> @@ -101,7 +101,9 @@ max_lod
> border_color
> Color union used for texel coordinates that are outside the [0,width-1],
> [0, height-1] or [0, depth-1] ranges. Interpreted according to sampler
> - view format.
> + view format, unless the driver reports
> + PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK, in which case special care has to
> be
> + taken (see description of the cap).
> max_anisotropy
> Maximum anistropy ratio to use when sampling from textures. For
> example,
> if max_anistropy=4, a region of up to 1 by 4 texels will be sampled.
> @@ -111,4 +113,4 @@ max_anisotropy
> seamless_cube_map
> If set, the bilinear filter of a cube map may take samples from adjacent
> cube map faces when sampled near a texture border to produce a seamless
> - look.
> \ No newline at end of file
> + look.
> diff --git a/src/gallium/docs/source/screen.rst
> b/src/gallium/docs/source/screen.rst
> index 4b01d77..3ab7e9e 100644
> --- a/src/gallium/docs/source/screen.rst
> +++ b/src/gallium/docs/source/screen.rst
> @@ -151,6 +151,17 @@ The integer capabilities:
> dedicated memory should return 1 and all software rasterizers should
> return 0.
> * ``PIPE_CAP_QUERY_PIPELINE_STATISTICS``: Whether
> PIPE_QUERY_PIPELINE_STATISTICS
> is supported.
> +* ``PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK``: Bitmask indicating whether
> special
> + considerations have to be given to the interaction between the border
> color
> + in the sampler object and the sampler view used with it.
> + If PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600 is set, the border color
> + may be affected in undefined ways for any kind of permutational swizzle
> + (any swizzle XYZW where X/Y/Z/W are not ZERO, ONE, or R/G/B/A
> respectively)
> + in the sampler view.
> + If PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 is set, the border color
> + state should be swizzled manually according to the swizzle in the sampler
> + view it is intended to be used with, or herein undefined results may occur
> + for permutational swizzles.
>
>
> .. _pipe_capf:
> diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c
> b/src/gallium/drivers/freedreno/freedreno_screen.c
> index 283d07f..4a9a54e 100644
> --- a/src/gallium/drivers/freedreno/freedreno_screen.c
> +++ b/src/gallium/drivers/freedreno/freedreno_screen.c
> @@ -200,6 +200,7 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
> case PIPE_CAP_USER_VERTEX_BUFFERS:
> case PIPE_CAP_USER_INDEX_BUFFERS:
> case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
> + case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> return 0;
>
> /* Stream output. */
> diff --git a/src/gallium/drivers/i915/i915_screen.c
> b/src/gallium/drivers/i915/i915_screen.c
> index 54b2154..dfb76b3 100644
> --- a/src/gallium/drivers/i915/i915_screen.c
> +++ b/src/gallium/drivers/i915/i915_screen.c
> @@ -213,6 +213,7 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap
> cap)
> case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
> case PIPE_CAP_TEXTURE_MULTISAMPLE:
> case PIPE_CAP_MIN_MAP_BUFFER_ALIGNMENT:
> + case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> return 0;
>
> case PIPE_CAP_CONSTANT_BUFFER_OFFSET_ALIGNMENT:
> diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c
> b/src/gallium/drivers/llvmpipe/lp_screen.c
> index ebcf680..1eed5f6 100644
> --- a/src/gallium/drivers/llvmpipe/lp_screen.c
> +++ b/src/gallium/drivers/llvmpipe/lp_screen.c
> @@ -138,6 +138,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum
> pipe_cap param)
> return 1;
> case PIPE_CAP_TEXTURE_SWIZZLE:
> return 1;
> + case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> + return 0;
> case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
> return LP_MAX_TEXTURE_2D_LEVELS;
> case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
> diff --git a/src/gallium/drivers/nv30/nv30_screen.c
> b/src/gallium/drivers/nv30/nv30_screen.c
> index e33710e..5b3b470 100644
> --- a/src/gallium/drivers/nv30/nv30_screen.c
> +++ b/src/gallium/drivers/nv30/nv30_screen.c
> @@ -123,6 +123,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
> case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
> case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
> case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
> + case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> return 0;
> case PIPE_CAP_VERTEX_BUFFER_OFFSET_4BYTE_ALIGNED_ONLY:
> case PIPE_CAP_VERTEX_BUFFER_STRIDE_4BYTE_ALIGNED_ONLY:
> diff --git a/src/gallium/drivers/nv50/nv50_screen.c
> b/src/gallium/drivers/nv50/nv50_screen.c
> index 55081be..5aa8ef3 100644
> --- a/src/gallium/drivers/nv50/nv50_screen.c
> +++ b/src/gallium/drivers/nv50/nv50_screen.c
> @@ -186,6 +186,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
> return 1;
> case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
> return 0;
> + case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> + return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50;
> default:
> NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
> return 0;
> diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c
> b/src/gallium/drivers/nvc0/nvc0_screen.c
> index ccdf2cd..8dfd4d1 100644
> --- a/src/gallium/drivers/nvc0/nvc0_screen.c
> +++ b/src/gallium/drivers/nvc0/nvc0_screen.c
> @@ -176,6 +176,8 @@ nvc0_screen_get_param(struct pipe_screen *pscreen, enum
> pipe_cap param)
> return (class_3d >= NVE4_3D_CLASS) ? 1 : 0;
> case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
> return 1;
> + case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> + return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50;
> default:
> NOUVEAU_ERR("unknown PIPE_CAP %d\n", param);
> return 0;
> diff --git a/src/gallium/drivers/r300/r300_screen.c
> b/src/gallium/drivers/r300/r300_screen.c
> index 3175b3b..a932be9 100644
> --- a/src/gallium/drivers/r300/r300_screen.c
> +++ b/src/gallium/drivers/r300/r300_screen.c
> @@ -162,6 +162,7 @@ static int r300_get_param(struct pipe_screen* pscreen,
> enum pipe_cap param)
> case PIPE_CAP_CUBE_MAP_ARRAY:
> case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
> case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
> + case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> return 0;
>
> /* SWTCL-only features. */
> diff --git a/src/gallium/drivers/r600/r600_pipe.c
> b/src/gallium/drivers/r600/r600_pipe.c
> index 3f36e63..0f0864b 100644
> --- a/src/gallium/drivers/r600/r600_pipe.c
> +++ b/src/gallium/drivers/r600/r600_pipe.c
> @@ -653,6 +653,9 @@ static int r600_get_param(struct pipe_screen* pscreen,
> enum pipe_cap param)
>
> case PIPE_CAP_MAX_TEXEL_OFFSET:
> return 7;
> +
> + case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> + return PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600;
> }
> return 0;
> }
> diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> index 5c25b2f..4e97f51 100644
> --- a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> +++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> @@ -380,6 +380,7 @@ static int r600_get_param(struct pipe_screen* pscreen,
> enum pipe_cap param)
> case PIPE_CAP_CUBE_MAP_ARRAY:
> case PIPE_CAP_TEXTURE_BUFFER_OBJECTS:
> case PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
> + case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> return 0;
>
> /* Stream output. */
> diff --git a/src/gallium/drivers/softpipe/sp_screen.c
> b/src/gallium/drivers/softpipe/sp_screen.c
> index 6915f91..88f9ecd 100644
> --- a/src/gallium/drivers/softpipe/sp_screen.c
> +++ b/src/gallium/drivers/softpipe/sp_screen.c
> @@ -94,6 +94,8 @@ softpipe_get_param(struct pipe_screen *screen, enum
> pipe_cap param)
> return 1;
> case PIPE_CAP_TEXTURE_SWIZZLE:
> return 1;
> + case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> + return 0;
> case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
> return SP_MAX_TEXTURE_2D_LEVELS;
> case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
> diff --git a/src/gallium/drivers/svga/svga_screen.c
> b/src/gallium/drivers/svga/svga_screen.c
> index 6213535..60e0442 100644
> --- a/src/gallium/drivers/svga/svga_screen.c
> +++ b/src/gallium/drivers/svga/svga_screen.c
> @@ -166,6 +166,8 @@ svga_get_param(struct pipe_screen *screen, enum pipe_cap
> param)
> return 1;
> case PIPE_CAP_TEXTURE_SWIZZLE:
> return 1;
> + case PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK:
> + return 0;
> case PIPE_CAP_USER_VERTEX_BUFFERS:
> case PIPE_CAP_USER_INDEX_BUFFERS:
> return 0;
> diff --git a/src/gallium/include/pipe/p_defines.h
> b/src/gallium/include/pipe/p_defines.h
> index 9939325..95fc788 100644
> --- a/src/gallium/include/pipe/p_defines.h
> +++ b/src/gallium/include/pipe/p_defines.h
> @@ -505,9 +505,14 @@ enum pipe_cap {
> PIPE_CAP_TEXTURE_BUFFER_OFFSET_ALIGNMENT = 78,
> PIPE_CAP_TGSI_TEXCOORD = 79,
> PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER = 80,
> - PIPE_CAP_QUERY_PIPELINE_STATISTICS = 81
> + PIPE_CAP_QUERY_PIPELINE_STATISTICS = 81,
> + PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK = 82
> };
>
> +#define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50 (1 << 0)
> +#define PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600 (1 << 1)
> +
> +
> /**
> * Implementation limits which are queried through
> * pipe_screen::get_paramf()
> diff --git a/src/mesa/state_tracker/st_atom.c
> b/src/mesa/state_tracker/st_atom.c
> index 32bcc26..7d38392 100644
> --- a/src/mesa/state_tracker/st_atom.c
> +++ b/src/mesa/state_tracker/st_atom.c
> @@ -55,10 +55,10 @@ static const struct st_tracked_state *atoms[] =
> &st_update_viewport,
> &st_update_scissor,
> &st_update_blend,
> - &st_update_sampler,
> &st_update_vertex_texture,
> &st_update_fragment_texture,
> &st_update_geometry_texture,
> + &st_update_sampler, /* depends on update_*_texture for swizzle */
> &st_update_framebuffer,
> &st_update_msaa,
> &st_update_vs_constants,
> diff --git a/src/mesa/state_tracker/st_atom_sampler.c
> b/src/mesa/state_tracker/st_atom_sampler.c
> index 3eba5b1..db51eea 100644
> --- a/src/mesa/state_tracker/st_atom_sampler.c
> +++ b/src/mesa/state_tracker/st_atom_sampler.c
> @@ -48,6 +48,8 @@
>
> #include "cso_cache/cso_context.h"
>
> +#include "util/u_format.h"
> +
>
> /**
> * Convert GLenum texcoord wrap tokens to pipe tokens.
> @@ -172,8 +174,10 @@ convert_sampler(struct st_context *st,
> msamp->BorderColor.ui[1] ||
> msamp->BorderColor.ui[2] ||
> msamp->BorderColor.ui[3]) {
> + struct st_texture_object *stobj = st_texture_object(texobj);
> struct gl_texture_image *teximg;
> GLboolean is_integer = GL_FALSE;
> + union pipe_color_union border_color;
>
> teximg = texobj->Image[0][texobj->BaseLevel];
>
> @@ -181,9 +185,26 @@ convert_sampler(struct st_context *st,
> is_integer = _mesa_is_enum_format_integer(teximg->InternalFormat);
> }
>
> - st_translate_color(&msamp->BorderColor,
> - &sampler->border_color,
> - teximg ? teximg->_BaseFormat : GL_RGBA,
> is_integer);
> + if (st->apply_texture_swizzle_to_border_color && stobj->sampler_view)
> {
> + const unsigned char swz[4] =
> + {
> + stobj->sampler_view->swizzle_r,
> + stobj->sampler_view->swizzle_g,
> + stobj->sampler_view->swizzle_b,
> + stobj->sampler_view->swizzle_a,
> + };
> +
> + st_translate_color(&msamp->BorderColor,
> + &border_color,
> + teximg ? teximg->_BaseFormat : GL_RGBA,
> is_integer);
> +
> + util_format_apply_color_swizzle(&sampler->border_color,
> + &border_color, swz, is_integer);
> + } else {
> + st_translate_color(&msamp->BorderColor,
> + &sampler->border_color,
> + teximg ? teximg->_BaseFormat : GL_RGBA,
> is_integer);
> + }
> }
>
> sampler->max_anisotropy = (msamp->MaxAnisotropy == 1.0 ?
> diff --git a/src/mesa/state_tracker/st_context.c
> b/src/mesa/state_tracker/st_context.c
> index 2042be3..bb216e2 100644
> --- a/src/mesa/state_tracker/st_context.c
> +++ b/src/mesa/state_tracker/st_context.c
> @@ -188,6 +188,9 @@ st_create_context_priv( struct gl_context *ctx, struct
> pipe_context *pipe,
>
> st->needs_texcoord_semantic =
> screen->get_param(screen, PIPE_CAP_TGSI_TEXCOORD);
> + st->apply_texture_swizzle_to_border_color =
> + !!(screen->get_param(screen, PIPE_CAP_TEXTURE_BORDER_COLOR_QUIRK) &
> + PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_NV50);
>
> /* GL limits and extensions */
> st_init_limits(st);
> diff --git a/src/mesa/state_tracker/st_context.h
> b/src/mesa/state_tracker/st_context.h
> index 8786a03..807453e 100644
> --- a/src/mesa/state_tracker/st_context.h
> +++ b/src/mesa/state_tracker/st_context.h
> @@ -87,6 +87,7 @@ struct st_context
> boolean prefer_blit_based_texture_transfer;
>
> boolean needs_texcoord_semantic;
> + boolean apply_texture_swizzle_to_border_color;
>
> /* On old libGL's for linux we need to invalidate the drawables
> * on glViewpport calls, this is set via a option.
> --
> 1.7.3.4
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
>
More information about the mesa-dev
mailing list