Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color v2
Thanks for the update. Looks good to me FWIW. Jose - Original Message - 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 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 +++
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
- Original Message - On 14.04.2013 15:34, Jose Fonseca wrote: - Original Message - On 14.04.2013 13:44, Jose Fonseca wrote: - Original Message - 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. Yes, please. 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 (!) I wonder if this is modeled after D3D10, where sampler state is independent from resource view state. Though as far as I known, D3D10's interpretation of texture border color does not depend on the swizzle... 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. You wouldn't really need to create all state combinations: if you known that textures and samplers are tightly coupled, then caching the actually used combinations will get you exactly the same behavior, without losing performance or generality. But granted, this would require more effort. The emphasize being on IF I knew (that they're tighly coupled). If I did, I could switch to linked mode where the card automatically uses the view index as sampler index, ignoring the actual sampler index, and validate them together. However, that only applies to 3D, not to COMPUTE (which means that GL compute shaders will still have the problem), and I'd have to support both variants for state trackers that do not allow the coupling, and we need a way for the state tracker to actually tell us what it wants. All that makes it even quirkier. Also please spare a thought for other state trackers -- and I'm not even talking about a potential D3D10 state tracker for which your driver would be unusable --, even inside Mesa: it seems like src/gallium/state_trackers/vega uses both texture border and swizzle, probably vl state tracker too, so your driver will be busted on those state trackers. These need to be It already is busted. It's also busted on r600 where making border color + swizzle work properly isn't even POSSIBLE (according to the radeon guys). Maybe not for vega, it doesn't use a permutational swizzle, it just sets components to PIPE_SWIZZLE_ONE, and incidentally the ZERO/ONE swizzles do affect the border color. As far as I can tell, it looks something like this (if you're interested; the exact behaviour seems not supposed to be made use of): === In the format description (including swizzle), each color component of RGBA (as seen by the shader) gets mapped a memory component {C0,C1,C2,C3} or {ZERO,ONE_INT,ONE_FLOAT}. When a memory (!) component (Cx) is first encountered when going through RGBA, it is assigned the SAMPLER_BORDER_COLOR component value for that component, and if the memory component is encountered again (because of swizzle), that same value will be used. So, assuming memory format RGBA and the swizzle 1RBG: R = ONE G = C0 B = C2 A = C1 the border colour will be SAMPLER_BORDER_COLOR.1GBA. The resulting border colour with swizzle applied to the sampler would be (lowercase being user values): R=1 G=r B=b A=g resulting in 1rbg, which works out. === [...] Btw., note that from my example of how swizzle *does*, but in a quirky, unexpected way, affect border color (if you have read that part), the name AFFECTS_BORDER_COLOR isn't really accurate ... I see.. Maybe leave the QUIRK name with an explanation that things will go wrong if you don't swizzle it according to texture swizzle. Or PIPE_CAP_BORDER_COLOR_MUST_MATCH_TEXTURE_SWIZZLE ? In this we could define the PIPE_CAP so that other drivers can eventually advertise swizzle schemes or slightly different texture border color quirks. That is, make the cap either an enum or bitmask, e.g.:
[Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color v2
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 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
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
- Original Message - 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. Yes, please. 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 (!) I wonder if this is modeled after D3D10, where sampler state is independent from resource view state. Though as far as I known, D3D10's interpretation of texture border color does not depend on the swizzle... 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. You wouldn't really need to create all state combinations: if you known that textures and samplers are tightly coupled, then caching the actually used combinations will get you exactly the same behavior, without losing performance or generality. But granted, this would require more effort. Also please spare a thought for other state trackers -- and I'm not even talking about a potential D3D10 state tracker for which your driver would be unusable --, even inside Mesa: it seems like src/gallium/state_trackers/vega uses both texture border and swizzle, probably vl state tracker too, so your driver will be busted on those state trackers. These need to be updated -- maybe the burden of considering this state can be lifted onto some helper functinons -- if not, these state trackers should at least be updated to abort/warn when the cap is set. But I'm not really objecting -- as texture border seems fundamentally quirky state. But before proceeding with this I'd like us to consider another texture border quirk while we are at it. The other quirk is the integer vs float texture border colors. Roland can probably talk a bit more about it as he was the one who came across it. In a few words, the interpretation of texture border color union depends on the format in the sampler view state (whether it's a pure integer format or not). So, I wonder how integer vs float texture border colors will fit in your driver's elegantly separated texture view and sampler states, or any other driver for that matter. That is, will the world need a PIPE_CAP_SAMPLER_VIEW_FORMAT_VIEW_AFFECTS_TEXTURE_BORDER_COLOR too? If so then maybe we want to lump these two things together. Jose ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
On 14.04.2013 13:44, Jose Fonseca wrote: - Original Message - 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. Yes, please. 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 (!) I wonder if this is modeled after D3D10, where sampler state is independent from resource view state. Though as far as I known, D3D10's interpretation of texture border color does not depend on the swizzle... 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. You wouldn't really need to create all state combinations: if you known that textures and samplers are tightly coupled, then caching the actually used combinations will get you exactly the same behavior, without losing performance or generality. But granted, this would require more effort. The emphasize being on IF I knew (that they're tighly coupled). If I did, I could switch to linked mode where the card automatically uses the view index as sampler index, ignoring the actual sampler index, and validate them together. However, that only applies to 3D, not to COMPUTE (which means that GL compute shaders will still have the problem), and I'd have to support both variants for state trackers that do not allow the coupling, and we need a way for the state tracker to actually tell us what it wants. All that makes it even quirkier. Also please spare a thought for other state trackers -- and I'm not even talking about a potential D3D10 state tracker for which your driver would be unusable --, even inside Mesa: it seems like src/gallium/state_trackers/vega uses both texture border and swizzle, probably vl state tracker too, so your driver will be busted on those state trackers. These need to be It already is busted. It's also busted on r600 where making border color + swizzle work properly isn't even POSSIBLE (according to the radeon guys). Maybe not for vega, it doesn't use a permutational swizzle, it just sets components to PIPE_SWIZZLE_ONE, and incidentally the ZERO/ONE swizzles do affect the border color. As far as I can tell, it looks something like this (if you're interested; the exact behaviour seems not supposed to be made use of): === In the format description (including swizzle), each color component of RGBA (as seen by the shader) gets mapped a memory component {C0,C1,C2,C3} or {ZERO,ONE_INT,ONE_FLOAT}. When a memory (!) component (Cx) is first encountered when going through RGBA, it is assigned the SAMPLER_BORDER_COLOR component value for that component, and if the memory component is encountered again (because of swizzle), that same value will be used. So, assuming memory format RGBA and the swizzle 1RBG: R = ONE G = C0 B = C2 A = C1 the border colour will be SAMPLER_BORDER_COLOR.1GBA. The resulting border colour with swizzle applied to the sampler would be (lowercase being user values): R=1 G=r B=b A=g resulting in 1rbg, which works out. === updated -- maybe the burden of considering this state can be lifted onto some helper functinons -- if not, these state trackers should at least be updated to abort/warn when the cap is set. But I'm not really objecting -- as texture border seems fundamentally quirky state. But before proceeding with this I'd like us to consider another texture border quirk while we are at it. The other quirk is the integer vs float texture border colors. Roland can probably talk a bit more about it as he was the one who came across it. In a few words, the interpretation of texture border color union depends on the format in the sampler view state (whether it's a pure integer format or not). So, I wonder how integer vs float texture border colors will fit in your driver's elegantly separated texture view and sampler states, or any other
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
On 14.04.2013 13:50, Jose Fonseca wrote: - Original Message - 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. Also, will this still be true when Mesa state tracker implements GL_ARB_texture_view ? I dare say yes. GL texture views do NOT decouple textures from samplers, they just decouple gallium sampler views from OpenGL textures. There may be an issue if we wanted (and we don't) to use a single sampler for all the OpenGL texture views of a single texture. However, that ONLY works if the shaders are changed as well, and since the texture/sampler combinations are not predictable, this is a very bad idea as it would mean frequent shader recompilations. As to whether there will ever be an OpenGL extension that adds separation of views and samplers to shaders ... I'm hoping for NV to add some clause to the spec to solve the border colour trouble, like forbidding texture swizzle in such cases (and I'm sure AMD would be inclined to agree). Jose ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
On 14.04.2013 14:33, Christoph Bumiller wrote: === In the format description (including swizzle), each color component of RGBA (as seen by the shader) gets mapped a memory component {C0,C1,C2,C3} or {ZERO,ONE_INT,ONE_FLOAT}. When a memory (!) component (Cx) is first encountered when going through RGBA, it is assigned the SAMPLER_BORDER_COLOR component value for that component, and if the memory component is encountered again (because of swizzle), that same value will be used. So, assuming memory format RGBA and the swizzle 1RBG: R = ONE G = C0 B = C2 A = C1 the border colour will be SAMPLER_BORDER_COLOR.1GBA. The resulting border colour with swizzle applied to the sampler would be (lowercase being user values): R=1 G=r B=b A=g resulting in 1rbg, which works out. === Sorry, that was a bad example, I feel the need to give a better one: When a memory component (Cx) is first encountered when going through RGBA, it is assigned the SAMPLER_BORDER_COLOR.R/G/B/A component value, and if the memory component is encountered again (because of swizzle), that same value will be used. RGBA8 with swizzle G1GB: R=C1 G=ONE B=C1 A=C2 gets BORDER_COLOR.R1RA. Maybe that's the same thing that happens on r600 (I just recall undo the swizzle in a weird way) ? ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
The border color in the sampler state is untyped and that's okay. The type is irrelevant with nearest filtering - just memcpy the border color to the destination register (if there is swizzling, just do what you do for texels). With linear filtering, you can always assume it's float (regardless of the sampler view). Marek On Sun, Apr 14, 2013 at 3:34 PM, Jose Fonseca jfons...@vmware.com wrote: - Original Message - On 14.04.2013 13:44, Jose Fonseca wrote: - Original Message - 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. Yes, please. 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 (!) I wonder if this is modeled after D3D10, where sampler state is independent from resource view state. Though as far as I known, D3D10's interpretation of texture border color does not depend on the swizzle... 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. You wouldn't really need to create all state combinations: if you known that textures and samplers are tightly coupled, then caching the actually used combinations will get you exactly the same behavior, without losing performance or generality. But granted, this would require more effort. The emphasize being on IF I knew (that they're tighly coupled). If I did, I could switch to linked mode where the card automatically uses the view index as sampler index, ignoring the actual sampler index, and validate them together. However, that only applies to 3D, not to COMPUTE (which means that GL compute shaders will still have the problem), and I'd have to support both variants for state trackers that do not allow the coupling, and we need a way for the state tracker to actually tell us what it wants. All that makes it even quirkier. Also please spare a thought for other state trackers -- and I'm not even talking about a potential D3D10 state tracker for which your driver would be unusable --, even inside Mesa: it seems like src/gallium/state_trackers/vega uses both texture border and swizzle, probably vl state tracker too, so your driver will be busted on those state trackers. These need to be It already is busted. It's also busted on r600 where making border color + swizzle work properly isn't even POSSIBLE (according to the radeon guys). Maybe not for vega, it doesn't use a permutational swizzle, it just sets components to PIPE_SWIZZLE_ONE, and incidentally the ZERO/ONE swizzles do affect the border color. As far as I can tell, it looks something like this (if you're interested; the exact behaviour seems not supposed to be made use of): === In the format description (including swizzle), each color component of RGBA (as seen by the shader) gets mapped a memory component {C0,C1,C2,C3} or {ZERO,ONE_INT,ONE_FLOAT}. When a memory (!) component (Cx) is first encountered when going through RGBA, it is assigned the SAMPLER_BORDER_COLOR component value for that component, and if the memory component is encountered again (because of swizzle), that same value will be used. So, assuming memory format RGBA and the swizzle 1RBG: R = ONE G = C0 B = C2 A = C1 the border colour will be SAMPLER_BORDER_COLOR.1GBA. The resulting border colour with swizzle applied to the sampler would be (lowercase being user values): R=1 G=r B=b A=g resulting in 1rbg, which works out. === updated -- maybe the burden of considering this state can be lifted onto some helper functinons -- if not, these state trackers should at least be updated to abort/warn when the cap is set. But I'm not really objecting -- as
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
Yeah it is ok for OpenGL. I guess for d3d10 we'd probably need to create another sampler if the same sampler is used for both int and float textures. Or just supply both int and float border colors to the sample code (but making it work both for opengl and d3d would be ugly). FWIW it looks like some intel hw also seems to require multiple border color values (and 6!!! ones at that), and the hw just picks the right value based on format. Though for some reason the only border color format it does _not_ have is 32bit int, so it looks this does absolutely nothing to make both float and 32bit int colors work with the same sampler simultaneously (and I guess 32bit int is probably the reason opengl specifies those as ints, since you can't get accurate values with floats). The swizzling looks like an orthogonal issue to that, however. Roland Am 14.04.2013 16:18, schrieb Marek Olšák: The border color in the sampler state is untyped and that's okay. The type is irrelevant with nearest filtering - just memcpy the border color to the destination register (if there is swizzling, just do what you do for texels). With linear filtering, you can always assume it's float (regardless of the sampler view). Marek On Sun, Apr 14, 2013 at 3:34 PM, Jose Fonseca jfons...@vmware.com mailto:jfons...@vmware.com wrote: - Original Message - On 14.04.2013 13:44, Jose Fonseca wrote: - Original Message - From: Christoph Bumiller christoph.bumil...@speed.at mailto: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. Yes, please. 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 (!) I wonder if this is modeled after D3D10, where sampler state is independent from resource view state. Though as far as I known, D3D10's interpretation of texture border color does not depend on the swizzle... 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. You wouldn't really need to create all state combinations: if you known that textures and samplers are tightly coupled, then caching the actually used combinations will get you exactly the same behavior, without losing performance or generality. But granted, this would require more effort. The emphasize being on IF I knew (that they're tighly coupled). If I did, I could switch to linked mode where the card automatically uses the view index as sampler index, ignoring the actual sampler index, and validate them together. However, that only applies to 3D, not to COMPUTE (which means that GL compute shaders will still have the problem), and I'd have to support both variants for state trackers that do not allow the coupling, and we need a way for the state tracker to actually tell us what it wants. All that makes it even quirkier. Also please spare a thought for other state trackers -- and I'm not even talking about a potential D3D10 state tracker for which your driver would be unusable --, even inside Mesa: it seems like src/gallium/state_trackers/vega uses both texture border and swizzle, probably vl state tracker too, so your driver will be busted on those state trackers. These need to be It already is busted. It's also busted on r600 where making border color + swizzle work properly isn't even POSSIBLE (according to the radeon guys). Maybe not for vega,
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
Oh and btw how does this work for real hw, if the hardware indeed interpets the border color value according to format? Are there some bits to set that the border color value is either interpreted according to format (useful for opengl) or always as float (useful for d3d10)? Or how else do you use the same sampler for different int/float textures? This discrepancy between OpenGL and d3d10 is quite a mess. Roland Am 14.04.2013 17:45, schrieb Roland Scheidegger: Yeah it is ok for OpenGL. I guess for d3d10 we'd probably need to create another sampler if the same sampler is used for both int and float textures. Or just supply both int and float border colors to the sample code (but making it work both for opengl and d3d would be ugly). FWIW it looks like some intel hw also seems to require multiple border color values (and 6!!! ones at that), and the hw just picks the right value based on format. Though for some reason the only border color format it does _not_ have is 32bit int, so it looks this does absolutely nothing to make both float and 32bit int colors work with the same sampler simultaneously (and I guess 32bit int is probably the reason opengl specifies those as ints, since you can't get accurate values with floats). The swizzling looks like an orthogonal issue to that, however. Roland Am 14.04.2013 16:18, schrieb Marek Olšák: The border color in the sampler state is untyped and that's okay. The type is irrelevant with nearest filtering - just memcpy the border color to the destination register (if there is swizzling, just do what you do for texels). With linear filtering, you can always assume it's float (regardless of the sampler view). Marek On Sun, Apr 14, 2013 at 3:34 PM, Jose Fonseca jfons...@vmware.com mailto:jfons...@vmware.com wrote: - Original Message - On 14.04.2013 13:44, Jose Fonseca wrote: - Original Message - From: Christoph Bumiller christoph.bumil...@speed.at mailto: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. Yes, please. 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 (!) I wonder if this is modeled after D3D10, where sampler state is independent from resource view state. Though as far as I known, D3D10's interpretation of texture border color does not depend on the swizzle... 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. You wouldn't really need to create all state combinations: if you known that textures and samplers are tightly coupled, then caching the actually used combinations will get you exactly the same behavior, without losing performance or generality. But granted, this would require more effort. The emphasize being on IF I knew (that they're tighly coupled). If I did, I could switch to linked mode where the card automatically uses the view index as sampler index, ignoring the actual sampler index, and validate them together. However, that only applies to 3D, not to COMPUTE (which means that GL compute shaders will still have the problem), and I'd have to support both variants for state trackers that do not allow the coupling, and we need a way for the state tracker to actually tell us what it wants. All that makes it even quirkier. Also please spare a thought for other state trackers -- and I'm not even talking about a potential D3D10 state tracker for which your
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
I think the hardware doesn't care what the border color type is. I think the border color is fetched from the sampler state, which should be a memcpy. If no texels are fetched from the texture, the border color is copied to the destination register. If I set the texture hardware format to invalid, the texture fetch instructions always return the border color, which suggests the hardware really does not care about the type. OpenGL also doesn't care what the border color type is after it is set, because the state is a union type. Marek On Sun, Apr 14, 2013 at 6:20 PM, Roland Scheidegger srol...@vmware.comwrote: Oh and btw how does this work for real hw, if the hardware indeed interpets the border color value according to format? Are there some bits to set that the border color value is either interpreted according to format (useful for opengl) or always as float (useful for d3d10)? Or how else do you use the same sampler for different int/float textures? This discrepancy between OpenGL and d3d10 is quite a mess. Roland Am 14.04.2013 17:45, schrieb Roland Scheidegger: Yeah it is ok for OpenGL. I guess for d3d10 we'd probably need to create another sampler if the same sampler is used for both int and float textures. Or just supply both int and float border colors to the sample code (but making it work both for opengl and d3d would be ugly). FWIW it looks like some intel hw also seems to require multiple border color values (and 6!!! ones at that), and the hw just picks the right value based on format. Though for some reason the only border color format it does _not_ have is 32bit int, so it looks this does absolutely nothing to make both float and 32bit int colors work with the same sampler simultaneously (and I guess 32bit int is probably the reason opengl specifies those as ints, since you can't get accurate values with floats). The swizzling looks like an orthogonal issue to that, however. Roland Am 14.04.2013 16:18, schrieb Marek Olšák: The border color in the sampler state is untyped and that's okay. The type is irrelevant with nearest filtering - just memcpy the border color to the destination register (if there is swizzling, just do what you do for texels). With linear filtering, you can always assume it's float (regardless of the sampler view). Marek On Sun, Apr 14, 2013 at 3:34 PM, Jose Fonseca jfons...@vmware.com mailto:jfons...@vmware.com wrote: - Original Message - On 14.04.2013 13:44, Jose Fonseca wrote: - Original Message - From: Christoph Bumiller christoph.bumil...@speed.at mailto: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. Yes, please. 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 (!) I wonder if this is modeled after D3D10, where sampler state is independent from resource view state. Though as far as I known, D3D10's interpretation of texture border color does not depend on the swizzle... 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. You wouldn't really need to create all state combinations: if you known that textures and samplers are tightly coupled, then caching the actually used combinations will get you exactly the same behavior, without losing performance or generality. But granted, this would require more effort. The emphasize being on IF I knew (that they're
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
Am 14.04.2013 18:55, schrieb Marek Olšák: I think the hardware doesn't care what the border color type is. I think the border color is fetched from the sampler state, which should be a memcpy. If no texels are fetched from the texture, the border color is copied to the destination register. If I set the texture hardware format to invalid, the texture fetch instructions always return the border color, which suggests the hardware really does not care about the type. But d3d always sets border color as float. So if your border color is 1.0, I doubt setting the fetched texel value of a int texture to 0x3f80 when you hit the border is the right thing to do (but it would obviously be correct for a float texture). You certainly can convert those float values to int type in your driver, but it will not work if the same sampler is used both for int and float textures. Though actually the spec also says (http://msdn.microsoft.com/de-ch/library/windows/desktop/bb172415%28v=vs.85%29.aspx) border color must be between 0.0 and 1.0. Doesn't make a whole lot of sense for integer textures (as the only possible values when converting to int would be 0 and 1). So something's clearly missing here... OpenGL also doesn't care what the border color type is after it is set, because the state is a union type. Yes of course. Roland Marek On Sun, Apr 14, 2013 at 6:20 PM, Roland Scheidegger srol...@vmware.com mailto:srol...@vmware.com wrote: Oh and btw how does this work for real hw, if the hardware indeed interpets the border color value according to format? Are there some bits to set that the border color value is either interpreted according to format (useful for opengl) or always as float (useful for d3d10)? Or how else do you use the same sampler for different int/float textures? This discrepancy between OpenGL and d3d10 is quite a mess. Roland Am 14.04.2013 17:45, schrieb Roland Scheidegger: Yeah it is ok for OpenGL. I guess for d3d10 we'd probably need to create another sampler if the same sampler is used for both int and float textures. Or just supply both int and float border colors to the sample code (but making it work both for opengl and d3d would be ugly). FWIW it looks like some intel hw also seems to require multiple border color values (and 6!!! ones at that), and the hw just picks the right value based on format. Though for some reason the only border color format it does _not_ have is 32bit int, so it looks this does absolutely nothing to make both float and 32bit int colors work with the same sampler simultaneously (and I guess 32bit int is probably the reason opengl specifies those as ints, since you can't get accurate values with floats). The swizzling looks like an orthogonal issue to that, however. Roland Am 14.04.2013 16:18, schrieb Marek Olšák: The border color in the sampler state is untyped and that's okay. The type is irrelevant with nearest filtering - just memcpy the border color to the destination register (if there is swizzling, just do what you do for texels). With linear filtering, you can always assume it's float (regardless of the sampler view). Marek On Sun, Apr 14, 2013 at 3:34 PM, Jose Fonseca jfons...@vmware.com mailto:jfons...@vmware.com mailto:jfons...@vmware.com mailto:jfons...@vmware.com wrote: - Original Message - On 14.04.2013 13:44, Jose Fonseca wrote: - Original Message - From: Christoph Bumiller christoph.bumil...@speed.at mailto:christoph.bumil...@speed.at mailto:christoph.bumil...@speed.at mailto: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. Yes, please. 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 (!) I wonder if this is modeled after
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
If the border color is 1.0f and the format is integer, I'm not sure if the behavior is defined in GL, but I think r600 will return 0x3f80, which is fine. No, I cannot convert the border color to any other type, because the original type is UNKNOWN after glTexParameter returns. Also, the border color is not clamped in GL. Marek On Sun, Apr 14, 2013 at 7:32 PM, Roland Scheidegger srol...@vmware.comwrote: Am 14.04.2013 18:55, schrieb Marek Olšák: I think the hardware doesn't care what the border color type is. I think the border color is fetched from the sampler state, which should be a memcpy. If no texels are fetched from the texture, the border color is copied to the destination register. If I set the texture hardware format to invalid, the texture fetch instructions always return the border color, which suggests the hardware really does not care about the type. But d3d always sets border color as float. So if your border color is 1.0, I doubt setting the fetched texel value of a int texture to 0x3f80 when you hit the border is the right thing to do (but it would obviously be correct for a float texture). You certainly can convert those float values to int type in your driver, but it will not work if the same sampler is used both for int and float textures. Though actually the spec also says ( http://msdn.microsoft.com/de-ch/library/windows/desktop/bb172415%28v=vs.85%29.aspx ) border color must be between 0.0 and 1.0. Doesn't make a whole lot of sense for integer textures (as the only possible values when converting to int would be 0 and 1). So something's clearly missing here... OpenGL also doesn't care what the border color type is after it is set, because the state is a union type. Yes of course. Roland Marek On Sun, Apr 14, 2013 at 6:20 PM, Roland Scheidegger srol...@vmware.com mailto:srol...@vmware.com wrote: Oh and btw how does this work for real hw, if the hardware indeed interpets the border color value according to format? Are there some bits to set that the border color value is either interpreted according to format (useful for opengl) or always as float (useful for d3d10)? Or how else do you use the same sampler for different int/float textures? This discrepancy between OpenGL and d3d10 is quite a mess. Roland Am 14.04.2013 17:45, schrieb Roland Scheidegger: Yeah it is ok for OpenGL. I guess for d3d10 we'd probably need to create another sampler if the same sampler is used for both int and float textures. Or just supply both int and float border colors to the sample code (but making it work both for opengl and d3d would be ugly). FWIW it looks like some intel hw also seems to require multiple border color values (and 6!!! ones at that), and the hw just picks the right value based on format. Though for some reason the only border color format it does _not_ have is 32bit int, so it looks this does absolutely nothing to make both float and 32bit int colors work with the same sampler simultaneously (and I guess 32bit int is probably the reason opengl specifies those as ints, since you can't get accurate values with floats). The swizzling looks like an orthogonal issue to that, however. Roland Am 14.04.2013 16:18, schrieb Marek Olšák: The border color in the sampler state is untyped and that's okay. The type is irrelevant with nearest filtering - just memcpy the border color to the destination register (if there is swizzling, just do what you do for texels). With linear filtering, you can always assume it's float (regardless of the sampler view). Marek On Sun, Apr 14, 2013 at 3:34 PM, Jose Fonseca jfons...@vmware.com mailto:jfons...@vmware.com mailto:jfons...@vmware.com mailto:jfons...@vmware.com wrote: - Original Message - On 14.04.2013 13:44, Jose Fonseca wrote: - Original Message - From: Christoph Bumiller christoph.bumil...@speed.at mailto:christoph.bumil...@speed.at mailto:christoph.bumil...@speed.at mailto: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. Yes, please. The dependency of update_sampler on the texture updates was introduced to
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
No, it's not defined in GL. But it doesn't matter there anyway cause you can't have the same sampler (and hence border color) used for different textures. Roland Am 14.04.2013 19:53, schrieb Marek Olšák: If the border color is 1.0f and the format is integer, I'm not sure if the behavior is defined in GL, but I think r600 will return 0x3f80, which is fine. No, I cannot convert the border color to any other type, because the original type is UNKNOWN after glTexParameter returns. Also, the border color is not clamped in GL. Marek On Sun, Apr 14, 2013 at 7:32 PM, Roland Scheidegger srol...@vmware.com mailto:srol...@vmware.com wrote: Am 14.04.2013 18:55, schrieb Marek Olšák: I think the hardware doesn't care what the border color type is. I think the border color is fetched from the sampler state, which should be a memcpy. If no texels are fetched from the texture, the border color is copied to the destination register. If I set the texture hardware format to invalid, the texture fetch instructions always return the border color, which suggests the hardware really does not care about the type. But d3d always sets border color as float. So if your border color is 1.0, I doubt setting the fetched texel value of a int texture to 0x3f80 when you hit the border is the right thing to do (but it would obviously be correct for a float texture). You certainly can convert those float values to int type in your driver, but it will not work if the same sampler is used both for int and float textures. Though actually the spec also says (http://msdn.microsoft.com/de-ch/library/windows/desktop/bb172415%28v=vs.85%29.aspx) border color must be between 0.0 and 1.0. Doesn't make a whole lot of sense for integer textures (as the only possible values when converting to int would be 0 and 1). So something's clearly missing here... OpenGL also doesn't care what the border color type is after it is set, because the state is a union type. Yes of course. Roland Marek On Sun, Apr 14, 2013 at 6:20 PM, Roland Scheidegger srol...@vmware.com mailto:srol...@vmware.com mailto:srol...@vmware.com mailto:srol...@vmware.com wrote: Oh and btw how does this work for real hw, if the hardware indeed interpets the border color value according to format? Are there some bits to set that the border color value is either interpreted according to format (useful for opengl) or always as float (useful for d3d10)? Or how else do you use the same sampler for different int/float textures? This discrepancy between OpenGL and d3d10 is quite a mess. Roland Am 14.04.2013 17:45, schrieb Roland Scheidegger: Yeah it is ok for OpenGL. I guess for d3d10 we'd probably need to create another sampler if the same sampler is used for both int and float textures. Or just supply both int and float border colors to the sample code (but making it work both for opengl and d3d would be ugly). FWIW it looks like some intel hw also seems to require multiple border color values (and 6!!! ones at that), and the hw just picks the right value based on format. Though for some reason the only border color format it does _not_ have is 32bit int, so it looks this does absolutely nothing to make both float and 32bit int colors work with the same sampler simultaneously (and I guess 32bit int is probably the reason opengl specifies those as ints, since you can't get accurate values with floats). The swizzling looks like an orthogonal issue to that, however. Roland Am 14.04.2013 16:18, schrieb Marek Olšák: The border color in the sampler state is untyped and that's okay. The type is irrelevant with nearest filtering - just memcpy the border color to the destination register (if there is swizzling, just do what you do for texels). With linear filtering, you can always assume it's float (regardless of the sampler view). Marek On Sun, Apr 14, 2013 at 3:34 PM, Jose Fonseca jfons...@vmware.com mailto:jfons...@vmware.com mailto:jfons...@vmware.com mailto:jfons...@vmware.com mailto:jfons...@vmware.com mailto:jfons...@vmware.com mailto:jfons...@vmware.com mailto:jfons...@vmware.com wrote: - Original Message - On 14.04.2013 13:44,
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
Ahh forget about all this. Thanks to Christoph Bumiller for noticing me that in fact this is a complete non-issue, since you cannot sample from integer textures _at all_ with d3d10. Only ld, hence no sampler and no border color... Looks like OpenGL is a lot more permissive there (which allows you to do pretty much anything with such textures just as ordinary textures, except you can't use non-nearest filter). Am 14.04.2013 20:19, schrieb Roland Scheidegger: No, it's not defined in GL. But it doesn't matter there anyway cause you can't have the same sampler (and hence border color) used for different textures. Roland Am 14.04.2013 19:53, schrieb Marek Olšák: If the border color is 1.0f and the format is integer, I'm not sure if the behavior is defined in GL, but I think r600 will return 0x3f80, which is fine. No, I cannot convert the border color to any other type, because the original type is UNKNOWN after glTexParameter returns. Also, the border color is not clamped in GL. Marek On Sun, Apr 14, 2013 at 7:32 PM, Roland Scheidegger srol...@vmware.com mailto:srol...@vmware.com wrote: Am 14.04.2013 18:55, schrieb Marek Olšák: I think the hardware doesn't care what the border color type is. I think the border color is fetched from the sampler state, which should be a memcpy. If no texels are fetched from the texture, the border color is copied to the destination register. If I set the texture hardware format to invalid, the texture fetch instructions always return the border color, which suggests the hardware really does not care about the type. But d3d always sets border color as float. So if your border color is 1.0, I doubt setting the fetched texel value of a int texture to 0x3f80 when you hit the border is the right thing to do (but it would obviously be correct for a float texture). You certainly can convert those float values to int type in your driver, but it will not work if the same sampler is used both for int and float textures. Though actually the spec also says (http://msdn.microsoft.com/de-ch/library/windows/desktop/bb172415%28v=vs.85%29.aspx) border color must be between 0.0 and 1.0. Doesn't make a whole lot of sense for integer textures (as the only possible values when converting to int would be 0 and 1). So something's clearly missing here... OpenGL also doesn't care what the border color type is after it is set, because the state is a union type. Yes of course. Roland Marek On Sun, Apr 14, 2013 at 6:20 PM, Roland Scheidegger srol...@vmware.com mailto:srol...@vmware.com mailto:srol...@vmware.com mailto:srol...@vmware.com wrote: Oh and btw how does this work for real hw, if the hardware indeed interpets the border color value according to format? Are there some bits to set that the border color value is either interpreted according to format (useful for opengl) or always as float (useful for d3d10)? Or how else do you use the same sampler for different int/float textures? This discrepancy between OpenGL and d3d10 is quite a mess. Roland Am 14.04.2013 17:45, schrieb Roland Scheidegger: Yeah it is ok for OpenGL. I guess for d3d10 we'd probably need to create another sampler if the same sampler is used for both int and float textures. Or just supply both int and float border colors to the sample code (but making it work both for opengl and d3d would be ugly). FWIW it looks like some intel hw also seems to require multiple border color values (and 6!!! ones at that), and the hw just picks the right value based on format. Though for some reason the only border color format it does _not_ have is 32bit int, so it looks this does absolutely nothing to make both float and 32bit int colors work with the same sampler simultaneously (and I guess 32bit int is probably the reason opengl specifies those as ints, since you can't get accurate values with floats). The swizzling looks like an orthogonal issue to that, however. Roland Am 14.04.2013 16:18, schrieb Marek Olšák: The border color in the sampler state is untyped and that's okay. The type is irrelevant with nearest filtering - just memcpy the border color to the destination register (if there is swizzling, just do what you do for texels). With linear filtering, you can always assume it's float (regardless of the sampler view).
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
On Sun, Apr 14, 2013 at 12:55 PM, Marek Olšák mar...@gmail.com wrote: I think the hardware doesn't care what the border color type is. I think the border color is fetched from the sampler state, which should be a memcpy. If no texels are fetched from the texture, the border color is copied to the destination register. If I set the texture hardware format to invalid, the texture fetch instructions always return the border color, which suggests the hardware really does not care about the type. The border color is definitely stored are part of the sampler state. Overrides (BORDER_COLOR_TYPE field) and format conversion are applied after the the state is fetched from the sampler. Alex OpenGL also doesn't care what the border color type is after it is set, because the state is a union type. Marek ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
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 @@
Re: [Mesa-dev] [PATCH] st/mesa: optionally apply texture swizzle to border color
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: +