summaryrefslogtreecommitdiff
path: root/Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp')
-rw-r--r--Source/Core/VideoBackends/Vulkan/ShaderCompiler.cpp22
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) {