[Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
Marek Olšák
maraeo at gmail.com
Sat Apr 13 12:35:42 PDT 2013
PIPE_CAP_TEXTURE_SWIZZLE_AFFECTS_BORDER_COLOR would be a better name (note
the meaning is inverted). Other than that, this looks good.
Marek
On Sat, Apr 13, 2013 at 4:31 PM, Christoph Bumiller <
e0425955 at student.tuwien.ac.at> wrote:
> 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 name of the cap could be changed to be more descriptive, like
> PIPE_CAP_TEXTURE_SWIZZLE_AFFECTS_BORDER_COLOR.
>
> The dependency of update_sampler on the texture updates was
> introduced to avoid doing the apply_depthmode to the swizzle twice.
>
> More detailed explanation of driver situation:
>
> No, really, don't suggest doing this in the driver. The driver has
> elegantly separated texture view and sampler states (which are each
> a structure in a table in VRAM and should not be updated to avoid
> performance loss), and table are bound to the independent (!) texture
> and sampler slots in shaders which must be separately indexable
> indirectly).
> So, if I was to do this in the driver, I'd have to add separate sampler
> state object instances for each texture view with appropriately swizzled
> border color, and there's only 16 slots, so I'd be limited to 4 texture
> units.
> Not to mention the sheer insanity, ugliness and emotional pain incurred
> when writing that code when it COULD be so easy and simple in the state
> tracker where you know that textures and samplers are tightly coupled,
> while in gallium I cannot assume that to be the case.
> ---
> src/gallium/docs/source/cso/sampler.rst | 7 ++-
> src/gallium/docs/source/screen.rst | 2 +
> 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 | 1 +
> src/gallium/drivers/nvc0/nvc0_screen.c | 1 +
> src/gallium/drivers/r300/r300_screen.c | 1 +
> src/gallium/drivers/r600/r600_pipe.c | 1 +
> 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 | 3 +-
> src/mesa/state_tracker/st_atom.c | 2 +-
> src/mesa/state_tracker/st_atom_sampler.c | 65
> +++++++++++++++++++++-
> src/mesa/state_tracker/st_context.c | 2 +
> src/mesa/state_tracker/st_context.h | 1 +
> 18 files changed, 89 insertions(+), 7 deletions(-)
>
> diff --git a/src/gallium/docs/source/cso/sampler.rst
> b/src/gallium/docs/source/cso/sampler.rst
> index 26ffc18..1911cea 100644
> --- a/src/gallium/docs/source/cso/sampler.rst
> +++ b/src/gallium/docs/source/cso/sampler.rst
> @@ -101,7 +101,10 @@ 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_BORDER_COLOR_QUIRK, in which case this value is substituted
> for
> + the texture color exactly as specified, the sampler view format and
> swizzle
> + have no effect on it.
> 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 +114,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..495398b 100644
> --- a/src/gallium/docs/source/screen.rst
> +++ b/src/gallium/docs/source/screen.rst
> @@ -151,6 +151,8 @@ 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_BORDER_COLOR_QUIRK``: Whether the sampler view's format and
> swizzle
> + affect the border color.
>
>
> .. _pipe_capf:
> diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c
> b/src/gallium/drivers/freedreno/freedreno_screen.c
> index 283d07f..5b60401 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_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..4c3d52f 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_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..9506162 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_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..52a3ec9 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_BORDER_COLOR_QUIRK: /* TODO: check */
> 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..39e0e63 100644
> --- a/src/gallium/drivers/nv50/nv50_screen.c
> +++ b/src/gallium/drivers/nv50/nv50_screen.c
> @@ -161,6 +161,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen,
> enum pipe_cap param)
> case PIPE_CAP_CONDITIONAL_RENDER:
> case PIPE_CAP_TEXTURE_BARRIER:
> case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
> + case PIPE_CAP_BORDER_COLOR_QUIRK:
> case PIPE_CAP_START_INSTANCE:
> return 1;
> case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
> diff --git a/src/gallium/drivers/nvc0/nvc0_screen.c
> b/src/gallium/drivers/nvc0/nvc0_screen.c
> index ccdf2cd..4768e9d 100644
> --- a/src/gallium/drivers/nvc0/nvc0_screen.c
> +++ b/src/gallium/drivers/nvc0/nvc0_screen.c
> @@ -153,6 +153,7 @@ nvc0_screen_get_param(struct pipe_screen *pscreen,
> enum pipe_cap param)
> case PIPE_CAP_CONDITIONAL_RENDER:
> case PIPE_CAP_TEXTURE_BARRIER:
> case PIPE_CAP_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION:
> + case PIPE_CAP_BORDER_COLOR_QUIRK:
> case PIPE_CAP_START_INSTANCE:
> return 1;
> case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
> diff --git a/src/gallium/drivers/r300/r300_screen.c
> b/src/gallium/drivers/r300/r300_screen.c
> index 3175b3b..f8bd5ce 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_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..ec05732 100644
> --- a/src/gallium/drivers/r600/r600_pipe.c
> +++ b/src/gallium/drivers/r600/r600_pipe.c
> @@ -611,6 +611,7 @@ static int r600_get_param(struct pipe_screen* pscreen,
> enum pipe_cap param)
> case PIPE_CAP_VERTEX_COLOR_CLAMPED:
> case PIPE_CAP_USER_VERTEX_BUFFERS:
> case PIPE_CAP_QUERY_PIPELINE_STATISTICS:
> + case PIPE_CAP_BORDER_COLOR_QUIRK:
> return 0;
>
> /* Stream output. */
> diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> b/src/gallium/drivers/radeonsi/radeonsi_pipe.c
> index 5c25b2f..b1f50bf 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_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..fb602ba 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_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..a8235b8 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_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 c790660..35d2707 100644
> --- a/src/gallium/include/pipe/p_defines.h
> +++ b/src/gallium/include/pipe/p_defines.h
> @@ -505,7 +505,8 @@ 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_BORDER_COLOR_QUIRK = 82
> };
>
> /**
> 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..1a78144 100644
> --- a/src/mesa/state_tracker/st_atom_sampler.c
> +++ b/src/mesa/state_tracker/st_atom_sampler.c
> @@ -123,6 +123,54 @@ gl_filter_to_img_filter(GLenum filter)
> }
>
>
> +static INLINE unsigned
> +get_sampler_view_swz(const struct pipe_sampler_view *view, unsigned
> component)
> +{
> + switch (component) {
> + case 1: return view->swizzle_g;
> + case 2: return view->swizzle_b;
> + case 3: return view->swizzle_a;
> + default:
> + assert(component == 0);
> + return view->swizzle_r;
> + }
> +}
> +
> +static void
> +apply_swizzle(union pipe_color_union *dst, const union pipe_color_union
> *src,
> + const struct pipe_sampler_view *view, boolean is_integer)
> +{
> + unsigned c;
> +
> + if (is_integer) {
> + for (c = 0; c < 4; ++c) {
> + unsigned swz = get_sampler_view_swz(view, c);
> + switch (swz) {
> + 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 == PIPE_SWIZZLE_ONE) ? 1 : 0;
> + break;
> + }
> + }
> + } else {
> + for (c = 0; c < 4; ++c) {
> + unsigned swz = get_sampler_view_swz(view, c);
> + switch (swz) {
> + 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 == PIPE_SWIZZLE_ONE) ? 1.0f : 0.0f;
> + break;
> + }
> + }
> + }
> +}
> +
> static void
> convert_sampler(struct st_context *st,
> struct pipe_sampler_state *sampler,
> @@ -172,8 +220,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 +231,18 @@ 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) {
> + st_translate_color(&msamp->BorderColor,
> + &border_color,
> + teximg ? teximg->_BaseFormat : GL_RGBA,
> is_integer);
> +
> + apply_swizzle(&sampler->border_color, &border_color,
> + stobj->sampler_view, 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..a6aee69 100644
> --- a/src/mesa/state_tracker/st_context.c
> +++ b/src/mesa/state_tracker/st_context.c
> @@ -188,6 +188,8 @@ 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_BORDER_COLOR_QUIRK);
>
> /* 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/mesa-dev/attachments/20130413/bdf26e6a/attachment-0001.html>
More information about the mesa-dev
mailing list