Re: [Mesa-dev] [PATCH 09/11] nir: add lowering stage for user-clip-planes / clipdist
On Tue, Sep 15, 2015 at 6:49 PM, Rob Clarkwrote: > On Tue, Sep 15, 2015 at 12:39 PM, Erik Faye-Lund wrote: >> On Mon, Sep 14, 2015 at 11:53 AM, Erik Faye-Lund wrote: >>> On Sun, Sep 13, 2015 at 5:51 PM, Rob Clark wrote: From: Rob Clark The vertex shader lowering adds calculation for CLIPDIST, if needed (ie. user-clip-planes), and the frag shader lowering adds conditional kills based on CLIPDIST value (which should be treated as a normal interpolated varying by the driver). >>> >>> >>> + +/* + * FS lowering + */ + +static void +lower_clip_fs(nir_function_impl *impl, unsigned ucp_enables, + nir_variable **in) +{ + nir_ssa_def *clipdist[MAX_CLIP_PLANES]; + nir_builder b; + + nir_builder_init(, impl); + b.cursor = nir_before_cf_list(>body); + + if (ucp_enables & 0x0f) + load_clipdist_input(, in[0], [0]); + if (ucp_enables & 0xf0) + load_clipdist_input(, in[1], [4]); + + for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) { + if (ucp_enables & (1 << plane)) { + nir_intrinsic_instr *discard; + nir_ssa_def *cond; + + cond = nir_flt(, clipdist[plane], nir_imm_float(, 0.0)); + + discard = nir_intrinsic_instr_create(b.shader, + nir_intrinsic_discard_if); + discard->src[0] = nir_src_for_ssa(cond); + nir_builder_instr_insert(, >instr); >>> >>> I think it's worth noting that this isn't *strictly* correct for >>> multi-sampling, unless the shader is s run with per-sample shading >>> (ala GL_ARB_sample_shading). Otherwise, all samples for a pixel will >>> get the same discard-condition, leading to aliasing along the >>> resulting edge. >>> >>> That being said, per-fragment clipping is better than no clipping, so >>> it's clearly an improvement. >> >> So, in order to do this correctly for MSAA, I guess you'd need to use >> SYSTEM_VALUE_SAMPLE_POS and FRAG_RESULT_SAMPLE_MASK, to perform >> alpha-testing for each sample-point. > > I think it still involves being able to run the frag shader once per > sample.. although blob does seem to expose OES_sample_shading so > maybe that is possible? No, that's the whole point of the above, to not have to run the entire shader per sample, only the clipping-bit. > I guess I'd care about it more once I supported MSAA ;-) > > (and tbh, all this effort was mostly just to get neverball to render > correctly :-P) Oh, I just meant that it might be neat to add to the commit message. I wouldn't go ahead and implement this just yet. ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 09/11] nir: add lowering stage for user-clip-planes / clipdist
On Mon, Sep 14, 2015 at 11:53 AM, Erik Faye-Lundwrote: > On Sun, Sep 13, 2015 at 5:51 PM, Rob Clark wrote: >> From: Rob Clark >> >> The vertex shader lowering adds calculation for CLIPDIST, if needed >> (ie. user-clip-planes), and the frag shader lowering adds conditional >> kills based on CLIPDIST value (which should be treated as a normal >> interpolated varying by the driver). > > > >> + >> +/* >> + * FS lowering >> + */ >> + >> +static void >> +lower_clip_fs(nir_function_impl *impl, unsigned ucp_enables, >> + nir_variable **in) >> +{ >> + nir_ssa_def *clipdist[MAX_CLIP_PLANES]; >> + nir_builder b; >> + >> + nir_builder_init(, impl); >> + b.cursor = nir_before_cf_list(>body); >> + >> + if (ucp_enables & 0x0f) >> + load_clipdist_input(, in[0], [0]); >> + if (ucp_enables & 0xf0) >> + load_clipdist_input(, in[1], [4]); >> + >> + for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) { >> + if (ucp_enables & (1 << plane)) { >> + nir_intrinsic_instr *discard; >> + nir_ssa_def *cond; >> + >> + cond = nir_flt(, clipdist[plane], nir_imm_float(, 0.0)); >> + >> + discard = nir_intrinsic_instr_create(b.shader, >> + nir_intrinsic_discard_if); >> + discard->src[0] = nir_src_for_ssa(cond); >> + nir_builder_instr_insert(, >instr); > > I think it's worth noting that this isn't *strictly* correct for > multi-sampling, unless the shader is s run with per-sample shading > (ala GL_ARB_sample_shading). Otherwise, all samples for a pixel will > get the same discard-condition, leading to aliasing along the > resulting edge. > > That being said, per-fragment clipping is better than no clipping, so > it's clearly an improvement. So, in order to do this correctly for MSAA, I guess you'd need to use SYSTEM_VALUE_SAMPLE_POS and FRAG_RESULT_SAMPLE_MASK, to perform alpha-testing for each sample-point. ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 09/11] nir: add lowering stage for user-clip-planes / clipdist
On Tue, Sep 15, 2015 at 12:39 PM, Erik Faye-Lundwrote: > On Mon, Sep 14, 2015 at 11:53 AM, Erik Faye-Lund wrote: >> On Sun, Sep 13, 2015 at 5:51 PM, Rob Clark wrote: >>> From: Rob Clark >>> >>> The vertex shader lowering adds calculation for CLIPDIST, if needed >>> (ie. user-clip-planes), and the frag shader lowering adds conditional >>> kills based on CLIPDIST value (which should be treated as a normal >>> interpolated varying by the driver). >> >> >> >>> + >>> +/* >>> + * FS lowering >>> + */ >>> + >>> +static void >>> +lower_clip_fs(nir_function_impl *impl, unsigned ucp_enables, >>> + nir_variable **in) >>> +{ >>> + nir_ssa_def *clipdist[MAX_CLIP_PLANES]; >>> + nir_builder b; >>> + >>> + nir_builder_init(, impl); >>> + b.cursor = nir_before_cf_list(>body); >>> + >>> + if (ucp_enables & 0x0f) >>> + load_clipdist_input(, in[0], [0]); >>> + if (ucp_enables & 0xf0) >>> + load_clipdist_input(, in[1], [4]); >>> + >>> + for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) { >>> + if (ucp_enables & (1 << plane)) { >>> + nir_intrinsic_instr *discard; >>> + nir_ssa_def *cond; >>> + >>> + cond = nir_flt(, clipdist[plane], nir_imm_float(, 0.0)); >>> + >>> + discard = nir_intrinsic_instr_create(b.shader, >>> + nir_intrinsic_discard_if); >>> + discard->src[0] = nir_src_for_ssa(cond); >>> + nir_builder_instr_insert(, >instr); >> >> I think it's worth noting that this isn't *strictly* correct for >> multi-sampling, unless the shader is s run with per-sample shading >> (ala GL_ARB_sample_shading). Otherwise, all samples for a pixel will >> get the same discard-condition, leading to aliasing along the >> resulting edge. >> >> That being said, per-fragment clipping is better than no clipping, so >> it's clearly an improvement. > > So, in order to do this correctly for MSAA, I guess you'd need to use > SYSTEM_VALUE_SAMPLE_POS and FRAG_RESULT_SAMPLE_MASK, to perform > alpha-testing for each sample-point. Perhaps worth mentioning that a3xx doesn't *actually* support sample shading, although it does appear to have a mode where a single invocation can supply all the samples (but then you can only have a single RT). Ultimately all it needs to do is be able to compute a sample mask though, which *is* supported, but you'd need to do the per-sample interp "by hand" (although afaik the IJ components are provided... somewhere). a4xx brings real per-sample shading from what I can tell though. No idea about vc4's capabilities. This is all a bit moot of course since none of the relevant drivers actually has support for even basic MSAA, nevermind sample shading. However having a piglit test that covers this would be neat... I guess you could clip a pixel in half and make sure that the resolved result is some in-between color? Lots of implementation-dependent stuff going on in there though. -ilia ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 09/11] nir: add lowering stage for user-clip-planes / clipdist
On Tue, Sep 15, 2015 at 12:39 PM, Erik Faye-Lundwrote: > On Mon, Sep 14, 2015 at 11:53 AM, Erik Faye-Lund wrote: >> On Sun, Sep 13, 2015 at 5:51 PM, Rob Clark wrote: >>> From: Rob Clark >>> >>> The vertex shader lowering adds calculation for CLIPDIST, if needed >>> (ie. user-clip-planes), and the frag shader lowering adds conditional >>> kills based on CLIPDIST value (which should be treated as a normal >>> interpolated varying by the driver). >> >> >> >>> + >>> +/* >>> + * FS lowering >>> + */ >>> + >>> +static void >>> +lower_clip_fs(nir_function_impl *impl, unsigned ucp_enables, >>> + nir_variable **in) >>> +{ >>> + nir_ssa_def *clipdist[MAX_CLIP_PLANES]; >>> + nir_builder b; >>> + >>> + nir_builder_init(, impl); >>> + b.cursor = nir_before_cf_list(>body); >>> + >>> + if (ucp_enables & 0x0f) >>> + load_clipdist_input(, in[0], [0]); >>> + if (ucp_enables & 0xf0) >>> + load_clipdist_input(, in[1], [4]); >>> + >>> + for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) { >>> + if (ucp_enables & (1 << plane)) { >>> + nir_intrinsic_instr *discard; >>> + nir_ssa_def *cond; >>> + >>> + cond = nir_flt(, clipdist[plane], nir_imm_float(, 0.0)); >>> + >>> + discard = nir_intrinsic_instr_create(b.shader, >>> + nir_intrinsic_discard_if); >>> + discard->src[0] = nir_src_for_ssa(cond); >>> + nir_builder_instr_insert(, >instr); >> >> I think it's worth noting that this isn't *strictly* correct for >> multi-sampling, unless the shader is s run with per-sample shading >> (ala GL_ARB_sample_shading). Otherwise, all samples for a pixel will >> get the same discard-condition, leading to aliasing along the >> resulting edge. >> >> That being said, per-fragment clipping is better than no clipping, so >> it's clearly an improvement. > > So, in order to do this correctly for MSAA, I guess you'd need to use > SYSTEM_VALUE_SAMPLE_POS and FRAG_RESULT_SAMPLE_MASK, to perform > alpha-testing for each sample-point. I think it still involves being able to run the frag shader once per sample.. although blob does seem to expose OES_sample_shading so maybe that is possible? I guess I'd care about it more once I supported MSAA ;-) (and tbh, all this effort was mostly just to get neverball to render correctly :-P) BR, -R ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 09/11] nir: add lowering stage for user-clip-planes / clipdist
On Tue, Sep 15, 2015 at 6:49 PM, Ilia Mirkinwrote: > However having a piglit test that covers this would be neat... I guess > you could clip a pixel in half and make sure that the resolved result > is some in-between color? Lots of implementation-dependent stuff going > on in there though. I think this would simply be a matter of drawing a white triangle on a black background both with clipping and pre-clipped, and verify that the result is the same. Perhaps even using a few differently sub-pixel jittered triangles. ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 09/11] nir: add lowering stage for user-clip-planes / clipdist
On Tue, Sep 15, 2015 at 1:09 PM, Erik Faye-Lundwrote: > On Tue, Sep 15, 2015 at 6:49 PM, Ilia Mirkin wrote: >> However having a piglit test that covers this would be neat... I guess >> you could clip a pixel in half and make sure that the resolved result >> is some in-between color? Lots of implementation-dependent stuff going >> on in there though. > > I think this would simply be a matter of drawing a white triangle on a > black background both with clipping and pre-clipped, and verify that > the result is the same. Perhaps even using a few differently sub-pixel > jittered triangles. Right, but sample positions are implementation-defined. Although I guess you could retrieve those positions and pre-clip yourself... However the resolve is also implementation-defined I think, so there's no good way to know what the resulting color would be. However you could ensure that it was neither white nor black. ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 09/11] nir: add lowering stage for user-clip-planes / clipdist
On Tue, Sep 15, 2015 at 6:49 PM, Ilia Mirkinwrote: > On Tue, Sep 15, 2015 at 12:39 PM, Erik Faye-Lund wrote: >> On Mon, Sep 14, 2015 at 11:53 AM, Erik Faye-Lund wrote: >>> On Sun, Sep 13, 2015 at 5:51 PM, Rob Clark wrote: From: Rob Clark The vertex shader lowering adds calculation for CLIPDIST, if needed (ie. user-clip-planes), and the frag shader lowering adds conditional kills based on CLIPDIST value (which should be treated as a normal interpolated varying by the driver). >>> >>> >>> + +/* + * FS lowering + */ + +static void +lower_clip_fs(nir_function_impl *impl, unsigned ucp_enables, + nir_variable **in) +{ + nir_ssa_def *clipdist[MAX_CLIP_PLANES]; + nir_builder b; + + nir_builder_init(, impl); + b.cursor = nir_before_cf_list(>body); + + if (ucp_enables & 0x0f) + load_clipdist_input(, in[0], [0]); + if (ucp_enables & 0xf0) + load_clipdist_input(, in[1], [4]); + + for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) { + if (ucp_enables & (1 << plane)) { + nir_intrinsic_instr *discard; + nir_ssa_def *cond; + + cond = nir_flt(, clipdist[plane], nir_imm_float(, 0.0)); + + discard = nir_intrinsic_instr_create(b.shader, + nir_intrinsic_discard_if); + discard->src[0] = nir_src_for_ssa(cond); + nir_builder_instr_insert(, >instr); >>> >>> I think it's worth noting that this isn't *strictly* correct for >>> multi-sampling, unless the shader is s run with per-sample shading >>> (ala GL_ARB_sample_shading). Otherwise, all samples for a pixel will >>> get the same discard-condition, leading to aliasing along the >>> resulting edge. >>> >>> That being said, per-fragment clipping is better than no clipping, so >>> it's clearly an improvement. >> >> So, in order to do this correctly for MSAA, I guess you'd need to use >> SYSTEM_VALUE_SAMPLE_POS and FRAG_RESULT_SAMPLE_MASK, to perform >> alpha-testing for each sample-point. > > Ultimately all it needs to do is be able to compute a > sample mask though, which *is* supported, but you'd need to do the > per-sample interp "by hand" (although afaik the IJ components are > provided... somewhere). SYSTEM_VALUE_SAMPLE_POS could be lowered to a uniform array. You just need to know where the hardware sampling points are. And you could use screen-space derivatives for the per-sample interp. So yeah, the *real* hardware-support needed is just being able to write a sample-mask from the fragment shader. ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 09/11] nir: add lowering stage for user-clip-planes / clipdist
On Tue, Sep 15, 2015 at 12:49 PM, Rob Clarkwrote: > On Tue, Sep 15, 2015 at 12:39 PM, Erik Faye-Lund wrote: >> On Mon, Sep 14, 2015 at 11:53 AM, Erik Faye-Lund wrote: >>> On Sun, Sep 13, 2015 at 5:51 PM, Rob Clark wrote: From: Rob Clark The vertex shader lowering adds calculation for CLIPDIST, if needed (ie. user-clip-planes), and the frag shader lowering adds conditional kills based on CLIPDIST value (which should be treated as a normal interpolated varying by the driver). >>> >>> >>> + +/* + * FS lowering + */ + +static void +lower_clip_fs(nir_function_impl *impl, unsigned ucp_enables, + nir_variable **in) +{ + nir_ssa_def *clipdist[MAX_CLIP_PLANES]; + nir_builder b; + + nir_builder_init(, impl); + b.cursor = nir_before_cf_list(>body); + + if (ucp_enables & 0x0f) + load_clipdist_input(, in[0], [0]); + if (ucp_enables & 0xf0) + load_clipdist_input(, in[1], [4]); + + for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) { + if (ucp_enables & (1 << plane)) { + nir_intrinsic_instr *discard; + nir_ssa_def *cond; + + cond = nir_flt(, clipdist[plane], nir_imm_float(, 0.0)); + + discard = nir_intrinsic_instr_create(b.shader, + nir_intrinsic_discard_if); + discard->src[0] = nir_src_for_ssa(cond); + nir_builder_instr_insert(, >instr); >>> >>> I think it's worth noting that this isn't *strictly* correct for >>> multi-sampling, unless the shader is s run with per-sample shading >>> (ala GL_ARB_sample_shading). Otherwise, all samples for a pixel will >>> get the same discard-condition, leading to aliasing along the >>> resulting edge. >>> >>> That being said, per-fragment clipping is better than no clipping, so >>> it's clearly an improvement. >> >> So, in order to do this correctly for MSAA, I guess you'd need to use >> SYSTEM_VALUE_SAMPLE_POS and FRAG_RESULT_SAMPLE_MASK, to perform >> alpha-testing for each sample-point. > > I think it still involves being able to run the frag shader once per > sample.. although blob does seem to expose OES_sample_shading so > maybe that is possible? (or rather, a4xx blob does, a3xx doesn't) > I guess I'd care about it more once I supported MSAA ;-) > > (and tbh, all this effort was mostly just to get neverball to render > correctly :-P) > > BR, > -R ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 09/11] nir: add lowering stage for user-clip-planes / clipdist
On Tue, Sep 15, 2015 at 7:12 PM, Ilia Mirkinwrote: > On Tue, Sep 15, 2015 at 1:09 PM, Erik Faye-Lund wrote: >> On Tue, Sep 15, 2015 at 6:49 PM, Ilia Mirkin wrote: >>> However having a piglit test that covers this would be neat... I guess >>> you could clip a pixel in half and make sure that the resolved result >>> is some in-between color? Lots of implementation-dependent stuff going >>> on in there though. >> >> I think this would simply be a matter of drawing a white triangle on a >> black background both with clipping and pre-clipped, and verify that >> the result is the same. Perhaps even using a few differently sub-pixel >> jittered triangles. > > Right, but sample positions are implementation-defined. Although I > guess you could retrieve those positions and pre-clip yourself... No need to do that, I think. Clipping happens earlier in the OpenGL pipeline than rasterization, so a user-clipped triangle and a pre-clipped triangle should produce exactly the same result. There is of course a chance of some variance in the calculations, though. So perhaps it'd be better to do a user-clipped triangle vs a near-plane clipped triangle one. Those are defined to be clipped in the same pipeline-stage, and should yield the same result. > However the resolve is also implementation-defined I think, so there's > no good way to know what the resulting color would be. However you > could ensure that it was neither white nor black. Yeah, that's why I'm suggesting comparing two renderings that should give the same result instead. ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 09/11] nir: add lowering stage for user-clip-planes / clipdist
On Tue, Sep 15, 2015 at 1:10 PM, Erik Faye-Lundwrote: >> I guess I'd care about it more once I supported MSAA ;-) >> >> (and tbh, all this effort was mostly just to get neverball to render >> correctly :-P) > > Oh, I just meant that it might be neat to add to the commit message. I > wouldn't go ahead and implement this just yet. yeah, fair enough, I'll add something to the commit msg ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
Re: [Mesa-dev] [PATCH 09/11] nir: add lowering stage for user-clip-planes / clipdist
On Sun, Sep 13, 2015 at 5:51 PM, Rob Clarkwrote: > From: Rob Clark > > The vertex shader lowering adds calculation for CLIPDIST, if needed > (ie. user-clip-planes), and the frag shader lowering adds conditional > kills based on CLIPDIST value (which should be treated as a normal > interpolated varying by the driver). > + > +/* > + * FS lowering > + */ > + > +static void > +lower_clip_fs(nir_function_impl *impl, unsigned ucp_enables, > + nir_variable **in) > +{ > + nir_ssa_def *clipdist[MAX_CLIP_PLANES]; > + nir_builder b; > + > + nir_builder_init(, impl); > + b.cursor = nir_before_cf_list(>body); > + > + if (ucp_enables & 0x0f) > + load_clipdist_input(, in[0], [0]); > + if (ucp_enables & 0xf0) > + load_clipdist_input(, in[1], [4]); > + > + for (int plane = 0; plane < MAX_CLIP_PLANES; plane++) { > + if (ucp_enables & (1 << plane)) { > + nir_intrinsic_instr *discard; > + nir_ssa_def *cond; > + > + cond = nir_flt(, clipdist[plane], nir_imm_float(, 0.0)); > + > + discard = nir_intrinsic_instr_create(b.shader, > + nir_intrinsic_discard_if); > + discard->src[0] = nir_src_for_ssa(cond); > + nir_builder_instr_insert(, >instr); I think it's worth noting that this isn't *strictly* correct for multi-sampling, unless the shader is s run with per-sample shading (ala GL_ARB_sample_shading). Otherwise, all samples for a pixel will get the same discard-condition, leading to aliasing along the resulting edge. That being said, per-fragment clipping is better than no clipping, so it's clearly an improvement. ___ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev
[Mesa-dev] [PATCH 09/11] nir: add lowering stage for user-clip-planes / clipdist
From: Rob ClarkThe vertex shader lowering adds calculation for CLIPDIST, if needed (ie. user-clip-planes), and the frag shader lowering adds conditional kills based on CLIPDIST value (which should be treated as a normal interpolated varying by the driver). Signed-off-by: Rob Clark --- src/glsl/Makefile.sources | 1 + src/glsl/nir/nir.h| 3 + src/glsl/nir/nir_lower_clip.c | 341 ++ 3 files changed, 345 insertions(+) create mode 100644 src/glsl/nir/nir_lower_clip.c diff --git a/src/glsl/Makefile.sources b/src/glsl/Makefile.sources index da7fdf9..5d98b7b 100644 --- a/src/glsl/Makefile.sources +++ b/src/glsl/Makefile.sources @@ -35,6 +35,7 @@ NIR_FILES = \ nir/nir_live_variables.c \ nir/nir_lower_alu_to_scalar.c \ nir/nir_lower_atomics.c \ + nir/nir_lower_clip.c \ nir/nir_lower_global_vars_to_local.c \ nir/nir_lower_load_const_to_scalar.c \ nir/nir_lower_locals_to_regs.c \ diff --git a/src/glsl/nir/nir.h b/src/glsl/nir/nir.h index 3f693b1..1e91ab5 100644 --- a/src/glsl/nir/nir.h +++ b/src/glsl/nir/nir.h @@ -1824,6 +1824,9 @@ void nir_lower_system_values(nir_shader *shader); void nir_lower_tex_projector(nir_shader *shader); void nir_lower_idiv(nir_shader *shader); +void nir_lower_clip_vs(nir_shader *shader, unsigned ucp_enables); +void nir_lower_clip_fs(nir_shader *shader, unsigned ucp_enables); + void nir_lower_atomics(nir_shader *shader); void nir_lower_to_source_mods(nir_shader *shader); diff --git a/src/glsl/nir/nir_lower_clip.c b/src/glsl/nir/nir_lower_clip.c new file mode 100644 index 000..b278aa2 --- /dev/null +++ b/src/glsl/nir/nir_lower_clip.c @@ -0,0 +1,341 @@ +/* + * Copyright © 2015 Red Hat + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + *Rob Clark + */ + +#include "nir.h" +#include "nir_builder.h" + +#define MAX_CLIP_PLANES 8 + +/* Generates the lowering code for user-clip-planes, generating CLIPDIST + * from UCP[n] + CLIPVERTEX or POSITION. Additionally, an optional pass + * for fragment shaders to insert conditional kill's based on the inter- + * polated CLIPDIST + * + * NOTE: should be run after nir_lower_outputs_to_temporaries() (or at + * least in scenarios where you can count on each output written once + * and only once). + */ + + +static nir_variable * +create_clipdist_var(nir_shader *shader, unsigned drvloc, +bool output, gl_varying_slot slot) +{ + nir_variable *var = rzalloc(shader, nir_variable); + + var->data.driver_location = drvloc; + var->type = glsl_vec4_type(); + var->data.mode = output ? nir_var_shader_out : nir_var_shader_in; + var->name = ralloc_asprintf(var, "clipdist_%d", drvloc); + var->data.index = 0; + var->data.location = slot; + + if (output) { + exec_list_push_tail(>outputs, >node); + } + else { + exec_list_push_tail(>inputs, >node); + } + return var; +} + +static void +store_clipdist_output(nir_builder *b, nir_variable *out, nir_ssa_def **val) +{ + nir_intrinsic_instr *store; + + store = nir_intrinsic_instr_create(b->shader, nir_intrinsic_store_output); + store->num_components = 4; + store->const_index[0] = out->data.driver_location; + store->src[0].ssa = nir_vec4(b, val[0], val[1], val[2], val[3]); + store->src[0].is_ssa = true; + nir_builder_instr_insert(b, >instr); +} + +static void +load_clipdist_input(nir_builder *b, nir_variable *in, nir_ssa_def **val) +{ + nir_intrinsic_instr *load; + + load = nir_intrinsic_instr_create(b->shader, nir_intrinsic_load_input); + load->num_components = 4; + load->const_index[0] = in->data.driver_location; + nir_ssa_dest_init(>instr, >dest, 4, NULL); + nir_builder_instr_insert(b, >instr); + + val[0] = nir_channel(b, >dest.ssa, 0); + val[1] = nir_channel(b,