Re: [Mesa-dev] [PATCH 2/3] nir: Add a discard optimization pass
On Wed, Jul 4, 2018 at 2:22 AM, Grazvydas Ignotas wrote: > On Wed, Jul 4, 2018 at 9:13 AM, Jason Ekstrand > wrote: > > Many fragment shaders do a discard using relatively little information > > but still put the discard fairly far down in the shader for no good > > reason. If the discard is moved higher up, we can possibly avoid doing > > some or almost all of the work in the shader. When this lets us skip > > texturing operations, it's an especially high win. > > > > One of the biggest offenders here is DXVK. The D3D APIs have different > > rules for discards than OpenGL and Vulkan. One effective way (which is > > what DXVK uses) to implement DX behavior on top of GL or Vulkan is to > > wait until the very end of the shader to discard. This ends up in the > > pessimal case where we always do all of the work before discarding. > > This pass helps some DXVK shaders significantly. > > --- > > src/compiler/Makefile.sources | 1 + > > src/compiler/nir/meson.build | 1 + > > src/compiler/nir/nir.h | 10 + > > src/compiler/nir/nir_opt_discard.c | 404 + > > 4 files changed, 416 insertions(+) > > create mode 100644 src/compiler/nir/nir_opt_discard.c > > > > diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile. > sources > > index 9e3fbdc2612..8600ce81281 100644 > > --- a/src/compiler/Makefile.sources > > +++ b/src/compiler/Makefile.sources > > @@ -271,6 +271,7 @@ NIR_FILES = \ > > nir/nir_opt_cse.c \ > > nir/nir_opt_dce.c \ > > nir/nir_opt_dead_cf.c \ > > + nir/nir_opt_discard.c \ > > nir/nir_opt_gcm.c \ > > nir/nir_opt_global_to_local.c \ > > nir/nir_opt_if.c \ > > diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build > > index 28aa8de7014..e339258bb94 100644 > > --- a/src/compiler/nir/meson.build > > +++ b/src/compiler/nir/meson.build > > @@ -156,6 +156,7 @@ files_libnir = files( > >'nir_opt_cse.c', > >'nir_opt_dce.c', > >'nir_opt_dead_cf.c', > > + 'nir_opt_discard.c', > >'nir_opt_gcm.c', > >'nir_opt_global_to_local.c', > >'nir_opt_if.c', > > diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h > > index 92ab3a699cc..44006dac160 100644 > > --- a/src/compiler/nir/nir.h > > +++ b/src/compiler/nir/nir.h > > @@ -2022,6 +2022,13 @@ typedef struct nir_shader_compiler_options { > > */ > > bool vs_inputs_dual_locations; > > > > + /** > > +* Whether or not derivatives are still a safe operation after a > discard > > +* has occurred. Optimization passes may be able to be a bit more > > +* agressive if this is true. > > +*/ > > + bool derivatives_safe_after_discard; > > + > > unsigned max_unroll_iterations; > > } nir_shader_compiler_options; > > > > @@ -2899,6 +2906,9 @@ bool nir_opt_dce(nir_shader *shader); > > > > bool nir_opt_dead_cf(nir_shader *shader); > > > > +bool nir_opt_discard_if(nir_shader *shader); > > +bool nir_opt_move_discards_to_top(nir_shader *shader); > > + > > bool nir_opt_gcm(nir_shader *shader, bool value_number); > > > > bool nir_opt_if(nir_shader *shader); > > diff --git a/src/compiler/nir/nir_opt_discard.c > b/src/compiler/nir/nir_opt_discard.c > > new file mode 100644 > > index 000..eb1a8296282 > > --- /dev/null > > +++ b/src/compiler/nir/nir_opt_discard.c > > @@ -0,0 +1,404 @@ > > +/* > > + * Copyright © 2014 Intel Corporation > > 2018? > Yeah... > > + * > > + * 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: > > + *Jason Ekstrand (ja...@jlekstrand.net) > > + * > > + */ > > + > > +#include "nir.h" > > +#include "nir_builder.h" > > +#include "nir_control_flow.h" > > +#include "nir_worklist.h" > > + > > +static bool > > +block_has_only_discard(nir_block *block) > > +{ > > + nir_instr *instr =
Re: [Mesa-dev] [PATCH 2/3] nir: Add a discard optimization pass
On Wed, Jul 4, 2018 at 9:13 AM, Jason Ekstrand wrote: > Many fragment shaders do a discard using relatively little information > but still put the discard fairly far down in the shader for no good > reason. If the discard is moved higher up, we can possibly avoid doing > some or almost all of the work in the shader. When this lets us skip > texturing operations, it's an especially high win. > > One of the biggest offenders here is DXVK. The D3D APIs have different > rules for discards than OpenGL and Vulkan. One effective way (which is > what DXVK uses) to implement DX behavior on top of GL or Vulkan is to > wait until the very end of the shader to discard. This ends up in the > pessimal case where we always do all of the work before discarding. > This pass helps some DXVK shaders significantly. > --- > src/compiler/Makefile.sources | 1 + > src/compiler/nir/meson.build | 1 + > src/compiler/nir/nir.h | 10 + > src/compiler/nir/nir_opt_discard.c | 404 + > 4 files changed, 416 insertions(+) > create mode 100644 src/compiler/nir/nir_opt_discard.c > > diff --git a/src/compiler/Makefile.sources b/src/compiler/Makefile.sources > index 9e3fbdc2612..8600ce81281 100644 > --- a/src/compiler/Makefile.sources > +++ b/src/compiler/Makefile.sources > @@ -271,6 +271,7 @@ NIR_FILES = \ > nir/nir_opt_cse.c \ > nir/nir_opt_dce.c \ > nir/nir_opt_dead_cf.c \ > + nir/nir_opt_discard.c \ > nir/nir_opt_gcm.c \ > nir/nir_opt_global_to_local.c \ > nir/nir_opt_if.c \ > diff --git a/src/compiler/nir/meson.build b/src/compiler/nir/meson.build > index 28aa8de7014..e339258bb94 100644 > --- a/src/compiler/nir/meson.build > +++ b/src/compiler/nir/meson.build > @@ -156,6 +156,7 @@ files_libnir = files( >'nir_opt_cse.c', >'nir_opt_dce.c', >'nir_opt_dead_cf.c', > + 'nir_opt_discard.c', >'nir_opt_gcm.c', >'nir_opt_global_to_local.c', >'nir_opt_if.c', > diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h > index 92ab3a699cc..44006dac160 100644 > --- a/src/compiler/nir/nir.h > +++ b/src/compiler/nir/nir.h > @@ -2022,6 +2022,13 @@ typedef struct nir_shader_compiler_options { > */ > bool vs_inputs_dual_locations; > > + /** > +* Whether or not derivatives are still a safe operation after a discard > +* has occurred. Optimization passes may be able to be a bit more > +* agressive if this is true. > +*/ > + bool derivatives_safe_after_discard; > + > unsigned max_unroll_iterations; > } nir_shader_compiler_options; > > @@ -2899,6 +2906,9 @@ bool nir_opt_dce(nir_shader *shader); > > bool nir_opt_dead_cf(nir_shader *shader); > > +bool nir_opt_discard_if(nir_shader *shader); > +bool nir_opt_move_discards_to_top(nir_shader *shader); > + > bool nir_opt_gcm(nir_shader *shader, bool value_number); > > bool nir_opt_if(nir_shader *shader); > diff --git a/src/compiler/nir/nir_opt_discard.c > b/src/compiler/nir/nir_opt_discard.c > new file mode 100644 > index 000..eb1a8296282 > --- /dev/null > +++ b/src/compiler/nir/nir_opt_discard.c > @@ -0,0 +1,404 @@ > +/* > + * Copyright © 2014 Intel Corporation 2018? > + * > + * 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: > + *Jason Ekstrand (ja...@jlekstrand.net) > + * > + */ > + > +#include "nir.h" > +#include "nir_builder.h" > +#include "nir_control_flow.h" > +#include "nir_worklist.h" > + > +static bool > +block_has_only_discard(nir_block *block) > +{ > + nir_instr *instr = nir_block_first_instr(block); > + if (instr == NULL || instr != nir_block_last_instr(block)) > + return false; > + > + if (instr->type != nir_instr_type_intrinsic) > + return false; > + > + nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr); > + return intrin->intrinsic == nir_intrinsic_discard; > +} > +