summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar ReinUsesLisp2019-11-07 20:03:50 -0300
committerGravatar ReinUsesLisp2019-11-07 20:08:42 -0300
commitcd663959445c855ab3d0c4c66b8930d30164cc40 (patch)
tree424f996aae381c1dd6960e0133c3a22b2cd6d653 /src
parentshader_ir/warp: Implement FSWZADD (diff)
downloadyuzu-cd663959445c855ab3d0c4c66b8930d30164cc40.tar.gz
yuzu-cd663959445c855ab3d0c4c66b8930d30164cc40.tar.xz
yuzu-cd663959445c855ab3d0c4c66b8930d30164cc40.zip
gl_shader_decompiler: Add safe fallbacks when ARB_shader_ballot is not available
Diffstat (limited to 'src')
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp2
-rw-r--r--src/video_core/renderer_opengl/gl_device.h5
-rw-r--r--src/video_core/renderer_opengl/gl_shader_decompiler.cpp26
3 files changed, 28 insertions, 5 deletions
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index c65b24c69..b30d5be74 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -62,6 +62,7 @@ Device::Device() {
62 max_varyings = GetInteger<u32>(GL_MAX_VARYING_VECTORS); 62 max_varyings = GetInteger<u32>(GL_MAX_VARYING_VECTORS);
63 has_warp_intrinsics = GLAD_GL_NV_gpu_shader5 && GLAD_GL_NV_shader_thread_group && 63 has_warp_intrinsics = GLAD_GL_NV_gpu_shader5 && GLAD_GL_NV_shader_thread_group &&
64 GLAD_GL_NV_shader_thread_shuffle; 64 GLAD_GL_NV_shader_thread_shuffle;
65 has_shader_ballot = GLAD_GL_ARB_shader_ballot;
65 has_vertex_viewport_layer = GLAD_GL_ARB_shader_viewport_layer_array; 66 has_vertex_viewport_layer = GLAD_GL_ARB_shader_viewport_layer_array;
66 has_image_load_formatted = HasExtension(extensions, "GL_EXT_shader_image_load_formatted"); 67 has_image_load_formatted = HasExtension(extensions, "GL_EXT_shader_image_load_formatted");
67 has_variable_aoffi = TestVariableAoffi(); 68 has_variable_aoffi = TestVariableAoffi();
@@ -79,6 +80,7 @@ Device::Device(std::nullptr_t) {
79 max_vertex_attributes = 16; 80 max_vertex_attributes = 16;
80 max_varyings = 15; 81 max_varyings = 15;
81 has_warp_intrinsics = true; 82 has_warp_intrinsics = true;
83 has_shader_ballot = true;
82 has_vertex_viewport_layer = true; 84 has_vertex_viewport_layer = true;
83 has_image_load_formatted = true; 85 has_image_load_formatted = true;
84 has_variable_aoffi = true; 86 has_variable_aoffi = true;
diff --git a/src/video_core/renderer_opengl/gl_device.h b/src/video_core/renderer_opengl/gl_device.h
index bf35bd0b6..6c86fe207 100644
--- a/src/video_core/renderer_opengl/gl_device.h
+++ b/src/video_core/renderer_opengl/gl_device.h
@@ -34,6 +34,10 @@ public:
34 return has_warp_intrinsics; 34 return has_warp_intrinsics;
35 } 35 }
36 36
37 bool HasShaderBallot() const {
38 return has_shader_ballot;
39 }
40
37 bool HasVertexViewportLayer() const { 41 bool HasVertexViewportLayer() const {
38 return has_vertex_viewport_layer; 42 return has_vertex_viewport_layer;
39 } 43 }
@@ -68,6 +72,7 @@ private:
68 u32 max_vertex_attributes{}; 72 u32 max_vertex_attributes{};
69 u32 max_varyings{}; 73 u32 max_varyings{};
70 bool has_warp_intrinsics{}; 74 bool has_warp_intrinsics{};
75 bool has_shader_ballot{};
71 bool has_vertex_viewport_layer{}; 76 bool has_vertex_viewport_layer{};
72 bool has_image_load_formatted{}; 77 bool has_image_load_formatted{};
73 bool has_variable_aoffi{}; 78 bool has_variable_aoffi{};
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
index 21c137ec5..5d2c38a5e 100644
--- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp
@@ -1382,13 +1382,19 @@ private:
1382 Expression FSwizzleAdd(Operation operation) { 1382 Expression FSwizzleAdd(Operation operation) {
1383 const std::string op_a = VisitOperand(operation, 0).AsFloat(); 1383 const std::string op_a = VisitOperand(operation, 0).AsFloat();
1384 const std::string op_b = VisitOperand(operation, 1).AsFloat(); 1384 const std::string op_b = VisitOperand(operation, 1).AsFloat();
1385 const std::string instr_mask = VisitOperand(operation, 2).AsUint();
1386 1385
1386 if (!device.HasShaderBallot()) {
1387 LOG_ERROR(Render_OpenGL, "Shader ballot is unavailable but required by the shader");
1388 return {fmt::format("{} + {}", op_a, op_b), Type::Float};
1389 }
1390
1391 const std::string instr_mask = VisitOperand(operation, 2).AsUint();
1387 const std::string mask = code.GenerateTemporary(); 1392 const std::string mask = code.GenerateTemporary();
1388 code.AddLine("uint {} = {} >> ((gl_SubGroupInvocationARB & 3) << 1);", mask, instr_mask); 1393 code.AddLine("uint {} = ({} >> ((gl_SubGroupInvocationARB & 3) << 1)) & 3;", mask,
1394 instr_mask);
1389 1395
1390 const std::string modifier_a = fmt::format("fswzadd_modifiers_a[{} & 3]", mask); 1396 const std::string modifier_a = fmt::format("fswzadd_modifiers_a[{}]", mask);
1391 const std::string modifier_b = fmt::format("fswzadd_modifiers_b[{} & 3]", mask); 1397 const std::string modifier_b = fmt::format("fswzadd_modifiers_b[{}]", mask);
1392 return {fmt::format("(({} * {}) + ({} * {}))", op_a, modifier_a, op_b, modifier_b), 1398 return {fmt::format("(({} * {}) + ({} * {}))", op_a, modifier_a, op_b, modifier_b),
1393 Type::Float}; 1399 Type::Float};
1394 } 1400 }
@@ -1957,11 +1963,21 @@ private:
1957 } 1963 }
1958 1964
1959 Expression ThreadId(Operation operation) { 1965 Expression ThreadId(Operation operation) {
1966 if (!device.HasShaderBallot()) {
1967 LOG_ERROR(Render_OpenGL, "Shader ballot is unavailable but required by the shader");
1968 return {"0U", Type::Uint};
1969 }
1960 return {"gl_SubGroupInvocationARB", Type::Uint}; 1970 return {"gl_SubGroupInvocationARB", Type::Uint};
1961 } 1971 }
1962 1972
1963 Expression ShuffleIndexed(Operation operation) { 1973 Expression ShuffleIndexed(Operation operation) {
1964 const std::string value = VisitOperand(operation, 0).AsFloat(); 1974 std::string value = VisitOperand(operation, 0).AsFloat();
1975
1976 if (!device.HasShaderBallot()) {
1977 LOG_ERROR(Render_OpenGL, "Shader ballot is unavailable but required by the shader");
1978 return {std::move(value), Type::Float};
1979 }
1980
1965 const std::string index = VisitOperand(operation, 1).AsUint(); 1981 const std::string index = VisitOperand(operation, 1).AsUint();
1966 return {fmt::format("readInvocationARB({}, {})", value, index), Type::Float}; 1982 return {fmt::format("readInvocationARB({}, {})", value, index), Type::Float};
1967 } 1983 }