diff options
| author | 2019-11-07 20:03:50 -0300 | |
|---|---|---|
| committer | 2019-11-07 20:08:42 -0300 | |
| commit | cd663959445c855ab3d0c4c66b8930d30164cc40 (patch) | |
| tree | 424f996aae381c1dd6960e0133c3a22b2cd6d653 /src | |
| parent | shader_ir/warp: Implement FSWZADD (diff) | |
| download | yuzu-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.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_device.h | 5 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 26 |
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 | } |