From e148d5ec991c2a6bedc00222d856e73af75f06f5 Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Tue, 2 Mar 2021 20:23:59 +0100 Subject: [PATCH] r600/sfn: lower intrinsic_load_tess_coord to driver version Fixes KHR-GL45.tessellation_shader.tessellation_shader_tessellation.TCS_TES KHR-GL45.tessellation_shader.tessellation_shader_tessellation.TES Signed-off-by: Gert Wollny Part-of: --- src/gallium/drivers/r600/sfn/sfn_nir.cpp | 4 +++ src/gallium/drivers/r600/sfn/sfn_nir.h | 1 + .../r600/sfn/sfn_nir_lower_tess_io.cpp | 33 +++++++++++++++++++ .../drivers/r600/sfn/sfn_shader_tess_eval.cpp | 18 ++-------- 4 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/gallium/drivers/r600/sfn/sfn_nir.cpp b/src/gallium/drivers/r600/sfn/sfn_nir.cpp index 3765c699e6c..f05c62e5690 100644 --- a/src/gallium/drivers/r600/sfn/sfn_nir.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_nir.cpp @@ -962,6 +962,10 @@ int r600_shader_from_nir(struct r600_context *rctx, NIR_PASS_V(sh, r600_append_tcs_TF_emission, (pipe_prim_type)key->tcs.prim_mode); + if (sh->info.stage == MESA_SHADER_TESS_EVAL) + NIR_PASS_V(sh, r600_lower_tess_coord, + static_cast(sh->info.tess.primitive_mode)); + NIR_PASS_V(sh, nir_lower_ubo_vec4); if (lower_64bit) NIR_PASS_V(sh, r600::r600_nir_64_to_vec2); diff --git a/src/gallium/drivers/r600/sfn/sfn_nir.h b/src/gallium/drivers/r600/sfn/sfn_nir.h index fe77f689b26..22d00a48816 100644 --- a/src/gallium/drivers/r600/sfn/sfn_nir.h +++ b/src/gallium/drivers/r600/sfn/sfn_nir.h @@ -136,6 +136,7 @@ r600_imm_ivec3(nir_builder *build, int x, int y, int z) bool r600_lower_tess_io(nir_shader *shader, enum pipe_prim_type prim_type); bool r600_append_tcs_TF_emission(nir_shader *shader, enum pipe_prim_type prim_type); +bool r600_lower_tess_coord(nir_shader *sh, enum pipe_prim_type prim_type); #ifdef __cplusplus extern "C" { diff --git a/src/gallium/drivers/r600/sfn/sfn_nir_lower_tess_io.cpp b/src/gallium/drivers/r600/sfn/sfn_nir_lower_tess_io.cpp index 2f0e0e48989..14d41f0cb9d 100644 --- a/src/gallium/drivers/r600/sfn/sfn_nir_lower_tess_io.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_nir_lower_tess_io.cpp @@ -462,3 +462,36 @@ bool r600_append_tcs_TF_emission(nir_shader *shader, enum pipe_prim_type prim_ty return true; } + +static bool +r600_lower_tess_coord_filter(const nir_instr *instr, UNUSED const void *_options) +{ + if (instr->type != nir_instr_type_intrinsic) + return false; + auto intr = nir_instr_as_intrinsic(instr); + return intr->intrinsic == nir_intrinsic_load_tess_coord; +} + +static nir_ssa_def * +r600_lower_tess_coord_impl(nir_builder *b, nir_instr *instr, void *_options) +{ + pipe_prim_type prim_type = *(pipe_prim_type *)_options; + + auto tc_xy = nir_load_tess_coord_r600(b); + + auto tc_x = nir_channel(b, tc_xy, 0); + auto tc_y = nir_channel(b, tc_xy, 1); + + if (prim_type == PIPE_PRIM_TRIANGLES) + return nir_vec3(b, tc_x, tc_y, nir_fsub(b, nir_imm_float(b, 1.0), + nir_fadd(b, tc_x, tc_y))); + else + return nir_vec3(b, tc_x, tc_y, nir_imm_float(b, 0.0)); +} + + +bool r600_lower_tess_coord(nir_shader *sh, enum pipe_prim_type prim_type) +{ + return nir_shader_lower_instructions(sh, r600_lower_tess_coord_filter, + r600_lower_tess_coord_impl, &prim_type); +} diff --git a/src/gallium/drivers/r600/sfn/sfn_shader_tess_eval.cpp b/src/gallium/drivers/r600/sfn/sfn_shader_tess_eval.cpp index 294511336d1..0a1760da03d 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader_tess_eval.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_shader_tess_eval.cpp @@ -51,7 +51,7 @@ bool TEvalShaderFromNir::scan_sysvalue_access(nir_instr *instr) auto ir = nir_instr_as_intrinsic(instr); switch (ir->intrinsic) { - case nir_intrinsic_load_tess_coord: + case nir_intrinsic_load_tess_coord_r600: m_sv_values.set(es_tess_coord); break; case nir_intrinsic_load_primitive_id: @@ -106,24 +106,12 @@ bool TEvalShaderFromNir::do_allocate_reserved_registers() return true; } -bool TEvalShaderFromNir::load_tess_z_coord(nir_intrinsic_instr* instr) -{ - if (m_tess_coord[2]) - return load_preloaded_value(instr->dest, 2, m_tess_coord[2]); - - m_tess_coord[2] = from_nir(instr->dest, 2); - emit_instruction(new AluInstruction(op2_add, m_tess_coord[2], Value::one_f, m_tess_coord[0], {alu_last_instr, alu_write, alu_src1_neg})); - emit_instruction(new AluInstruction(op2_add, m_tess_coord[2], m_tess_coord[2], m_tess_coord[1], {alu_last_instr, alu_write, alu_src1_neg})); - return true; -} - bool TEvalShaderFromNir::emit_intrinsic_instruction_override(nir_intrinsic_instr* instr) { switch (instr->intrinsic) { - case nir_intrinsic_load_tess_coord: + case nir_intrinsic_load_tess_coord_r600: return load_preloaded_value(instr->dest, 0, m_tess_coord[0]) && - load_preloaded_value(instr->dest, 1, m_tess_coord[1]) && - load_tess_z_coord(instr); + load_preloaded_value(instr->dest, 1, m_tess_coord[1]); case nir_intrinsic_load_primitive_id: return load_preloaded_value(instr->dest, 0, m_primitive_id); case nir_intrinsic_load_tcs_rel_patch_id_r600: