diff options
author | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-05-24 01:27:54 +0200 |
---|---|---|
committer | ReinUsesLisp <reinuseslisp@airmail.cc> | 2019-05-24 07:47:56 +0200 |
commit | d8827b07b5c823903609e00b8f0e1c27fa34fb91 (patch) | |
tree | b170468a3bd2e56f367a999561ea0e6b705a2f81 | |
parent | gl_device: Add test to detect broken component indexing (diff) | |
download | yuzu-d8827b07b5c823903609e00b8f0e1c27fa34fb91.tar yuzu-d8827b07b5c823903609e00b8f0e1c27fa34fb91.tar.gz yuzu-d8827b07b5c823903609e00b8f0e1c27fa34fb91.tar.bz2 yuzu-d8827b07b5c823903609e00b8f0e1c27fa34fb91.tar.lz yuzu-d8827b07b5c823903609e00b8f0e1c27fa34fb91.tar.xz yuzu-d8827b07b5c823903609e00b8f0e1c27fa34fb91.tar.zst yuzu-d8827b07b5c823903609e00b8f0e1c27fa34fb91.zip |
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index 6d4658c8b..4a40e4843 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -577,9 +577,26 @@ private: if (std::holds_alternative<OperationNode>(*offset)) { // Indirect access const std::string final_offset = code.GenerateTemporary(); - code.AddLine("uint {} = (ftou({}) / 4);", final_offset, Visit(offset)); - return fmt::format("{}[{} / 4][{} % 4]", GetConstBuffer(cbuf->GetIndex()), - final_offset, final_offset); + code.AddLine("uint {} = ftou({}) >> 2;", final_offset, Visit(offset)); + + if (!device.HasComponentIndexingBug()) { + return fmt::format("{}[{} >> 2][{} & 3]", GetConstBuffer(cbuf->GetIndex()), + final_offset, final_offset); + } + + // AMD's proprietary GLSL compiler emits ill code for variable component access. + // To bypass this driver bug generate 4 ifs, one per each component. + const std::string pack = code.GenerateTemporary(); + code.AddLine("vec4 {} = {}[{} >> 2];", pack, GetConstBuffer(cbuf->GetIndex()), + final_offset); + + const std::string result = code.GenerateTemporary(); + code.AddLine("float {};", result); + for (u32 swizzle = 0; swizzle < 4; ++swizzle) { + code.AddLine("if (({} & 3) == {}) {} = {}{};", final_offset, swizzle, result, + pack, GetSwizzle(swizzle)); + } + return result; } UNREACHABLE_MSG("Unmanaged offset node type"); |