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 < e0425...@student.tuwien.ac.at> wrote: > From: Christoph Bumiller <christoph.bumil...@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@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev