diff options
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp')
| -rw-r--r-- | Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp b/Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp index abe6df2653..a9c1fa2c19 100644 --- a/Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp +++ b/Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp @@ -17,6 +17,7 @@ #include "ShaderLang.h" #include "disassemble.h" +#include "Common/CommonFuncs.h" #include "Common/FileUtil.h" #include "Common/Logging/Log.h" #include "Common/MsgHandler.h" @@ -99,6 +100,18 @@ static const char COMPUTE_SHADER_HEADER[] = R"( #define frac fract #define lerp mix )"; +static const char SUBGROUP_HELPER_HEADER[] = R"( + #extension GL_KHR_shader_subgroup_basic : enable + #extension GL_KHR_shader_subgroup_arithmetic : enable + #extension GL_KHR_shader_subgroup_ballot : enable + + #define SUPPORTS_SUBGROUP_REDUCTION 1 + #define CAN_USE_SUBGROUP_REDUCTION true + #define IS_HELPER_INVOCATION gl_HelperInvocation + #define IS_FIRST_ACTIVE_INVOCATION (gl_SubgroupInvocationID == subgroupBallotFindLSB(subgroupBallot(true))) + #define SUBGROUP_MIN(value) value = subgroupMin(value) + #define SUBGROUP_MAX(value) value = subgroupMax(value) +)"; bool CompileShaderToSPV(SPIRVCodeVector* out_code, EShLanguage stage, const char* stage_filename, const char* source_code, size_t source_code_length, const char* header, @@ -120,13 +133,20 @@ bool CompileShaderToSPV(SPIRVCodeVector* out_code, EShLanguage stage, const char int pass_source_code_length = static_cast<int>(source_code_length); if (header_length > 0) { - full_source_code.reserve(header_length + source_code_length); + constexpr size_t subgroup_helper_header_length = ArraySize(SUBGROUP_HELPER_HEADER) - 1; + full_source_code.reserve(header_length + subgroup_helper_header_length + source_code_length); full_source_code.append(header, header_length); + if (g_vulkan_context->SupportsShaderSubgroupOperations()) + full_source_code.append(SUBGROUP_HELPER_HEADER, subgroup_helper_header_length); full_source_code.append(source_code, source_code_length); pass_source_code = full_source_code.c_str(); pass_source_code_length = static_cast<int>(full_source_code.length()); } + // Sub-group operations require Vulkan 1.1 and SPIR-V 1.3. + if (g_vulkan_context->SupportsShaderSubgroupOperations()) + shader->setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3); + shader->setStringsWithLengths(&pass_source_code, &pass_source_code_length, 1); auto DumpBadShader = [&](const char* msg) { |
