Просмотр исходного кода

glsl: Add boolean reference workaround

ameerj 4 лет назад
Родитель
Сommit
8c907c620d

+ 3 - 1
src/shader_recompiler/backend/glsl/emit_glsl_bitwise_conversion.cpp

@@ -7,6 +7,7 @@
 #include "shader_recompiler/backend/glsl/emit_glsl_instructions.h"
 #include "shader_recompiler/backend/glsl/glsl_emit_context.h"
 #include "shader_recompiler/frontend/ir/value.h"
+#include "shader_recompiler/profile.h"
 
 namespace Shader::Backend::GLSL {
 namespace {
@@ -30,8 +31,9 @@ void EmitConditionRef(EmitContext& ctx, IR::Inst& inst, const IR::Value& value)
     inst.DestructiveAddUsage(1);
     const auto ret{ctx.var_alloc.Define(inst, GlslVarType::U1)};
     const auto input{ctx.var_alloc.Consume(value)};
+    const auto suffix{ctx.profile.has_gl_bool_ref_bug ? "?true:false" : ""};
     if (ret != input) {
-        ctx.Add("{}={};", ret, input);
+        ctx.Add("{}={}{};", ret, input, suffix);
     }
 }
 

+ 3 - 1
src/shader_recompiler/backend/glsl/emit_glsl_special.cpp

@@ -90,7 +90,9 @@ void EmitPhiMove(EmitContext& ctx, const IR::Value& phi_value, const IR::Value&
     if (phi_reg == val_reg) {
         return;
     }
-    ctx.Add("{}={};", phi_reg, val_reg);
+    const bool needs_workaround{ctx.profile.has_gl_bool_ref_bug && phi_type == IR::Type::U1};
+    const auto suffix{needs_workaround ? "?true:false" : ""};
+    ctx.Add("{}={}{};", phi_reg, val_reg, suffix);
 }
 
 void EmitPrologue(EmitContext& ctx) {

+ 2 - 0
src/shader_recompiler/profile.h

@@ -67,6 +67,8 @@ struct Profile {
     bool has_gl_precise_bug{};
     /// Some drivers do not properly support floatBitsToUint when used on cbufs
     bool has_gl_cbuf_ftou_bug{};
+    /// Some drivers poorly optimize boolean variable references
+    bool has_gl_bool_ref_bug{};
     /// Ignores SPIR-V ordered vs unordered using GLSL semantics
     bool ignore_nan_fp_comparisons{};
 

+ 1 - 0
src/video_core/renderer_opengl/gl_device.cpp

@@ -188,6 +188,7 @@ Device::Device() {
             std::atoi(driver_version.substr(0, driver_version.find(".")).data());
         if (version_major >= 495) {
             has_cbuf_ftou_bug = true;
+            has_bool_ref_bug = true;
         }
     }
 

+ 5 - 0
src/video_core/renderer_opengl/gl_device.h

@@ -156,6 +156,10 @@ public:
         return has_cbuf_ftou_bug;
     }
 
+    bool HasBoolRefBug() const {
+        return has_bool_ref_bug;
+    }
+
     Settings::ShaderBackend GetShaderBackend() const {
         return shader_backend;
     }
@@ -205,6 +209,7 @@ private:
     bool warp_size_potentially_larger_than_guest{};
     bool need_fastmath_off{};
     bool has_cbuf_ftou_bug{};
+    bool has_bool_ref_bug{};
 
     std::string vendor_name;
 };

+ 1 - 0
src/video_core/renderer_opengl/gl_shader_cache.cpp

@@ -215,6 +215,7 @@ ShaderCache::ShaderCache(RasterizerOpenGL& rasterizer_, Core::Frontend::EmuWindo
           .has_gl_component_indexing_bug = device.HasComponentIndexingBug(),
           .has_gl_precise_bug = device.HasPreciseBug(),
           .has_gl_cbuf_ftou_bug = device.HasCbufFtouBug(),
+          .has_gl_bool_ref_bug = device.HasBoolRefBug(),
           .ignore_nan_fp_comparisons = true,
           .gl_max_compute_smem_size = device.GetMaxComputeSharedMemorySize(),
       },