summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/auxiliary/util/u_format.c34
-rw-r--r--src/gallium/auxiliary/util/u_format.h12
-rw-r--r--src/gallium/docs/source/cso/sampler.rst6
-rw-r--r--src/gallium/docs/source/screen.rst11
-rw-r--r--src/gallium/drivers/freedreno/freedreno_screen.c1
-rw-r--r--src/gallium/drivers/i915/i915_screen.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c2
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.c1
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c2
-rw-r--r--src/gallium/drivers/nvc0/nvc0_screen.c2
-rw-r--r--src/gallium/drivers/r300/r300_screen.c1
-rw-r--r--src/gallium/drivers/r600/r600_pipe.c3
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_pipe.c1
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c2
-rw-r--r--src/gallium/drivers/svga/svga_screen.c2
-rw-r--r--src/gallium/include/pipe/p_defines.h7
-rw-r--r--src/mesa/state_tracker/st_atom.c2
-rw-r--r--src/mesa/state_tracker/st_atom_sampler.c27
-rw-r--r--src/mesa/state_tracker/st_context.c4
-rw-r--r--src/mesa/state_tracker/st_context.h1
20 files changed, 115 insertions, 7 deletions
diff --git a/src/gallium/auxiliary/util/u_format.c b/src/gallium/auxiliary/util/u_format.c
index 18456371c0a..9bdc2eabf11 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 ed942fb1658..e4b9c365c97 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 26ffc181031..9959793a332 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 4b01d77322e..3ab7e9e6906 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 283d07f12e4..4a9a54e3aea 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 54b21549ba5..dfb76b3e98c 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 7152c3e8bca..5535f8523a7 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 e33710e71f7..5b3b470cc4e 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 55081beb300..5aa8ef32e65 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 ccdf2cde84b..8dfd4d12a02 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 3175b3bdd40..a932be9b41d 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 9b43cef2737..4948dddae74 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -654,6 +654,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 5c25b2f98b3..4e97f51dbdc 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 b2b7f2e3208..53ee7d31cab 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 6213535a23e..60e0442944b 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 5b00acc7418..2d38ce1a8c4 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 32bcc266a34..7d383924300 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 3eba5b13cae..db51eead16b 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 2042be36bd3..ed1bf26a260 100644
--- a/src/mesa/state_tracker/st_context.c
+++ b/src/mesa/state_tracker/st_context.c
@@ -188,6 +188,10 @@ 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 |
+ PIPE_QUIRK_TEXTURE_BORDER_COLOR_SWIZZLE_R600));
/* 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 8786a036ff4..807453e9974 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.