summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/ir_opt
diff options
context:
space:
mode:
authorGravatar Fernando S2022-03-18 00:36:31 +0100
committerGravatar GitHub2022-03-18 00:36:31 +0100
commitcb86e7941b87c28491114c80cf2cd3cafd316c72 (patch)
treeecd031fac28e0bfe9c2d10855c74e01379654a4f /src/shader_recompiler/ir_opt
parentMerge pull request #8030 from liamwhite/s8d24-conversion (diff)
parentAddress review comments (diff)
downloadyuzu-cb86e7941b87c28491114c80cf2cd3cafd316c72.tar.gz
yuzu-cb86e7941b87c28491114c80cf2cd3cafd316c72.tar.xz
yuzu-cb86e7941b87c28491114c80cf2cd3cafd316c72.zip
Merge pull request #8024 from liamwhite/const-indexing
Add shader support for const buffer indirect addressing
Diffstat (limited to 'src/shader_recompiler/ir_opt')
-rw-r--r--src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp86
1 files changed, 51 insertions, 35 deletions
diff --git a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
index bfd2ae650..0b2c60842 100644
--- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
+++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp
@@ -29,6 +29,46 @@ void AddConstantBufferDescriptor(Info& info, u32 index, u32 count) {
29 }); 29 });
30} 30}
31 31
32void AddRegisterIndexedLdc(Info& info) {
33 info.uses_cbuf_indirect = true;
34
35 // The shader can use any possible constant buffer
36 info.constant_buffer_mask = (1 << Info::MAX_CBUFS) - 1;
37
38 auto& cbufs{info.constant_buffer_descriptors};
39 cbufs.clear();
40 for (u32 i = 0; i < Info::MAX_CBUFS; i++) {
41 cbufs.push_back(ConstantBufferDescriptor{.index = i, .count = 1});
42
43 // The shader can use any possible access size
44 info.constant_buffer_used_sizes[i] = 0x10'000;
45 }
46}
47
48u32 GetElementSize(IR::Type& used_type, Shader::IR::Opcode opcode) {
49 switch (opcode) {
50 case IR::Opcode::GetCbufU8:
51 case IR::Opcode::GetCbufS8:
52 used_type |= IR::Type::U8;
53 return 1;
54 case IR::Opcode::GetCbufU16:
55 case IR::Opcode::GetCbufS16:
56 used_type |= IR::Type::U16;
57 return 2;
58 case IR::Opcode::GetCbufU32:
59 used_type |= IR::Type::U32;
60 return 4;
61 case IR::Opcode::GetCbufF32:
62 used_type |= IR::Type::F32;
63 return 4;
64 case IR::Opcode::GetCbufU32x2:
65 used_type |= IR::Type::U32x2;
66 return 8;
67 default:
68 throw InvalidArgument("Invalid opcode {}", opcode);
69 }
70}
71
32void GetPatch(Info& info, IR::Patch patch) { 72void GetPatch(Info& info, IR::Patch patch) {
33 if (!IR::IsGeneric(patch)) { 73 if (!IR::IsGeneric(patch)) {
34 throw NotImplementedException("Reading non-generic patch {}", patch); 74 throw NotImplementedException("Reading non-generic patch {}", patch);
@@ -463,42 +503,18 @@ void VisitUsages(Info& info, IR::Inst& inst) {
463 case IR::Opcode::GetCbufU32x2: { 503 case IR::Opcode::GetCbufU32x2: {
464 const IR::Value index{inst.Arg(0)}; 504 const IR::Value index{inst.Arg(0)};
465 const IR::Value offset{inst.Arg(1)}; 505 const IR::Value offset{inst.Arg(1)};
466 if (!index.IsImmediate()) { 506 if (index.IsImmediate()) {
467 throw NotImplementedException("Constant buffer with non-immediate index"); 507 AddConstantBufferDescriptor(info, index.U32(), 1);
468 } 508 u32 element_size = GetElementSize(info.used_constant_buffer_types, inst.GetOpcode());
469 AddConstantBufferDescriptor(info, index.U32(), 1); 509 u32& size{info.constant_buffer_used_sizes[index.U32()]};
470 u32 element_size{}; 510 if (offset.IsImmediate()) {
471 switch (inst.GetOpcode()) { 511 size = Common::AlignUp(std::max(size, offset.U32() + element_size), 16u);
472 case IR::Opcode::GetCbufU8: 512 } else {
473 case IR::Opcode::GetCbufS8: 513 size = 0x10'000;
474 info.used_constant_buffer_types |= IR::Type::U8; 514 }
475 element_size = 1;
476 break;
477 case IR::Opcode::GetCbufU16:
478 case IR::Opcode::GetCbufS16:
479 info.used_constant_buffer_types |= IR::Type::U16;
480 element_size = 2;
481 break;
482 case IR::Opcode::GetCbufU32:
483 info.used_constant_buffer_types |= IR::Type::U32;
484 element_size = 4;
485 break;
486 case IR::Opcode::GetCbufF32:
487 info.used_constant_buffer_types |= IR::Type::F32;
488 element_size = 4;
489 break;
490 case IR::Opcode::GetCbufU32x2:
491 info.used_constant_buffer_types |= IR::Type::U32x2;
492 element_size = 8;
493 break;
494 default:
495 break;
496 }
497 u32& size{info.constant_buffer_used_sizes[index.U32()]};
498 if (offset.IsImmediate()) {
499 size = Common::AlignUp(std::max(size, offset.U32() + element_size), 16u);
500 } else { 515 } else {
501 size = 0x10'000; 516 AddRegisterIndexedLdc(info);
517 GetElementSize(info.used_indirect_cbuf_types, inst.GetOpcode());
502 } 518 }
503 break; 519 break;
504 } 520 }