diff options
| author | 2021-05-30 22:44:28 -0400 | |
|---|---|---|
| committer | 2021-07-22 21:51:37 -0400 | |
| commit | e10366974edd7c75111d0bef16daf941db9e9a30 (patch) | |
| tree | e7e986cc5f7184dba92ac2e6325ac3948111f08d /src/shader_recompiler/backend/glsl | |
| parent | HACK glsl: Write defaults to unused generic attributes (diff) | |
| download | yuzu-e10366974edd7c75111d0bef16daf941db9e9a30.tar.gz yuzu-e10366974edd7c75111d0bef16daf941db9e9a30.tar.xz yuzu-e10366974edd7c75111d0bef16daf941db9e9a30.zip | |
glsl: Implement precise fp variable allocation
Diffstat (limited to 'src/shader_recompiler/backend/glsl')
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 | ||
| 11 | namespace Shader::Backend::GLSL { | 12 | namespace 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 | |||
| 25 | bool Precise(IR::Inst& inst) { | ||
| 26 | return {inst.Flags<IR::FpControl>().no_contraction}; | ||
| 27 | } | ||
| 23 | } // namespace | 28 | } // namespace |
| 24 | 29 | ||
| 25 | void EmitFPAbs16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 30 | void 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 | ||
| 43 | void EmitFPAdd32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | 48 | void 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 | ||
| 47 | void EmitFPAdd64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | 56 | void 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 | ||
| 51 | void EmitFPFma16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 64 | void 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 | ||
| 57 | void EmitFPFma32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b, | 70 | void 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 | ||
| 62 | void EmitFPFma64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b, | 79 | void 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 | ||
| 67 | void EmitFPMax32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | 88 | void 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 | ||
| 88 | void EmitFPMul32(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | 109 | void 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 | ||
| 92 | void EmitFPMul64(EmitContext& ctx, IR::Inst& inst, std::string_view a, std::string_view b) { | 117 | void 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 | ||
| 96 | void EmitFPNeg16([[maybe_unused]] EmitContext& ctx, [[maybe_unused]] IR::Inst& inst, | 125 | void 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 |