summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/shader_recompiler/backend/glsl/emit_context.h10
-rw-r--r--src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp41
-rw-r--r--src/shader_recompiler/backend/glsl/var_alloc.cpp16
-rw-r--r--src/shader_recompiler/backend/glsl/var_alloc.h8
4 files changed, 67 insertions, 8 deletions
diff --git a/src/shader_recompiler/backend/glsl/emit_context.h b/src/shader_recompiler/backend/glsl/emit_context.h
index 423fc6104..48786a2c7 100644
--- a/src/shader_recompiler/backend/glsl/emit_context.h
+++ b/src/shader_recompiler/backend/glsl/emit_context.h
@@ -119,6 +119,16 @@ public:
119 } 119 }
120 120
121 template <typename... Args> 121 template <typename... Args>
122 void AddPrecF32(const char* format_str, IR::Inst& inst, Args&&... args) {
123 Add<GlslVarType::PrecF32>(format_str, inst, args...);
124 }
125
126 template <typename... Args>
127 void AddPrecF64(const char* format_str, IR::Inst& inst, Args&&... args) {
128 Add<GlslVarType::PrecF64>(format_str, inst, args...);
129 }
130
131 template <typename... Args>
122 void Add(const char* format_str, Args&&... args) { 132 void Add(const char* format_str, Args&&... args) {
123 code += fmt::format(format_str, std::forward<Args>(args)...); 133 code += fmt::format(format_str, std::forward<Args>(args)...);
124 // TODO: Remove this 134 // TODO: Remove this
diff --git a/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp b/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp
index 5f9603602..342d4efb2 100644
--- a/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp
+++ b/src/shader_recompiler/backend/glsl/emit_glsl_floating_point.cpp
@@ -6,6 +6,7 @@
6 6
7#include "shader_recompiler/backend/glsl/emit_context.h" 7#include "shader_recompiler/backend/glsl/emit_context.h"
8#include "shader_recompiler/backend/glsl/emit_glsl_instructions.h" 8#include "shader_recompiler/backend/glsl/emit_glsl_instructions.h"
9#include "shader_recompiler/frontend/ir/modifiers.h"
9#include "shader_recompiler/frontend/ir/value.h" 10#include "shader_recompiler/frontend/ir/value.h"
10 11
11namespace Shader::Backend::GLSL { 12namespace Shader::Backend::GLSL {
@@ -20,6 +21,10 @@ void Compare(EmitContext& ctx, IR::Inst& inst, std::string_view lhs, std::string
20 } 21 }
21 ctx.code += ";"; 22 ctx.code += ";";
22} 23}
24
25bool Precise(IR::Inst& inst) {
26 return {inst.Flags<IR::FpControl>().no_contraction};
27}
23} // namespace 28} // namespace
24 29
25void EmitFPAbs16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, 30void EmitFPAbs16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
@@ -41,11 +46,19 @@ void EmitFPAdd16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& i
41} 46}
42 47
43void EmitFPAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { 48void EmitFPAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) {
44 ctx.AddF32("{}=float({})+float({});", inst, a, b); 49 if (Precise(inst)) {
50 ctx.AddPrecF32("{}=float({})+float({});", inst, a, b);
51 } else {
52 ctx.AddF32("{}=float({})+float({});", inst, a, b);
53 }
45} 54}
46 55
47void EmitFPAdd64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { 56void EmitFPAdd64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) {
48 ctx.AddF64("{}=double({})+double({});", inst, a, b); 57 if (Precise(inst)) {
58 ctx.AddPrecF64("{}=double({})+double({});", inst, a, b);
59 } else {
60 ctx.AddF64("{}=double({})+double({});", inst, a, b);
61 }
49} 62}
50 63
51void EmitFPFma16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, 64void EmitFPFma16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
@@ -56,12 +69,20 @@ void EmitFPFma16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& i
56 69
57void EmitFPFma32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b, 70void EmitFPFma32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b,
58 std::string_view c) { 71 std::string_view c) {
59 ctx.AddF32("{}=fma({},{},{});", inst, a, b, c); 72 if (Precise(inst)) {
73 ctx.AddPrecF32("{}=fma({},{},{});", inst, a, b, c);
74 } else {
75 ctx.AddF32("{}=fma({},{},{});", inst, a, b, c);
76 }
60} 77}
61 78
62void EmitFPFma64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b, 79void EmitFPFma64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b,
63 std::string_view c) { 80 std::string_view c) {
64 ctx.AddF64("{}=fma({},{},{});", inst, a, b, c); 81 if (Precise(inst)) {
82 ctx.AddPrecF64("{}=fma({},{},{});", inst, a, b, c);
83 } else {
84 ctx.AddF64("{}=fma({},{},{});", inst, a, b, c);
85 }
65} 86}
66 87
67void EmitFPMax32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { 88void EmitFPMax32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) {
@@ -86,11 +107,19 @@ void EmitFPMul16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& i
86} 107}
87 108
88void EmitFPMul32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { 109void EmitFPMul32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) {
89 ctx.AddF32("{}={}*{};", inst, a, b); 110 if (Precise(inst)) {
111 ctx.AddPrecF32("{}={}*{};", inst, a, b);
112 } else {
113 ctx.AddF32("{}={}*{};", inst, a, b);
114 }
90} 115}
91 116
92void EmitFPMul64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { 117void EmitFPMul64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) {
93 ctx.AddF64("{}={}*{};", inst, a, b); 118 if (Precise(inst)) {
119 ctx.AddPrecF64("{}={}*{};", inst, a, b);
120 } else {
121 ctx.AddF64("{}={}*{};", inst, a, b);
122 }
94} 123}
95 124
96void EmitFPNeg16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, 125void EmitFPNeg16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst,
diff --git a/src/shader_recompiler/backend/glsl/var_alloc.cpp b/src/shader_recompiler/backend/glsl/var_alloc.cpp
index 896457248..2ecdec7f2 100644
--- a/src/shader_recompiler/backend/glsl/var_alloc.cpp
+++ b/src/shader_recompiler/backend/glsl/var_alloc.cpp
@@ -43,6 +43,10 @@ std::string TypePrefix(GlslVarType type) {
43 return "u4_"; 43 return "u4_";
44 case GlslVarType::F32x4: 44 case GlslVarType::F32x4:
45 return "f4_"; 45 return "f4_";
46 case GlslVarType::PrecF32:
47 return "pf_";
48 case GlslVarType::PrecF64:
49 return "pd_";
46 case GlslVarType::Void: 50 case GlslVarType::Void:
47 return ""; 51 return "";
48 default: 52 default:
@@ -225,6 +229,10 @@ std::string VarAlloc::GetGlslType(GlslVarType type) const {
225 return "uvec4 "; 229 return "uvec4 ";
226 case GlslVarType::F32x4: 230 case GlslVarType::F32x4:
227 return "vec4 "; 231 return "vec4 ";
232 case GlslVarType::PrecF32:
233 return "precise float ";
234 case GlslVarType::PrecF64:
235 return "precise double ";
228 case GlslVarType::Void: 236 case GlslVarType::Void:
229 return ""; 237 return "";
230 default: 238 default:
@@ -262,6 +270,10 @@ VarAlloc::UseTracker& VarAlloc::GetUseTracker(GlslVarType type) {
262 return var_u32x4; 270 return var_u32x4;
263 case GlslVarType::F32x4: 271 case GlslVarType::F32x4:
264 return var_f32x4; 272 return var_f32x4;
273 case GlslVarType::PrecF32:
274 return var_precf32;
275 case GlslVarType::PrecF64:
276 return var_precf64;
265 default: 277 default:
266 throw NotImplementedException("Type {}", type); 278 throw NotImplementedException("Type {}", type);
267 } 279 }
@@ -297,6 +309,10 @@ const VarAlloc::UseTracker& VarAlloc::GetUseTracker(GlslVarType type) const {
297 return var_u32x4; 309 return var_u32x4;
298 case GlslVarType::F32x4: 310 case GlslVarType::F32x4:
299 return var_f32x4; 311 return var_f32x4;
312 case GlslVarType::PrecF32:
313 return var_precf32;
314 case GlslVarType::PrecF64:
315 return var_precf64;
300 default: 316 default:
301 throw NotImplementedException("Type {}", type); 317 throw NotImplementedException("Type {}", type);
302 } 318 }
diff --git a/src/shader_recompiler/backend/glsl/var_alloc.h b/src/shader_recompiler/backend/glsl/var_alloc.h
index 574960b1a..be21a87ea 100644
--- a/src/shader_recompiler/backend/glsl/var_alloc.h
+++ b/src/shader_recompiler/backend/glsl/var_alloc.h
@@ -33,6 +33,8 @@ enum class GlslVarType : u32 {
33 F32x3, 33 F32x3,
34 U32x4, 34 U32x4,
35 F32x4, 35 F32x4,
36 PrecF32,
37 PrecF64,
36 Void, 38 Void,
37}; 39};
38 40
@@ -40,8 +42,8 @@ struct Id {
40 union { 42 union {
41 u32 raw; 43 u32 raw;
42 BitField<0, 1, u32> is_valid; 44 BitField<0, 1, u32> is_valid;
43 BitField<1, 4, GlslVarType> type; 45 BitField<1, 5, GlslVarType> type;
44 BitField<5, 27, u32> index; 46 BitField<6, 26, u32> index;
45 }; 47 };
46 48
47 bool operator==(Id rhs) const noexcept { 49 bool operator==(Id rhs) const noexcept {
@@ -101,6 +103,8 @@ private:
101 UseTracker var_u64{}; 103 UseTracker var_u64{};
102 UseTracker var_s64{}; 104 UseTracker var_s64{};
103 UseTracker var_f64{}; 105 UseTracker var_f64{};
106 UseTracker var_precf32{};
107 UseTracker var_precf64{};
104}; 108};
105 109
106} // namespace Shader::Backend::GLSL 110} // namespace Shader::Backend::GLSL