Vulkan: Support subgroup reduction operations via GL_KHR_shader_subgroup

This commit is contained in:
Stenzek
2019-03-22 20:39:37 +10:00
parent 86da282570
commit 6561850f2b
4 changed files with 56 additions and 1 deletions

View File

@ -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) {