Thanks for the update. Looks good to me FWIW.
Jose ----- Original Message ----- > From: Christoph Bumiller <[email protected]> > > 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 > [email protected] > http://lists.freedesktop.org/mailman/listinfo/mesa-dev > _______________________________________________ mesa-dev mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/mesa-dev
