summaryrefslogtreecommitdiffstats
path: root/src/video_core/shader
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/shader')
-rw-r--r--src/video_core/shader/decode/memory.cpp70
-rw-r--r--src/video_core/shader/shader_ir.h9
2 files changed, 61 insertions, 18 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp
index 9b579bde1..e006f8138 100644
--- a/src/video_core/shader/decode/memory.cpp
+++ b/src/video_core/shader/decode/memory.cpp
@@ -104,19 +104,42 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, 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;
}
@@ -203,12 +226,20 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, 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: {}",
@@ -325,15 +356,18 @@ u32 ShaderIR::DecodeMemory(NodeBlock& bb, 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/shader_ir.h b/src/video_core/shader/shader_ir.h
index 8f97512ee..1d4fbef53 100644
--- a/src/video_core/shader/shader_ir.h
+++ b/src/video_core/shader/shader_ir.h
@@ -236,6 +236,11 @@ private:
class ConstBuffer {
public:
+ explicit ConstBuffer(u32 max_offset, bool is_indirect)
+ : max_offset{max_offset}, is_indirect{is_indirect} {}
+
+ ConstBuffer() = default;
+
void MarkAsUsed(u64 offset) {
max_offset = std::max(max_offset, static_cast<u32>(offset));
}
@@ -252,6 +257,10 @@ public:
return max_offset + sizeof(float);
}
+ u32 GetMaxOffset() const {
+ return max_offset;
+ }
+
private:
u32 max_offset{};
bool is_indirect{};