diff options
Diffstat (limited to 'src/video_core/shader/decode')
-rw-r--r-- | src/video_core/shader/decode/arithmetic.cpp | 2 | ||||
-rw-r--r-- | src/video_core/shader/decode/arithmetic_half.cpp | 2 | ||||
-rw-r--r-- | src/video_core/shader/decode/arithmetic_integer.cpp | 2 | ||||
-rw-r--r-- | src/video_core/shader/decode/conversion.cpp | 6 | ||||
-rw-r--r-- | src/video_core/shader/decode/ffma.cpp | 4 | ||||
-rw-r--r-- | src/video_core/shader/decode/float_set.cpp | 2 | ||||
-rw-r--r-- | src/video_core/shader/decode/float_set_predicate.cpp | 2 | ||||
-rw-r--r-- | src/video_core/shader/decode/hfma2.cpp | 7 | ||||
-rw-r--r-- | src/video_core/shader/decode/integer_set.cpp | 2 | ||||
-rw-r--r-- | src/video_core/shader/decode/integer_set_predicate.cpp | 2 | ||||
-rw-r--r-- | src/video_core/shader/decode/memory.cpp | 76 | ||||
-rw-r--r-- | src/video_core/shader/decode/shift.cpp | 2 | ||||
-rw-r--r-- | src/video_core/shader/decode/xmad.cpp | 5 |
13 files changed, 75 insertions, 39 deletions
diff --git a/src/video_core/shader/decode/arithmetic.cpp b/src/video_core/shader/decode/arithmetic.cpp index e7847f614..51b8d55d4 100644 --- a/src/video_core/shader/decode/arithmetic.cpp +++ b/src/video_core/shader/decode/arithmetic.cpp @@ -25,7 +25,7 @@ u32 ShaderIR::DecodeArithmetic(BasicBlock& bb, const BasicBlock& code, u32 pc) { } else if (instr.is_b_gpr) { return GetRegister(instr.gpr20); } else { - return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); + return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); } }(); diff --git a/src/video_core/shader/decode/arithmetic_half.cpp b/src/video_core/shader/decode/arithmetic_half.cpp index a237dcb92..37eef2bf2 100644 --- a/src/video_core/shader/decode/arithmetic_half.cpp +++ b/src/video_core/shader/decode/arithmetic_half.cpp @@ -35,7 +35,7 @@ u32 ShaderIR::DecodeArithmeticHalf(BasicBlock& bb, const BasicBlock& code, u32 p switch (opcode->get().GetId()) { case OpCode::Id::HADD2_C: case OpCode::Id::HMUL2_C: - return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); + return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); case OpCode::Id::HADD2_R: case OpCode::Id::HMUL2_R: return GetRegister(instr.gpr20); diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp index 4a8cc1a1c..cc9a76a19 100644 --- a/src/video_core/shader/decode/arithmetic_integer.cpp +++ b/src/video_core/shader/decode/arithmetic_integer.cpp @@ -26,7 +26,7 @@ u32 ShaderIR::DecodeArithmeticInteger(BasicBlock& bb, const BasicBlock& code, u3 } else if (instr.is_b_gpr) { return GetRegister(instr.gpr20); } else { - return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); + return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); } }(); diff --git a/src/video_core/shader/decode/conversion.cpp b/src/video_core/shader/decode/conversion.cpp index ee18d3a99..728a393a1 100644 --- a/src/video_core/shader/decode/conversion.cpp +++ b/src/video_core/shader/decode/conversion.cpp @@ -48,7 +48,7 @@ u32 ShaderIR::DecodeConversion(BasicBlock& bb, const BasicBlock& code, u32 pc) { if (instr.is_b_gpr) { return GetRegister(instr.gpr20); } else { - return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); + return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); } }(); const bool input_signed = instr.conversion.is_input_signed; @@ -72,7 +72,7 @@ u32 ShaderIR::DecodeConversion(BasicBlock& bb, const BasicBlock& code, u32 pc) { if (instr.is_b_gpr) { return GetRegister(instr.gpr20); } else { - return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); + return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); } }(); @@ -110,7 +110,7 @@ u32 ShaderIR::DecodeConversion(BasicBlock& bb, const BasicBlock& code, u32 pc) { if (instr.is_b_gpr) { return GetRegister(instr.gpr20); } else { - return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); + return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); } }(); diff --git a/src/video_core/shader/decode/ffma.cpp b/src/video_core/shader/decode/ffma.cpp index be8dc2230..52f39d3ff 100644 --- a/src/video_core/shader/decode/ffma.cpp +++ b/src/video_core/shader/decode/ffma.cpp @@ -27,14 +27,14 @@ u32 ShaderIR::DecodeFfma(BasicBlock& bb, const BasicBlock& code, u32 pc) { auto [op_b, op_c] = [&]() -> std::tuple<Node, Node> { switch (opcode->get().GetId()) { case OpCode::Id::FFMA_CR: { - return {GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset), + return {GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()), GetRegister(instr.gpr39)}; } case OpCode::Id::FFMA_RR: return {GetRegister(instr.gpr20), GetRegister(instr.gpr39)}; case OpCode::Id::FFMA_RC: { return {GetRegister(instr.gpr39), - GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset)}; + GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset())}; } case OpCode::Id::FFMA_IMM: return {GetImmediate19(instr), GetRegister(instr.gpr39)}; diff --git a/src/video_core/shader/decode/float_set.cpp b/src/video_core/shader/decode/float_set.cpp index ba846f1bd..9f9da2278 100644 --- a/src/video_core/shader/decode/float_set.cpp +++ b/src/video_core/shader/decode/float_set.cpp @@ -25,7 +25,7 @@ u32 ShaderIR::DecodeFloatSet(BasicBlock& bb, const BasicBlock& code, u32 pc) { } else if (instr.is_b_gpr) { return GetRegister(instr.gpr20); } else { - return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); + return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); } }(); diff --git a/src/video_core/shader/decode/float_set_predicate.cpp b/src/video_core/shader/decode/float_set_predicate.cpp index e88b04d18..dd3aef6f2 100644 --- a/src/video_core/shader/decode/float_set_predicate.cpp +++ b/src/video_core/shader/decode/float_set_predicate.cpp @@ -25,7 +25,7 @@ u32 ShaderIR::DecodeFloatSetPredicate(BasicBlock& bb, const BasicBlock& code, u3 } else if (instr.is_b_gpr) { return GetRegister(instr.gpr20); } else { - return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); + return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); } }(); op_b = GetOperandAbsNegFloat(op_b, instr.fsetp.abs_b, false); diff --git a/src/video_core/shader/decode/hfma2.cpp b/src/video_core/shader/decode/hfma2.cpp index 4a6b945f9..43a0a9e10 100644 --- a/src/video_core/shader/decode/hfma2.cpp +++ b/src/video_core/shader/decode/hfma2.cpp @@ -39,13 +39,14 @@ u32 ShaderIR::DecodeHfma2(BasicBlock& bb, const BasicBlock& code, u32 pc) { neg_b = instr.hfma2.negate_b; neg_c = instr.hfma2.negate_c; return {instr.hfma2.saturate, instr.hfma2.type_b, - GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset), instr.hfma2.type_reg39, - GetRegister(instr.gpr39)}; + GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()), + instr.hfma2.type_reg39, GetRegister(instr.gpr39)}; case OpCode::Id::HFMA2_RC: neg_b = instr.hfma2.negate_b; neg_c = instr.hfma2.negate_c; return {instr.hfma2.saturate, instr.hfma2.type_reg39, GetRegister(instr.gpr39), - instr.hfma2.type_b, GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset)}; + instr.hfma2.type_b, + GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset())}; case OpCode::Id::HFMA2_RR: neg_b = instr.hfma2.rr.negate_b; neg_c = instr.hfma2.rr.negate_c; diff --git a/src/video_core/shader/decode/integer_set.cpp b/src/video_core/shader/decode/integer_set.cpp index 85e67b03b..16eb3985f 100644 --- a/src/video_core/shader/decode/integer_set.cpp +++ b/src/video_core/shader/decode/integer_set.cpp @@ -23,7 +23,7 @@ u32 ShaderIR::DecodeIntegerSet(BasicBlock& bb, const BasicBlock& code, u32 pc) { } else if (instr.is_b_gpr) { return GetRegister(instr.gpr20); } else { - return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); + return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); } }(); diff --git a/src/video_core/shader/decode/integer_set_predicate.cpp b/src/video_core/shader/decode/integer_set_predicate.cpp index c8b105a08..daf97174b 100644 --- a/src/video_core/shader/decode/integer_set_predicate.cpp +++ b/src/video_core/shader/decode/integer_set_predicate.cpp @@ -25,7 +25,7 @@ u32 ShaderIR::DecodeIntegerSetPredicate(BasicBlock& bb, const BasicBlock& code, } else if (instr.is_b_gpr) { return GetRegister(instr.gpr20); } else { - return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); + return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); } }(); diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 04cb386b7..3dd26da20 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp @@ -80,7 +80,7 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) { Node index = GetRegister(instr.gpr8); const Node op_a = - GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.offset + 0, index); + GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 0, index); switch (instr.ld_c.type.Value()) { case Tegra::Shader::UniformType::Single: @@ -89,7 +89,7 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) { case Tegra::Shader::UniformType::Double: { const Node op_b = - GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.offset + 4, index); + GetConstBufferIndirect(instr.cbuf36.index, instr.cbuf36.GetOffset() + 4, index); SetTemporal(bb, 0, op_a); SetTemporal(bb, 1, op_b); @@ -104,19 +104,42 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) { } case OpCode::Id::LD_L: { UNIMPLEMENTED_IF_MSG(instr.ld_l.unknown == 1, "LD_L Unhandled mode: {}", - static_cast<unsigned>(instr.ld_l.unknown.Value())); - - const Node index = Operation(OperationCode::IAdd, GetRegister(instr.gpr8), - Immediate(static_cast<s32>(instr.smem_imm))); - const Node lmem = GetLocalMemory(index); + static_cast<u32>(instr.ld_l.unknown.Value())); + + const auto GetLmem = [&](s32 offset) { + ASSERT(offset % 4 == 0); + const Node immediate_offset = Immediate(static_cast<s32>(instr.smem_imm) + offset); + const Node address = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), + immediate_offset); + return GetLocalMemory(address); + }; switch (instr.ldst_sl.type.Value()) { - case Tegra::Shader::StoreType::Bytes32: - SetRegister(bb, instr.gpr0, lmem); + case Tegra::Shader::StoreType::Bits32: + case Tegra::Shader::StoreType::Bits64: + case Tegra::Shader::StoreType::Bits128: { + const u32 count = [&]() { + switch (instr.ldst_sl.type.Value()) { + case Tegra::Shader::StoreType::Bits32: + return 1; + case Tegra::Shader::StoreType::Bits64: + return 2; + case Tegra::Shader::StoreType::Bits128: + return 4; + default: + UNREACHABLE(); + return 0; + } + }(); + for (u32 i = 0; i < count; ++i) + SetTemporal(bb, i, GetLmem(i * 4)); + for (u32 i = 0; i < count; ++i) + SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i)); break; + } default: UNIMPLEMENTED_MSG("LD_L Unhandled type: {}", - static_cast<unsigned>(instr.ldst_sl.type.Value())); + static_cast<u32>(instr.ldst_sl.type.Value())); } break; } @@ -142,7 +165,7 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) { ASSERT(cbuf != nullptr); const auto cbuf_offset_imm = std::get_if<ImmediateNode>(cbuf->GetOffset()); ASSERT(cbuf_offset_imm != nullptr); - const auto cbuf_offset = cbuf_offset_imm->GetValue() * 4; + const auto cbuf_offset = cbuf_offset_imm->GetValue(); bb.push_back(Comment( fmt::format("Base address is c[0x{:x}][0x{:x}]", cbuf->GetIndex(), cbuf_offset))); @@ -202,12 +225,20 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) { UNIMPLEMENTED_IF_MSG(instr.st_l.unknown == 0, "ST_L Unhandled mode: {}", static_cast<u32>(instr.st_l.unknown.Value())); - const Node index = Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), - Immediate(static_cast<s32>(instr.smem_imm))); + const auto GetLmemAddr = [&](s32 offset) { + ASSERT(offset % 4 == 0); + const Node immediate = Immediate(static_cast<s32>(instr.smem_imm) + offset); + return Operation(OperationCode::IAdd, NO_PRECISE, GetRegister(instr.gpr8), immediate); + }; switch (instr.ldst_sl.type.Value()) { - case Tegra::Shader::StoreType::Bytes32: - SetLocalMemory(bb, index, GetRegister(instr.gpr0)); + case Tegra::Shader::StoreType::Bits128: + SetLocalMemory(bb, GetLmemAddr(12), GetRegister(instr.gpr0.Value() + 3)); + SetLocalMemory(bb, GetLmemAddr(8), GetRegister(instr.gpr0.Value() + 2)); + case Tegra::Shader::StoreType::Bits64: + SetLocalMemory(bb, GetLmemAddr(4), GetRegister(instr.gpr0.Value() + 1)); + case Tegra::Shader::StoreType::Bits32: + SetLocalMemory(bb, GetLmemAddr(0), GetRegister(instr.gpr0)); break; default: UNIMPLEMENTED_MSG("ST_L Unhandled type: {}", @@ -324,15 +355,18 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, const BasicBlock& code, u32 pc) { const auto& sampler = GetSampler(instr.sampler, Tegra::Shader::TextureType::Texture2D, false, false); + u32 indexer = 0; switch (instr.txq.query_type) { case Tegra::Shader::TextureQueryType::Dimension: { for (u32 element = 0; element < 4; ++element) { - MetaTexture meta{sampler, element}; - const Node value = Operation(OperationCode::F4TextureQueryDimensions, - std::move(meta), GetRegister(instr.gpr8)); - SetTemporal(bb, element, value); + if (instr.txq.IsComponentEnabled(element)) { + MetaTexture meta{sampler, element}; + const Node value = Operation(OperationCode::F4TextureQueryDimensions, + std::move(meta), GetRegister(instr.gpr8)); + SetTemporal(bb, indexer++, value); + } } - for (u32 i = 0; i < 4; ++i) { + for (u32 i = 0; i < indexer; ++i) { SetRegister(bb, instr.gpr0.Value() + i, GetTemporal(i)); } break; @@ -734,4 +768,4 @@ std::tuple<std::size_t, std::size_t> ShaderIR::ValidateAndGetCoordinateElement( return {coord_count, total_coord_count}; } -} // namespace VideoCommon::Shader
\ No newline at end of file +} // namespace VideoCommon::Shader diff --git a/src/video_core/shader/decode/shift.cpp b/src/video_core/shader/decode/shift.cpp index 85026bb37..6623f8ff9 100644 --- a/src/video_core/shader/decode/shift.cpp +++ b/src/video_core/shader/decode/shift.cpp @@ -23,7 +23,7 @@ u32 ShaderIR::DecodeShift(BasicBlock& bb, const BasicBlock& code, u32 pc) { } else if (instr.is_b_gpr) { return GetRegister(instr.gpr20); } else { - return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset); + return GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()); } }(); diff --git a/src/video_core/shader/decode/xmad.cpp b/src/video_core/shader/decode/xmad.cpp index 0cd9cd1cc..9cb864500 100644 --- a/src/video_core/shader/decode/xmad.cpp +++ b/src/video_core/shader/decode/xmad.cpp @@ -32,13 +32,14 @@ u32 ShaderIR::DecodeXmad(BasicBlock& bb, const BasicBlock& code, u32 pc) { auto [is_merge, op_b, op_c] = [&]() -> std::tuple<bool, Node, Node> { switch (opcode->get().GetId()) { case OpCode::Id::XMAD_CR: - return {instr.xmad.merge_56, GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset), + return {instr.xmad.merge_56, + GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset()), GetRegister(instr.gpr39)}; case OpCode::Id::XMAD_RR: return {instr.xmad.merge_37, GetRegister(instr.gpr20), GetRegister(instr.gpr39)}; case OpCode::Id::XMAD_RC: return {false, GetRegister(instr.gpr39), - GetConstBuffer(instr.cbuf34.index, instr.cbuf34.offset)}; + GetConstBuffer(instr.cbuf34.index, instr.cbuf34.GetOffset())}; case OpCode::Id::XMAD_IMM: return {instr.xmad.merge_37, Immediate(static_cast<u32>(instr.xmad.imm20_16)), GetRegister(instr.gpr39)}; |