diff options
author | bunnei <bunneidev@gmail.com> | 2019-08-29 18:58:10 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-08-29 18:58:10 +0200 |
commit | 680ab6132726946435081df6c4f2ef01ec2f1691 (patch) | |
tree | 230bc98a8bdd67a95c5abde32294655469845b3b /src/video_core/renderer_opengl/gl_shader_decompiler.cpp | |
parent | Merge pull request #2748 from FernandoS27/align-memory (diff) | |
parent | shader_ir: Implement VOTE (diff) | |
download | yuzu-680ab6132726946435081df6c4f2ef01ec2f1691.tar yuzu-680ab6132726946435081df6c4f2ef01ec2f1691.tar.gz yuzu-680ab6132726946435081df6c4f2ef01ec2f1691.tar.bz2 yuzu-680ab6132726946435081df6c4f2ef01ec2f1691.tar.lz yuzu-680ab6132726946435081df6c4f2ef01ec2f1691.tar.xz yuzu-680ab6132726946435081df6c4f2ef01ec2f1691.tar.zst yuzu-680ab6132726946435081df6c4f2ef01ec2f1691.zip |
Diffstat (limited to 'src/video_core/renderer_opengl/gl_shader_decompiler.cpp')
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_decompiler.cpp | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp index d8f722c26..1bfdbcd61 100644 --- a/src/video_core/renderer_opengl/gl_shader_decompiler.cpp +++ b/src/video_core/renderer_opengl/gl_shader_decompiler.cpp @@ -1735,6 +1735,48 @@ private: return "utof(gl_WorkGroupID"s + GetSwizzle(element) + ')'; } + std::string BallotThread(Operation operation) { + const std::string value = VisitOperand(operation, 0, Type::Bool); + if (!device.HasWarpIntrinsics()) { + LOG_ERROR(Render_OpenGL, + "Nvidia warp intrinsics are not available and its required by a shader"); + // Stub on non-Nvidia devices by simulating all threads voting the same as the active + // one. + return fmt::format("utof({} ? 0xFFFFFFFFU : 0U)", value); + } + return fmt::format("utof(ballotThreadNV({}))", value); + } + + std::string Vote(Operation operation, const char* func) { + const std::string value = VisitOperand(operation, 0, Type::Bool); + if (!device.HasWarpIntrinsics()) { + LOG_ERROR(Render_OpenGL, + "Nvidia vote intrinsics are not available and its required by a shader"); + // Stub with a warp size of one. + return value; + } + return fmt::format("{}({})", func, value); + } + + std::string VoteAll(Operation operation) { + return Vote(operation, "allThreadsNV"); + } + + std::string VoteAny(Operation operation) { + return Vote(operation, "anyThreadNV"); + } + + std::string VoteEqual(Operation operation) { + if (!device.HasWarpIntrinsics()) { + LOG_ERROR(Render_OpenGL, + "Nvidia vote intrinsics are not available and its required by a shader"); + // We must return true here since a stub for a theoretical warp size of 1 will always + // return an equal result for all its votes. + return "true"; + } + return Vote(operation, "allThreadsEqualNV"); + } + static constexpr std::array operation_decompilers = { &GLSLDecompiler::Assign, @@ -1885,6 +1927,11 @@ private: &GLSLDecompiler::WorkGroupId<0>, &GLSLDecompiler::WorkGroupId<1>, &GLSLDecompiler::WorkGroupId<2>, + + &GLSLDecompiler::BallotThread, + &GLSLDecompiler::VoteAll, + &GLSLDecompiler::VoteAny, + &GLSLDecompiler::VoteEqual, }; static_assert(operation_decompilers.size() == static_cast<std::size_t>(OperationCode::Amount)); |