d600/sfn: write stream outputs to correct mem ring
authorGert Wollny <gert.wollny@collabora.com>
Sat, 18 Jul 2020 20:42:54 +0000 (22:42 +0200)
committerMarge Bot <eric+marge@anholt.net>
Mon, 20 Jul 2020 09:32:51 +0000 (09:32 +0000)
Fixes: arb_gpu_shader5-xfb-streams
Signed-off-by: Gert Wollny <gert.wollny@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5963>

src/gallium/drivers/r600/sfn/sfn_instruction_export.cpp
src/gallium/drivers/r600/sfn/sfn_instruction_export.h
src/gallium/drivers/r600/sfn/sfn_shader_geometry.cpp
src/gallium/drivers/r600/sfn/sfn_shader_geometry.h

index db24b1d7562c984b6ad67eede6cd009b94ea9b46..b19c029c3b689777a76a1e7b4386ceb17392daa8 100644 (file)
@@ -329,4 +329,12 @@ void MemRingOutIntruction::remap_registers_child(std::vector<rename_reg_pair>& m
    map[m_index->sel()].used = true;
 }
 
+void MemRingOutIntruction::patch_ring(int stream)
+{
+   const ECFOpCode ring_op[4] = {cf_mem_ring, cf_mem_ring2, cf_mem_ring3, cf_mem_ring3};
+
+   assert(stream < 4);
+   m_ring_op = ring_op[stream];
+}
+
 }
index 8ab827e71b2cf35955fa5c4037f106d63616aaf3..a2c74e8b67e2b14effc2fa601f8874dde4094fd3 100644 (file)
@@ -152,6 +152,7 @@ public:
    void replace_values_child(const ValueSet& candiates, PValue new_value) override;
    void remap_registers_child(std::vector<rename_reg_pair>& map,
                         ValueMap& values) override;
+   void patch_ring(int stream);
 private:
    bool is_equal_to(const Instruction& lhs) const override;
    void do_print(std::ostream& os) const override;
index 5155488541d1ceb88c9feadc12efe729fcef39ef..5ebeec6d6f1e25a80a7363160a34fdbdd965418b 100644 (file)
@@ -66,7 +66,8 @@ bool GeometryShaderFromNir::do_emit_store_deref(const nir_variable *out_var, nir
    auto ir = new MemRingOutIntruction(cf_mem_ring, mem_write_ind, out_value,
                                       4 * out_var->data.driver_location,
                                       instr->num_components, m_export_base);
-   emit_instruction(ir);
+
+   streamout_data[out_var->data.location] = ir;
 
    return true;
 }
@@ -267,6 +268,14 @@ bool GeometryShaderFromNir::emit_vertex(nir_intrinsic_instr* instr, bool cut)
    int stream = nir_intrinsic_stream_id(instr);
    assert(stream < 4);
 
+   for(auto v: streamout_data) {
+      if (stream == 0 || v.first != VARYING_SLOT_POS) {
+         v.second->patch_ring(stream);
+         emit_instruction(v.second);
+      } else
+         delete v.second;
+   }
+   streamout_data.clear();
    emit_instruction(new EmitVertex(stream, cut));
 
    if (!cut)
index 08df47e559fa69c31006180f2904ef1aea4a5d48..3a66b9d750a73a137c2fb36b9d76b1e062584f78 100644 (file)
@@ -74,6 +74,8 @@ private:
    int m_num_clip_dist;
    unsigned m_cur_ring_output;
    bool m_gs_tri_strip_adj_fix;
+
+   std::map<int, MemRingOutIntruction *> streamout_data;
 };
 
 }