diff options
author | Jason Ekstrand <[email protected]> | 2018-08-30 15:02:25 -0500 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2018-09-06 16:07:50 -0500 |
commit | 25efd787cfd842c0b0b900f35399e44a2e01ea39 (patch) | |
tree | be4df409f2242e2d16f10c3f8e15e6535b713769 /src/compiler/nir | |
parent | 1285f71d3e93f200cec0c321bb6e621d4aece7b3 (diff) |
compiler: Move double_inputs to gl_program::DualSlotInputs
Previously, we had two field in shader_info: double_inputs_read and
double_inputs. Presumably, the one was for all double inputs that are
read and the other is all that exist. However, because nir_gather_info
regenerates these two values, there is a possibility, if a variable gets
deleted, that the value of double_inputs could change over time. This
is a problem because double_inputs is used to remap the input locations
to a two-slot-per-dvec3/4 scheme for i965. If that mapping were to
change between glsl_to_nir and back-end state setup, we would fall over
when trying to map the NIR outputs back onto the GL location space.
This commit changes the way slot re-mapping works. Instead of the
double_inputs field in shader_info, it adds a DualSlotInputs bitfield to
gl_program. By having it in gl_program, we more easily guarantee that
NIR passes won't touch it after it's been set. It also makes more sense
to put it in a GL data structure since it's really a mapping from GL
slots to back-end and/or NIR slots and not really a NIR shader thing.
Tested-by: Alejandro Piñeiro <[email protected]> (ARB_gl_spirv tests)
Reviewed-by: Alejandro Piñeiro <[email protected]>
Reviewed-by: Timothy Arceri <[email protected]>
Diffstat (limited to 'src/compiler/nir')
-rw-r--r-- | src/compiler/nir/nir.c | 49 | ||||
-rw-r--r-- | src/compiler/nir/nir.h | 6 | ||||
-rw-r--r-- | src/compiler/nir/nir_gather_info.c | 6 |
3 files changed, 41 insertions, 20 deletions
diff --git a/src/compiler/nir/nir.c b/src/compiler/nir/nir.c index 7ae46845191..0d8a554bd20 100644 --- a/src/compiler/nir/nir.c +++ b/src/compiler/nir/nir.c @@ -1854,23 +1854,48 @@ nir_system_value_from_intrinsic(nir_intrinsic_op intrin) } } +uint64_t +nir_get_dual_slot_attributes(nir_shader *shader) +{ + assert(shader->info.stage == MESA_SHADER_VERTEX); + + uint64_t dual_slot = 0; + nir_foreach_variable(var, &shader->inputs) { + if (glsl_type_is_dual_slot(glsl_without_array(var->type))) { + unsigned slots = glsl_count_attribute_slots(var->type, true); + dual_slot |= BITFIELD64_MASK(slots) << var->data.location; + } + } + + return dual_slot; +} + /* OpenGL utility method that remaps the location attributes if they are * doubles. Not needed for vulkan due the differences on the input location * count for doubles on vulkan vs OpenGL */ void -nir_remap_attributes(nir_shader *shader, - const nir_shader_compiler_options *options) -{ - if (options->vs_inputs_dual_locations) { - nir_foreach_variable(var, &shader->inputs) { - var->data.location += - _mesa_bitcount_64(shader->info.vs.double_inputs & - BITFIELD64_MASK(var->data.location)); - } +nir_remap_dual_slot_attributes(nir_shader *shader, uint64_t dual_slot) +{ + assert(shader->info.stage == MESA_SHADER_VERTEX); + + nir_foreach_variable(var, &shader->inputs) { + var->data.location += + _mesa_bitcount_64(dual_slot & BITFIELD64_MASK(var->data.location)); } +} - /* Once the remap is done, reset double_inputs_read, so later it will have - * which location/slots are doubles */ - shader->info.vs.double_inputs = 0; +/* Returns an attribute mask that has been re-compacted using the given + * dual_slot mask. + */ +uint64_t +nir_get_single_slot_attribs_mask(uint64_t attribs, uint64_t dual_slot) +{ + while (dual_slot) { + unsigned loc = u_bit_scan64(&dual_slot); + /* mask of all bits up to and including loc */ + uint64_t mask = BITFIELD64_MASK(loc + 1); + attribs = (attribs & mask) | ((attribs & ~mask) >> 1); + } + return attribs; } diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h index 169fa1fa20d..b9393702097 100644 --- a/src/compiler/nir/nir.h +++ b/src/compiler/nir/nir.h @@ -3039,8 +3039,10 @@ bool nir_opt_conditional_discard(nir_shader *shader); void nir_sweep(nir_shader *shader); -void nir_remap_attributes(nir_shader *shader, - const nir_shader_compiler_options *options); +uint64_t nir_get_dual_slot_attributes(nir_shader *shader); +void nir_remap_dual_slot_attributes(nir_shader *shader, + uint64_t dual_slot); +uint64_t nir_get_single_slot_attribs_mask(uint64_t attribs, uint64_t dual_slot); nir_intrinsic_op nir_intrinsic_from_system_value(gl_system_value val); gl_system_value nir_system_value_from_intrinsic(nir_intrinsic_op intrin); diff --git a/src/compiler/nir/nir_gather_info.c b/src/compiler/nir/nir_gather_info.c index 4a030cb6256..de18c9bd78e 100644 --- a/src/compiler/nir/nir_gather_info.c +++ b/src/compiler/nir/nir_gather_info.c @@ -54,11 +54,6 @@ set_io_mask(nir_shader *shader, nir_variable *var, int offset, int len, else shader->info.inputs_read |= bitfield; - /* double inputs read is only for vertex inputs */ - if (shader->info.stage == MESA_SHADER_VERTEX && - glsl_type_is_dual_slot(glsl_without_array(var->type))) - shader->info.vs.double_inputs_read |= bitfield; - if (shader->info.stage == MESA_SHADER_FRAGMENT) { shader->info.fs.uses_sample_qualifier |= var->data.sample; } @@ -417,7 +412,6 @@ nir_shader_gather_info(nir_shader *shader, nir_function_impl *entrypoint) shader->info.system_values_read = 0; if (shader->info.stage == MESA_SHADER_VERTEX) { shader->info.vs.double_inputs = 0; - shader->info.vs.double_inputs_read = 0; } if (shader->info.stage == MESA_SHADER_FRAGMENT) { shader->info.fs.uses_sample_qualifier = false; |