diff options
| author | 2021-02-20 03:30:13 -0300 | |
|---|---|---|
| committer | 2021-07-22 21:51:22 -0400 | |
| commit | e2bc05b17d91854cbb9c0ce3647141bf7d33143e (patch) | |
| tree | 96769db006b6015cd536483db98ee0697aee4992 /src/shader_recompiler/ir_opt | |
| parent | spirv: Add lower fp16 to fp32 pass (diff) | |
| download | yuzu-e2bc05b17d91854cbb9c0ce3647141bf7d33143e.tar.gz yuzu-e2bc05b17d91854cbb9c0ce3647141bf7d33143e.tar.xz yuzu-e2bc05b17d91854cbb9c0ce3647141bf7d33143e.zip | |
shader: Add denorm flush support
Diffstat (limited to 'src/shader_recompiler/ir_opt')
| -rw-r--r-- | src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | 71 | ||||
| -rw-r--r-- | src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp | 1 |
2 files changed, 65 insertions, 7 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 f7f102f53..6662ef4cd 100644 --- a/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp +++ b/src/shader_recompiler/ir_opt/collect_shader_info_pass.cpp | |||
| @@ -2,23 +2,28 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "shader_recompiler/frontend/ir/microinstruction.h" | ||
| 6 | #include "shader_recompiler/frontend/ir/modifiers.h" | ||
| 5 | #include "shader_recompiler/frontend/ir/program.h" | 7 | #include "shader_recompiler/frontend/ir/program.h" |
| 6 | #include "shader_recompiler/shader_info.h" | 8 | #include "shader_recompiler/shader_info.h" |
| 7 | 9 | ||
| 8 | namespace Shader::Optimization { | 10 | namespace Shader::Optimization { |
| 9 | namespace { | 11 | namespace { |
| 10 | void AddConstantBufferDescriptor(Info& info, u32 index) { | 12 | void AddConstantBufferDescriptor(Info& info, u32 index, u32 count) { |
| 11 | auto& descriptor{info.constant_buffers.at(index)}; | 13 | if (count != 1) { |
| 12 | if (descriptor) { | 14 | throw NotImplementedException("Constant buffer descriptor indexing"); |
| 15 | } | ||
| 16 | if ((info.constant_buffer_mask & (1U << index)) != 0) { | ||
| 13 | return; | 17 | return; |
| 14 | } | 18 | } |
| 15 | descriptor = &info.constant_buffer_descriptors.emplace_back(Info::ConstantBufferDescriptor{ | 19 | info.constant_buffer_mask |= 1U << index; |
| 20 | info.constant_buffer_descriptors.push_back({ | ||
| 16 | .index{index}, | 21 | .index{index}, |
| 17 | .count{1}, | 22 | .count{1}, |
| 18 | }); | 23 | }); |
| 19 | } | 24 | } |
| 20 | 25 | ||
| 21 | void Visit(Info& info, IR::Inst& inst) { | 26 | void VisitUsages(Info& info, IR::Inst& inst) { |
| 22 | switch (inst.Opcode()) { | 27 | switch (inst.Opcode()) { |
| 23 | case IR::Opcode::WorkgroupId: | 28 | case IR::Opcode::WorkgroupId: |
| 24 | info.uses_workgroup_id = true; | 29 | info.uses_workgroup_id = true; |
| @@ -72,7 +77,7 @@ void Visit(Info& info, IR::Inst& inst) { | |||
| 72 | break; | 77 | break; |
| 73 | case IR::Opcode::GetCbuf: | 78 | case IR::Opcode::GetCbuf: |
| 74 | if (const IR::Value index{inst.Arg(0)}; index.IsImmediate()) { | 79 | if (const IR::Value index{inst.Arg(0)}; index.IsImmediate()) { |
| 75 | AddConstantBufferDescriptor(info, index.U32()); | 80 | AddConstantBufferDescriptor(info, index.U32(), 1); |
| 76 | } else { | 81 | } else { |
| 77 | throw NotImplementedException("Constant buffer with non-immediate index"); | 82 | throw NotImplementedException("Constant buffer with non-immediate index"); |
| 78 | } | 83 | } |
| @@ -81,6 +86,60 @@ void Visit(Info& info, IR::Inst& inst) { | |||
| 81 | break; | 86 | break; |
| 82 | } | 87 | } |
| 83 | } | 88 | } |
| 89 | |||
| 90 | void VisitFpModifiers(Info& info, IR::Inst& inst) { | ||
| 91 | switch (inst.Opcode()) { | ||
| 92 | case IR::Opcode::FPAdd16: | ||
| 93 | case IR::Opcode::FPFma16: | ||
| 94 | case IR::Opcode::FPMul16: | ||
| 95 | case IR::Opcode::FPRoundEven16: | ||
| 96 | case IR::Opcode::FPFloor16: | ||
| 97 | case IR::Opcode::FPCeil16: | ||
| 98 | case IR::Opcode::FPTrunc16: { | ||
| 99 | const auto control{inst.Flags<IR::FpControl>()}; | ||
| 100 | switch (control.fmz_mode) { | ||
| 101 | case IR::FmzMode::DontCare: | ||
| 102 | break; | ||
| 103 | case IR::FmzMode::FTZ: | ||
| 104 | case IR::FmzMode::FMZ: | ||
| 105 | info.uses_fp16_denorms_flush = true; | ||
| 106 | break; | ||
| 107 | case IR::FmzMode::None: | ||
| 108 | info.uses_fp16_denorms_preserve = true; | ||
| 109 | break; | ||
| 110 | } | ||
| 111 | break; | ||
| 112 | } | ||
| 113 | case IR::Opcode::FPAdd32: | ||
| 114 | case IR::Opcode::FPFma32: | ||
| 115 | case IR::Opcode::FPMul32: | ||
| 116 | case IR::Opcode::FPRoundEven32: | ||
| 117 | case IR::Opcode::FPFloor32: | ||
| 118 | case IR::Opcode::FPCeil32: | ||
| 119 | case IR::Opcode::FPTrunc32: { | ||
| 120 | const auto control{inst.Flags<IR::FpControl>()}; | ||
| 121 | switch (control.fmz_mode) { | ||
| 122 | case IR::FmzMode::DontCare: | ||
| 123 | break; | ||
| 124 | case IR::FmzMode::FTZ: | ||
| 125 | case IR::FmzMode::FMZ: | ||
| 126 | info.uses_fp32_denorms_flush = true; | ||
| 127 | break; | ||
| 128 | case IR::FmzMode::None: | ||
| 129 | info.uses_fp32_denorms_preserve = true; | ||
| 130 | break; | ||
| 131 | } | ||
| 132 | break; | ||
| 133 | } | ||
| 134 | default: | ||
| 135 | break; | ||
| 136 | } | ||
| 137 | } | ||
| 138 | |||
| 139 | void Visit(Info& info, IR::Inst& inst) { | ||
| 140 | VisitUsages(info, inst); | ||
| 141 | VisitFpModifiers(info, inst); | ||
| 142 | } | ||
| 84 | } // Anonymous namespace | 143 | } // Anonymous namespace |
| 85 | 144 | ||
| 86 | void CollectShaderInfoPass(IR::Program& program) { | 145 | void CollectShaderInfoPass(IR::Program& program) { |
diff --git a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp index bf230a850..03bd547b7 100644 --- a/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp +++ b/src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp | |||
| @@ -351,7 +351,6 @@ void GlobalMemoryToStorageBufferPass(IR::Program& program) { | |||
| 351 | .cbuf_offset{storage_buffer.offset}, | 351 | .cbuf_offset{storage_buffer.offset}, |
| 352 | .count{1}, | 352 | .count{1}, |
| 353 | }); | 353 | }); |
| 354 | info.storage_buffers[storage_index] = &info.storage_buffers_descriptors.back(); | ||
| 355 | ++storage_index; | 354 | ++storage_index; |
| 356 | } | 355 | } |
| 357 | for (const StorageInst& storage_inst : to_replace) { | 356 | for (const StorageInst& storage_inst : to_replace) { |