From d2df0761200ba9680f0d22defaa02c33fb051fcf Mon Sep 17 00:00:00 2001 From: Brian Ho Date: Thu, 14 May 2020 12:17:48 -0700 Subject: [PATCH] nir: Add an option for lowering TessLevelInner/Outer to vecs The GLSL to NIR compiler supports the LowerTessLevel flag to convert gl_TessLevelInner/Outer from their GLSL declarations as arrays of floats to vec4/vec2s to better match how they are represented in hardware. This commit adds the similar support to the SPIR-V to NIR compiler so turnip can use the same IR3/NIR tess lowering passes as freedreno. Part-of: --- src/compiler/spirv/nir_spirv.h | 6 ++++++ src/compiler/spirv/vtn_variables.c | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/compiler/spirv/nir_spirv.h b/src/compiler/spirv/nir_spirv.h index acfcc084f41..70f29fd104e 100644 --- a/src/compiler/spirv/nir_spirv.h +++ b/src/compiler/spirv/nir_spirv.h @@ -69,6 +69,12 @@ struct spirv_to_nir_options { */ bool tess_levels_are_sysvals; + /* Whether to lower TessLevelInner/Outer from their SPIR-V declarations + * as arrays of floats to vec4 and vec2 respectively. This is the same as + * LowerTessLevel in GLSL. + */ + bool lower_tess_levels_to_vec; + struct spirv_supported_capabilities caps; /* Address format for various kinds of pointers. */ diff --git a/src/compiler/spirv/vtn_variables.c b/src/compiler/spirv/vtn_variables.c index b36edbafa12..aad07d7556d 100644 --- a/src/compiler/spirv/vtn_variables.c +++ b/src/compiler/spirv/vtn_variables.c @@ -1617,6 +1617,11 @@ apply_var_decoration(struct vtn_builder *b, switch (builtin) { case SpvBuiltInTessLevelOuter: case SpvBuiltInTessLevelInner: + /* Since the compact flag is only valid on arrays, don't set it if + * we are lowering TessLevelInner/Outer to vec4/vec2. */ + if (!b->options || !b->options->lower_tess_levels_to_vec) + var_data->compact = true; + break; case SpvBuiltInClipDistance: case SpvBuiltInCullDistance: var_data->compact = true; @@ -1828,6 +1833,22 @@ var_decoration_cb(struct vtn_builder *b, struct vtn_value *val, int member, } } +static void +var_decoration_tess_level_vec_cb( + struct vtn_builder *b, struct vtn_value *val, int member, + const struct vtn_decoration *dec, void *void_var) +{ + struct vtn_variable *vtn_var = void_var; + if (dec->decoration == SpvDecorationBuiltIn) { + SpvBuiltIn builtin = dec->operands[0]; + if (builtin == SpvBuiltInTessLevelOuter) { + vtn_var->var->type = glsl_vector_type(GLSL_TYPE_FLOAT, 4); + } else if (builtin == SpvBuiltInTessLevelInner) { + vtn_var->var->type = glsl_vector_type(GLSL_TYPE_FLOAT, 2); + } + } +} + enum vtn_variable_mode vtn_storage_class_to_mode(struct vtn_builder *b, SpvStorageClass class, @@ -2407,6 +2428,9 @@ vtn_create_variable(struct vtn_builder *b, struct vtn_value *val, vtn_foreach_decoration(b, val, var_decoration_cb, var); vtn_foreach_decoration(b, val, ptr_decoration_cb, val->pointer); + if (b->options && b->options->lower_tess_levels_to_vec) + vtn_foreach_decoration(b, val, var_decoration_tess_level_vec_cb, var); + /* Propagate access flags from the OpVariable decorations. */ val->pointer->access |= var->access; -- 2.30.2