summaryrefslogtreecommitdiff
path: root/src/shader_recompiler/ir_opt
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2021-02-20 03:30:13 -0300
committerGravatar ameerj2021-07-22 21:51:22 -0400
commite2bc05b17d91854cbb9c0ce3647141bf7d33143e (patch)
tree96769db006b6015cd536483db98ee0697aee4992 /src/shader_recompiler/ir_opt
parentspirv: Add lower fp16 to fp32 pass (diff)
downloadyuzu-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.cpp71
-rw-r--r--src/shader_recompiler/ir_opt/global_memory_to_storage_buffer_pass.cpp1
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
8namespace Shader::Optimization { 10namespace Shader::Optimization {
9namespace { 11namespace {
10void AddConstantBufferDescriptor(Info& info, u32 index) { 12void 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
21void Visit(Info& info, IR::Inst& inst) { 26void 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
90void 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
139void Visit(Info& info, IR::Inst& inst) {
140 VisitUsages(info, inst);
141 VisitFpModifiers(info, inst);
142}
84} // Anonymous namespace 143} // Anonymous namespace
85 144
86void CollectShaderInfoPass(IR::Program& program) { 145void 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) {