aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrian Ho <[email protected]>2020-04-24 08:05:48 -0700
committerMarge Bot <[email protected]>2020-06-22 14:35:45 +0000
commitb09e690f3b77accfe62398ed314b6ddb0303bf7b (patch)
treead3f240b4d4edb854baa9d4cf58d7fc462d2c2d6 /src
parentd2df0761200ba9680f0d22defaa02c33fb051fcf (diff)
turnip: Lower shaders for tessellation
To enable lowering of tess-related shaders, this commit sets the tessellation primitive field of the ir3_shader_key. In addition, this commit sets various tessellation flags for spirv_to_nir configuration. Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5059>
Diffstat (limited to 'src')
-rw-r--r--src/freedreno/vulkan/tu_pipeline.c29
-rw-r--r--src/freedreno/vulkan/tu_shader.c10
2 files changed, 37 insertions, 2 deletions
diff --git a/src/freedreno/vulkan/tu_pipeline.c b/src/freedreno/vulkan/tu_pipeline.c
index ef1422fa708..6093881217e 100644
--- a/src/freedreno/vulkan/tu_pipeline.c
+++ b/src/freedreno/vulkan/tu_pipeline.c
@@ -1672,7 +1672,26 @@ tu_pipeline_shader_key_init(struct ir3_shader_key *key,
if (msaa_info->sampleShadingEnable)
key->sample_shading = true;
- /* TODO: Populate the remaining fields of ir3_shader_key. */
+ /* We set this after we compile to NIR because we need the prim mode */
+ key->tessellation = IR3_TESS_NONE;
+}
+
+static uint32_t
+tu6_get_tessmode(struct tu_shader* shader)
+{
+ uint32_t primitive_mode = shader->ir3_shader->nir->info.tess.primitive_mode;
+ switch (primitive_mode) {
+ case GL_ISOLINES:
+ return IR3_TESS_ISOLINES;
+ case GL_TRIANGLES:
+ return IR3_TESS_TRIANGLES;
+ case GL_QUADS:
+ return IR3_TESS_QUADS;
+ case GL_NONE:
+ return IR3_TESS_NONE;
+ default:
+ unreachable("bad tessmode");
+ }
}
static VkResult
@@ -1702,6 +1721,14 @@ tu_pipeline_builder_compile_shaders(struct tu_pipeline_builder *builder)
if (!shader)
return VK_ERROR_OUT_OF_HOST_MEMORY;
+ /* In SPIR-V generated from GLSL, the primitive mode is specified in the
+ * tessellation evaluation shader, but in SPIR-V generated from HLSL,
+ * the mode is specified in the tessellation control shader. */
+ if ((stage == MESA_SHADER_TESS_EVAL || stage == MESA_SHADER_TESS_CTRL) &&
+ key.tessellation == IR3_TESS_NONE) {
+ key.tessellation = tu6_get_tessmode(shader);
+ }
+
builder->shaders[stage] = shader;
}
diff --git a/src/freedreno/vulkan/tu_shader.c b/src/freedreno/vulkan/tu_shader.c
index 1a0772726f5..b25a959b89e 100644
--- a/src/freedreno/vulkan/tu_shader.c
+++ b/src/freedreno/vulkan/tu_shader.c
@@ -43,8 +43,11 @@ tu_spirv_to_nir(struct ir3_compiler *compiler,
const struct spirv_to_nir_options spirv_options = {
.frag_coord_is_sysval = true,
.lower_ubo_ssbo_access_to_offsets = true,
+ .tess_levels_are_sysvals = true,
+ .lower_tess_levels_to_vec = true,
.caps = {
- .transform_feedback = compiler->gpu_id >= 600,
+ .transform_feedback = true,
+ .tessellation = true,
},
};
const nir_shader_compiler_options *nir_options =
@@ -608,6 +611,11 @@ tu_shader_create(struct tu_device *dev,
NIR_PASS_V(nir, nir_opt_combine_stores, nir_var_all);
/* ir3 doesn't support indirect input/output */
+ /* TODO: We shouldn't perform this lowering pass on gl_TessLevelInner
+ * and gl_TessLevelOuter. Since the tess levels are actually stored in
+ * a global BO, they can be directly accessed via stg and ldg.
+ * nir_lower_indirect_derefs will instead generate a big if-ladder which
+ * isn't *incorrect* but is much less efficient. */
NIR_PASS_V(nir, nir_lower_indirect_derefs, nir_var_shader_in | nir_var_shader_out);
NIR_PASS_V(nir, nir_lower_io_arrays_to_elements_no_indirects, false);