spirv: Skip creating unused variables in SPIR-V >= 1.4

Newer versions of SPIR-V require that all the global variables used by
the entry point are declared (in contrast to only I/O in previous
versions), so there's no need to remove dead variables or keep track
of the indirectly used variables.

Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/8456>
This commit is contained in:
Caio Marcelo de Oliveira Filho
2021-01-12 11:30:52 -08:00
committed by Marge Bot
parent e3abbe7a24
commit 0c3fe06421
2 changed files with 19 additions and 11 deletions

View File

@@ -4189,7 +4189,7 @@ vtn_handle_entry_point(struct vtn_builder *b, const uint32_t *w,
vtn_assert(b->entry_point == NULL);
b->entry_point = entry_point;
/* Entry points enumerate which I/O variables are used. */
/* Entry points enumerate which global variables are used. */
size_t start = 3 + name_words;
b->interface_ids_count = count - start;
b->interface_ids = ralloc_array(b, uint32_t, b->interface_ids_count);
@@ -5753,7 +5753,7 @@ vtn_create_builder(const uint32_t *words, size_t word_count,
b->value_id_bound = value_id_bound;
b->values = rzalloc_array(b, struct vtn_value, value_id_bound);
if (b->options->environment == NIR_SPIRV_VULKAN)
if (b->options->environment == NIR_SPIRV_VULKAN && b->version < 0x10400)
b->vars_used_indirectly = _mesa_pointer_set_create(b);
return b;
@@ -5975,11 +5975,12 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
/* A SPIR-V module can have multiple shaders stages and also multiple
* shaders of the same stage. Global variables are declared per-module.
*
* For I/O storage classes, OpEntryPoint will list the variables used, so
* only valid ones are created. Remove dead variables to clean up the
* remaining ones.
* Starting in SPIR-V 1.4 the list of global variables is part of
* OpEntryPoint, so only valid ones will be created. Previous versions
* only have Input and Output variables listed, so remove dead variables to
* clean up the remaining ones.
*/
if (!options->create_library) {
if (!options->create_library && b->version < 0x10400) {
const nir_remove_dead_variables_options dead_opts = {
.can_remove_var = can_remove,
.can_remove_var_data = b->vars_used_indirectly,

View File

@@ -2287,12 +2287,19 @@ vtn_handle_variables(struct vtn_builder *b, SpvOp opcode,
SpvStorageClass storage_class = w[3];
/* Skip I/O variables that are not used by the entry point. */
const bool is_global = storage_class != SpvStorageClassFunction;
const bool is_io = storage_class == SpvStorageClassInput ||
storage_class == SpvStorageClassOutput;
/* Skip global variables that are not used by the entrypoint. Before
* SPIR-V 1.4 the interface is only used for I/O variables, so extra
* variables will still need to be removed later.
*/
if (!b->options->create_library &&
(storage_class == SpvStorageClassInput ||
storage_class == SpvStorageClassOutput) &&
!bsearch(&w[2], b->interface_ids, b->interface_ids_count, 4, cmp_uint32_t))
break;
(is_io || (b->version >= 0x10400 && is_global))) {
if (!bsearch(&w[2], b->interface_ids, b->interface_ids_count, 4, cmp_uint32_t))
break;
}
struct vtn_value *val = vtn_push_value(b, w[2], vtn_value_type_pointer);
struct vtn_value *initializer = count > 4 ? vtn_untyped_value(b, w[4]) : NULL;