From 5aef9ea2a3c8cf76d4bbfbee13ba8821d69cb57f Mon Sep 17 00:00:00 2001 From: Gert Wollny Date: Sat, 9 May 2020 15:09:36 +0200 Subject: [PATCH] r600/sfn: Add support for reading cube image array dim. The cube array size can't be queried directly, the number of array elements must be passed via a constant buffer. Signed-off-by: Gert Wollny Part-of: --- .../r600/sfn/sfn_emitssboinstruction.cpp | 30 +++++++++++++++---- .../drivers/r600/sfn/sfn_shader_base.cpp | 16 ++++++++-- src/gallium/drivers/r600/sfn/sfn_value.cpp | 9 ++---- 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/src/gallium/drivers/r600/sfn/sfn_emitssboinstruction.cpp b/src/gallium/drivers/r600/sfn/sfn_emitssboinstruction.cpp index 972a0651395..e9510eb614b 100644 --- a/src/gallium/drivers/r600/sfn/sfn_emitssboinstruction.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_emitssboinstruction.cpp @@ -9,6 +9,8 @@ namespace r600 { +#define R600_SHADER_BUFFER_INFO_SEL (512 + R600_BUFFER_INFO_OFFSET / 16) + EmitSSBOInstruction::EmitSSBOInstruction(ShaderFromNirProcessor& processor): EmitInstruction(processor), m_require_rat_return_address(false) @@ -507,20 +509,36 @@ bool EmitSSBOInstruction::fetch_return_value(const nir_intrinsic_instr *intrin) bool EmitSSBOInstruction::emit_image_size(const nir_intrinsic_instr *intrin) { GPRVector dest = vec_from_nir(intrin->dest, nir_dest_num_components(intrin->dest)); - GPRVector src{9,{4,4,4,4}}; + GPRVector src{0,{4,4,4,4}}; - int res_id = R600_IMAGE_REAL_RESOURCE_OFFSET; auto const_offset = nir_src_as_const_value(intrin->src[0]); auto dyn_offset = PValue(); + int res_id = R600_IMAGE_REAL_RESOURCE_OFFSET; if (const_offset) res_id += const_offset[0].u32; else dyn_offset = from_nir(intrin->src[0], 0); - auto ir = new TexInstruction(TexInstruction::get_resinfo, dest, src, - 0/* ?? */, - res_id, dyn_offset); - emit_instruction(ir); + if (nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_BUF) { + emit_instruction(new FetchInstruction(dest, PValue(new GPRValue(0, 7)), + res_id, + bim_none)); + return true; + } else { + emit_instruction(new TexInstruction(TexInstruction::get_resinfo, dest, src, + 0/* ?? */, + res_id, dyn_offset)); + if (nir_intrinsic_image_dim(intrin) == GLSL_SAMPLER_DIM_CUBE && + nir_intrinsic_image_array(intrin) && nir_dest_num_components(intrin->dest) > 2) { + /* Need to load the layers from a const buffer */ + + unsigned lookup_resid = const_offset[0].u32; + emit_instruction(new AluInstruction(op1_mov, dest.reg_i(2), + PValue(new UniformValue(lookup_resid/4 + R600_SHADER_BUFFER_INFO_SEL, lookup_resid % 4, + R600_BUFFER_INFO_CONST_BUFFER)), + EmitInstruction::last_write)); + } + } return true; } diff --git a/src/gallium/drivers/r600/sfn/sfn_shader_base.cpp b/src/gallium/drivers/r600/sfn/sfn_shader_base.cpp index 92d65c574bf..a1a258c8cbd 100644 --- a/src/gallium/drivers/r600/sfn/sfn_shader_base.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_shader_base.cpp @@ -93,12 +93,15 @@ bool ShaderFromNirProcessor::scan_instruction(nir_instr *instr) nir_tex_instr *t = nir_instr_as_tex(instr); if (t->sampler_dim == GLSL_SAMPLER_DIM_BUF) sh_info().uses_tex_buffers = true; + if (t->op == nir_texop_txs && + t->sampler_dim == GLSL_SAMPLER_DIM_CUBE && + t->is_array) + sh_info().has_txq_cube_array_z_comp = true; break; } case nir_instr_type_intrinsic: { auto *i = nir_instr_as_intrinsic(instr); switch (i->intrinsic) { - case nir_intrinsic_image_load: case nir_intrinsic_ssbo_atomic_add: case nir_intrinsic_image_atomic_add: case nir_intrinsic_ssbo_atomic_and: @@ -116,13 +119,22 @@ bool ShaderFromNirProcessor::scan_instruction(nir_instr *instr) case nir_intrinsic_image_atomic_xor: case nir_intrinsic_image_atomic_exchange: case nir_intrinsic_image_atomic_comp_swap: - m_ssbo_instr.set_require_rat_return_address(); m_sel.info.writes_memory = 1; + /* fallthrough */ + case nir_intrinsic_image_load: + m_ssbo_instr.set_require_rat_return_address(); break; + case nir_intrinsic_image_size: { + if (nir_intrinsic_image_dim(i) == GLSL_SAMPLER_DIM_CUBE && + nir_intrinsic_image_array(i) && nir_dest_num_components(i->dest) > 2) + sh_info().has_txq_cube_array_z_comp = true; + } + default: ; } + } default: ; diff --git a/src/gallium/drivers/r600/sfn/sfn_value.cpp b/src/gallium/drivers/r600/sfn/sfn_value.cpp index f88760cfc5b..370b7adeae8 100644 --- a/src/gallium/drivers/r600/sfn/sfn_value.cpp +++ b/src/gallium/drivers/r600/sfn/sfn_value.cpp @@ -203,13 +203,8 @@ bool InlineConstValue::is_equal_to(const Value& other) const UniformValue::UniformValue(uint32_t sel, uint32_t chan, uint32_t kcache_bank): Value(Value::kconst, chan) { - if (sel < 512) { - m_index = sel & 0x1f; - m_kcache_bank = ((sel >> 5) & 1) | ((sel >> 7) & 2); - } else { - m_index = sel; - m_kcache_bank = kcache_bank; - } + m_index = sel; + m_kcache_bank = kcache_bank; } UniformValue::UniformValue(uint32_t sel, uint32_t chan, PValue addr): -- 2.30.2