diff options
| author | 2018-12-21 00:06:13 -0300 | |
|---|---|---|
| committer | 2019-01-15 17:54:50 -0300 | |
| commit | 0c049e0a2106ff1624dfe4dcbfe8703584863c7c (patch) | |
| tree | 4d41c455e389eabf5cf2a6c49e56def14bb80ca3 /src | |
| parent | shader_decode: Implement LD_A (diff) | |
| download | yuzu-0c049e0a2106ff1624dfe4dcbfe8703584863c7c.tar.gz yuzu-0c049e0a2106ff1624dfe4dcbfe8703584863c7c.tar.xz yuzu-0c049e0a2106ff1624dfe4dcbfe8703584863c7c.zip | |
shader_decode: Implement ST_A
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/shader/decode/memory.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/video_core/shader/decode/memory.cpp b/src/video_core/shader/decode/memory.cpp index 30e2b33a3..aea1a0675 100644 --- a/src/video_core/shader/decode/memory.cpp +++ b/src/video_core/shader/decode/memory.cpp | |||
| @@ -52,6 +52,36 @@ u32 ShaderIR::DecodeMemory(BasicBlock& bb, u32 pc) { | |||
| 52 | } | 52 | } |
| 53 | break; | 53 | break; |
| 54 | } | 54 | } |
| 55 | case OpCode::Id::ST_A: { | ||
| 56 | UNIMPLEMENTED_IF_MSG(instr.gpr8.Value() != Register::ZeroIndex, | ||
| 57 | "Indirect attribute loads are not supported"); | ||
| 58 | UNIMPLEMENTED_IF_MSG((instr.attribute.fmt20.immediate.Value() % sizeof(u32)) != 0, | ||
| 59 | "Unaligned attribute loads are not supported"); | ||
| 60 | |||
| 61 | u64 next_element = instr.attribute.fmt20.element; | ||
| 62 | auto next_index = static_cast<u64>(instr.attribute.fmt20.index.Value()); | ||
| 63 | |||
| 64 | const auto StoreNextElement = [&](u32 reg_offset) { | ||
| 65 | const auto dest = GetOutputAttribute(static_cast<Attribute::Index>(next_index), | ||
| 66 | next_element, GetRegister(instr.gpr39)); | ||
| 67 | const auto src = GetRegister(instr.gpr0.Value() + reg_offset); | ||
| 68 | |||
| 69 | bb.push_back(Operation(OperationCode::Assign, dest, src)); | ||
| 70 | |||
| 71 | // Load the next attribute element into the following register. If the element | ||
| 72 | // to load goes beyond the vec4 size, load the first element of the next | ||
| 73 | // attribute. | ||
| 74 | next_element = (next_element + 1) % 4; | ||
| 75 | next_index = next_index + (next_element == 0 ? 1 : 0); | ||
| 76 | }; | ||
| 77 | |||
| 78 | const u32 num_words = static_cast<u32>(instr.attribute.fmt20.size.Value()) + 1; | ||
| 79 | for (u32 reg_offset = 0; reg_offset < num_words; ++reg_offset) { | ||
| 80 | StoreNextElement(reg_offset); | ||
| 81 | } | ||
| 82 | |||
| 83 | break; | ||
| 84 | } | ||
| 55 | default: | 85 | default: |
| 56 | UNIMPLEMENTED_MSG("Unhandled memory instruction: {}", opcode->get().GetName()); | 86 | UNIMPLEMENTED_MSG("Unhandled memory instruction: {}", opcode->get().GetName()); |
| 57 | } | 87 | } |