diff --git a/src/gallium/drivers/r600/sfn/sfn_instruction_export.cpp b/src/gallium/drivers/r600/sfn/sfn_instruction_export.cpp index cf40f2aff62..d5796d2e56b 100644 --- a/src/gallium/drivers/r600/sfn/sfn_instruction_export.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_instruction_export.cpp @@ -329,12 +329,13 @@ void MemRingOutIntruction::remap_registers_child(std::vector& m map[m_index->sel()].used = true; } -void MemRingOutIntruction::patch_ring(int stream) +void MemRingOutIntruction::patch_ring(int stream, PValue index) { const ECFOpCode ring_op[4] = {cf_mem_ring, cf_mem_ring1, cf_mem_ring2, cf_mem_ring3}; assert(stream < 4); m_ring_op = ring_op[stream]; + m_index = index; } } diff --git a/src/gallium/drivers/r600/sfn/sfn_instruction_export.h b/src/gallium/drivers/r600/sfn/sfn_instruction_export.h index a2c74e8b67e..1bc83087ce8 100644 --- a/src/gallium/drivers/r600/sfn/sfn_instruction_export.h +++ b/src/gallium/drivers/r600/sfn/sfn_instruction_export.h @@ -152,7 +152,7 @@ public: void replace_values_child(const ValueSet& candiates, PValue new_value) override; void remap_registers_child(std::vector& map, ValueMap& values) override; - void patch_ring(int stream); + void patch_ring(int stream, PValue index); private: bool is_equal_to(const Instruction& lhs) const override; void do_print(std::ostream& os) const override; diff --git a/src/gallium/drivers/r600/sfn/sfn_shader_geometry.cpp b/src/gallium/drivers/r600/sfn/sfn_shader_geometry.cpp index 38629866780..58ac2700bbe 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader_geometry.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_shader_geometry.cpp @@ -65,7 +65,7 @@ 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); + instr->num_components, m_export_base[0]); streamout_data[out_var->data.location] = ir; @@ -180,8 +180,14 @@ bool GeometryShaderFromNir::do_allocate_reserved_registers() m_invocation_id.reset(reg); inject_register(1, 3, m_invocation_id, false); - m_export_base = get_temp_register(); - emit_instruction(new AluInstruction(op1_mov, m_export_base, Value::zero, {alu_write, alu_last_instr})); + m_export_base[0] = get_temp_register(0); + m_export_base[1] = get_temp_register(0); + m_export_base[2] = get_temp_register(0); + m_export_base[3] = get_temp_register(0); + emit_instruction(new AluInstruction(op1_mov, m_export_base[0], Value::zero, {alu_write, alu_last_instr})); + emit_instruction(new AluInstruction(op1_mov, m_export_base[1], Value::zero, {alu_write, alu_last_instr})); + emit_instruction(new AluInstruction(op1_mov, m_export_base[2], Value::zero, {alu_write, alu_last_instr})); + emit_instruction(new AluInstruction(op1_mov, m_export_base[3], Value::zero, {alu_write, alu_last_instr})); sh_info().ring_item_sizes[0] = m_next_input_ring_offset; @@ -193,7 +199,7 @@ bool GeometryShaderFromNir::do_allocate_reserved_registers() void GeometryShaderFromNir::emit_adj_fix() { - PValue adjhelp0(new GPRValue(m_export_base->sel(), 1)); + PValue adjhelp0(new GPRValue(m_export_base[0]->sel(), 1)); emit_instruction(op2_and_int, adjhelp0, {m_primitive_id, Value::one_i}, {alu_write, alu_last_instr}); int help2 = allocate_temp_register(); @@ -203,7 +209,7 @@ void GeometryShaderFromNir::emit_adj_fix() int rotate_indices[6] = {4, 5, 0, 1, 2, 3}; reg_indices[0] = reg_indices[1] = reg_indices[2] = reg_indices[3] = help2; - reg_indices[4] = reg_indices[5] = m_export_base->sel(); + reg_indices[4] = reg_indices[5] = m_export_base[0]->sel(); std::array adjhelp; @@ -270,7 +276,7 @@ bool GeometryShaderFromNir::emit_vertex(nir_intrinsic_instr* instr, bool cut) for(auto v: streamout_data) { if (stream == 0 || v.first != VARYING_SLOT_POS) { - v.second->patch_ring(stream); + v.second->patch_ring(stream, m_export_base[stream]); emit_instruction(v.second); } else delete v.second; @@ -279,7 +285,7 @@ bool GeometryShaderFromNir::emit_vertex(nir_intrinsic_instr* instr, bool cut) emit_instruction(new EmitVertex(stream, cut)); if (!cut) - emit_instruction(new AluInstruction(op2_add_int, m_export_base, m_export_base, + emit_instruction(new AluInstruction(op2_add_int, m_export_base[stream], m_export_base[stream], PValue(new LiteralValue(sh_info().noutput)), {alu_write, alu_last_instr})); diff --git a/src/gallium/drivers/r600/sfn/sfn_shader_geometry.h b/src/gallium/drivers/r600/sfn/sfn_shader_geometry.h index 3a66b9d750a..1e0776912eb 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader_geometry.h +++ b/src/gallium/drivers/r600/sfn/sfn_shader_geometry.h @@ -64,7 +64,7 @@ private: std::array m_per_vertex_offsets; PValue m_primitive_id; PValue m_invocation_id; - PValue m_export_base; + PValue m_export_base[4]; bool m_first_vertex_emitted; std::map m_in_array_deref;