From 75eb953575b99da5657c1d1e5fe0605782b30e35 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 12 Apr 2020 05:06:55 -0300 Subject: [PATCH 1/2] gl_shader_decompiler: Improve generated code in HMergeH* Avoiding bitwise expressions, this fixes Turing issues in shaders using half float merges that affected several games. --- .../renderer_opengl/gl_shader_decompiler.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 160ae4340..59bbd1211 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1819,15 +1819,17 @@ private: } Expression HMergeH0(Operation operation) { - std::string dest = VisitOperand(operation, 0).AsUint(); - std::string src = VisitOperand(operation, 1).AsUint(); - return {fmt::format("(({} & 0x0000FFFFU) | ({} & 0xFFFF0000U))", src, dest), Type::Uint}; + const std::string dest = VisitOperand(operation, 0).AsUint(); + const std::string src = VisitOperand(operation, 1).AsUint(); + return {fmt::format("vec2(unpackHalf2x16({}).x, unpackHalf2x16({}).y)", src, dest), + Type::HalfFloat}; } Expression HMergeH1(Operation operation) { - std::string dest = VisitOperand(operation, 0).AsUint(); - std::string src = VisitOperand(operation, 1).AsUint(); - return {fmt::format("(({} & 0x0000FFFFU) | ({} & 0xFFFF0000U))", dest, src), Type::Uint}; + const std::string dest = VisitOperand(operation, 0).AsUint(); + const std::string src = VisitOperand(operation, 1).AsUint(); + return {fmt::format("vec2(unpackHalf2x16({}).x, unpackHalf2x16({}).y)", dest, src), + Type::HalfFloat}; } Expression HPack2(Operation operation) { From 05cf27083608bebd3ee4c38f2f948c8f2030f881 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 12 Apr 2020 22:39:57 -0300 Subject: [PATCH 2/2] gl_shader_decompiler: Implement merges with bitfieldInsert This also fixes Turing issues but it avoids doing more bitcasts. This should improve the generated code while also avoiding more points where compilers can flush floats. --- src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 59bbd1211..1f1f01313 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1821,15 +1821,13 @@ private: Expression HMergeH0(Operation operation) { const std::string dest = VisitOperand(operation, 0).AsUint(); const std::string src = VisitOperand(operation, 1).AsUint(); - return {fmt::format("vec2(unpackHalf2x16({}).x, unpackHalf2x16({}).y)", src, dest), - Type::HalfFloat}; + return {fmt::format("bitfieldInsert({}, {}, 0, 16)", dest, src), Type::Uint}; } Expression HMergeH1(Operation operation) { const std::string dest = VisitOperand(operation, 0).AsUint(); const std::string src = VisitOperand(operation, 1).AsUint(); - return {fmt::format("vec2(unpackHalf2x16({}).x, unpackHalf2x16({}).y)", dest, src), - Type::HalfFloat}; + return {fmt::format("bitfieldInsert({}, {}, 16, 16)", dest, src), Type::Uint}; } Expression HPack2(Operation operation) {