r600/sfn: Emit some LDS instructions
authorGert Wollny <gert.wollny@collabora.com>
Sun, 12 Apr 2020 15:03:10 +0000 (17:03 +0200)
committerMarge Bot <eric+marge@anholt.net>
Tue, 28 Apr 2020 08:06:33 +0000 (08:06 +0000)
Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4714>

src/gallium/drivers/r600/sfn/sfn_shader_base.cpp
src/gallium/drivers/r600/sfn/sfn_shader_base.h

index a1336fb242ec0abff9dd9b82dd3f768ec54a1fa1..6877780466423491a4dcb7b53ff2c5a86ca77801 100644 (file)
@@ -36,6 +36,7 @@
 #include "sfn_nir.h"
 #include "sfn_instruction_misc.h"
 #include "sfn_instruction_fetch.h"
+#include "sfn_instruction_lds.h"
 
 #include <iostream>
 
@@ -421,6 +422,46 @@ bool ShaderFromNirProcessor::emit_ifelse_end(int if_id)
    return true;
 }
 
+bool ShaderFromNirProcessor::emit_load_tcs_param_base(nir_intrinsic_instr* instr, int offset)
+{
+   PValue src = get_temp_register();
+   emit_instruction(new AluInstruction(op1_mov, src, Value::zero, {alu_write, alu_last_instr}));
+
+   GPRVector dest = vec_from_nir(instr->dest, instr->num_components);
+   emit_instruction(new FetchTCSIOParam(dest, src, offset));
+
+   return true;
+
+}
+
+bool ShaderFromNirProcessor::emit_load_local_shared(nir_intrinsic_instr* instr)
+{
+   auto address = varvec_from_nir(instr->src[0], instr->num_components);
+   auto dest_value = varvec_from_nir(instr->dest, instr->num_components);
+
+   emit_instruction(new LDSReadInstruction(address, dest_value));
+   return true;
+}
+
+bool ShaderFromNirProcessor::emit_store_local_shared(nir_intrinsic_instr* instr)
+{
+   unsigned write_mask = nir_intrinsic_write_mask(instr);
+
+   auto address = from_nir(instr->src[1], 0);
+   int swizzle_base = (write_mask & 0x3) ? 0 : 2;
+   write_mask |= write_mask >> 2;
+
+   auto value =  from_nir(instr->src[0], swizzle_base);
+   if (!(write_mask & 2)) {
+      emit_instruction(new LDSWriteInstruction(address, 0, value));
+   } else {
+      auto value1 = from_nir(instr->src[0], swizzle_base + 1);
+      emit_instruction(new LDSWriteInstruction(address, 0, value, value1));
+   }
+
+   return true;
+}
+
 bool ShaderFromNirProcessor::emit_intrinsic_instruction(nir_intrinsic_instr* instr)
 {
    r600::sfn_log << SfnLog::instr << "emit '"
@@ -486,6 +527,14 @@ bool ShaderFromNirProcessor::emit_intrinsic_instruction(nir_intrinsic_instr* ins
    case nir_intrinsic_load_constant:
    case nir_intrinsic_load_input:
    case nir_intrinsic_store_output:
+   case nir_intrinsic_load_tcs_in_param_base_r600:
+      return emit_load_tcs_param_base(instr, 0);
+   case nir_intrinsic_load_tcs_out_param_base_r600:
+      return emit_load_tcs_param_base(instr, 16);
+   case nir_intrinsic_load_local_shared_r600:
+      return emit_load_local_shared(instr);
+   case nir_intrinsic_store_local_shared_r600:
+      return emit_store_local_shared(instr);
    default:
       fprintf(stderr, "r600-nir: Unsupported intrinsic %d\n", instr->intrinsic);
       return false;
index 1074a3f5edb7149d99547fc9535c7f4781a391ae..a7ea03e0fe0a2d599ce69473cf1b0e159fb71ba2 100644 (file)
@@ -98,6 +98,10 @@ protected:
    bool emit_loop_end(int loop_id);
    bool emit_jump_instruction(nir_jump_instr *instr);
 
+   bool emit_load_tcs_param_base(nir_intrinsic_instr* instr, int offset);
+   bool emit_load_local_shared(nir_intrinsic_instr* instr);
+   bool emit_store_local_shared(nir_intrinsic_instr* instr);
+
    const GPRVector *output_register(unsigned location) const;
 
    bool load_preloaded_value(const nir_dest& dest, int chan, PValue value,