Add support for GL_EXT_shared_memory_block

Uses SPV_KHR_workgroup_memory_explicit_layout.  Note that if
GL_EXT_scalar_block_layout is enabled, Workgroup blocks can also use
scalar layout.
This commit is contained in:
Caio Marcelo de Oliveira Filho
2020-06-02 16:58:51 -07:00
parent 3785ddd59a
commit 4bfbf62794
33 changed files with 822 additions and 8 deletions

View File

@@ -50,5 +50,6 @@ static const char* const E_SPV_KHR_ray_tracing = "SPV_KHR_ray_t
static const char* const E_SPV_KHR_ray_query = "SPV_KHR_ray_query";
static const char* const E_SPV_KHR_fragment_shading_rate = "SPV_KHR_fragment_shading_rate";
static const char* const E_SPV_KHR_terminate_invocation = "SPV_KHR_terminate_invocation";
static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout";
#endif // #ifndef GLSLextKHR_H

View File

@@ -380,6 +380,7 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto
case glslang::EvqBuffer: return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock;
case glslang::EvqVaryingIn: return spv::DecorationBlock;
case glslang::EvqVaryingOut: return spv::DecorationBlock;
case glslang::EvqShared: return spv::DecorationBlock;
#ifndef GLSLANG_WEB
case glslang::EvqPayload: return spv::DecorationBlock;
case glslang::EvqPayloadIn: return spv::DecorationBlock;
@@ -436,6 +437,7 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T
break;
case glslang::EbtBlock:
switch (type.getQualifier().storage) {
case glslang::EvqShared:
case glslang::EvqUniform:
case glslang::EvqBuffer:
switch (type.getQualifier().layoutPacking) {
@@ -1278,6 +1280,12 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
return spv::StorageClassUniformConstant;
}
if (type.getQualifier().storage == glslang::EvqShared && type.getBasicType() == glslang::EbtBlock) {
builder.addExtension(spv::E_SPV_KHR_workgroup_memory_explicit_layout);
builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR);
return spv::StorageClassWorkgroup;
}
switch (type.getQualifier().storage) {
case glslang::EvqGlobal: return spv::StorageClassPrivate;
case glslang::EvqConstReadOnly: return spv::StorageClassFunction;
@@ -3623,6 +3631,11 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
break;
#endif
default:
if (storageClass == spv::StorageClassWorkgroup &&
node->getType().getBasicType() == glslang::EbtBlock) {
builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR);
break;
}
if (node->getType().contains16BitFloat())
builder.addCapability(spv::CapabilityFloat16);
if (node->getType().contains16BitInt())
@@ -3641,6 +3654,9 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
} else if (storageClass == spv::StorageClassStorageBuffer) {
builder.addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
builder.addCapability(spv::CapabilityStorageBuffer8BitAccess);
} else if (storageClass == spv::StorageClassWorkgroup &&
node->getType().getBasicType() == glslang::EbtBlock) {
builder.addCapability(spv::CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR);
} else {
builder.addCapability(spv::CapabilityInt8);
}
@@ -4407,6 +4423,7 @@ glslang::TLayoutPacking TGlslangToSpvTraverser::getExplicitLayout(const glslang:
// has to be a uniform or buffer block or task in/out blocks
if (type.getQualifier().storage != glslang::EvqUniform &&
type.getQualifier().storage != glslang::EvqBuffer &&
type.getQualifier().storage != glslang::EvqShared &&
!type.getQualifier().isTaskMemory())
return glslang::ElpNone;

View File

@@ -443,6 +443,31 @@ void Builder::postProcessFeatures() {
memoryModel = spv::MemoryModelVulkanKHR;
addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5);
}
// Add Aliased decoration if there's more than one Workgroup Block variable.
if (capabilities.find(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR) != capabilities.end()) {
assert(entryPoints.size() == 1);
auto &ep = entryPoints[0];
std::vector<Id> workgroup_variables;
for (int i = 0; i < (int)ep->getNumOperands(); i++) {
if (!ep->isIdOperand(i))
continue;
const Id id = ep->getIdOperand(i);
const Instruction *instr = module.getInstruction(id);
if (instr->getOpCode() != spv::OpVariable)
continue;
if (instr->getImmediateOperand(0) == spv::StorageClassWorkgroup)
workgroup_variables.push_back(id);
}
if (workgroup_variables.size() > 1) {
for (size_t i = 0; i < workgroup_variables.size(); i++)
addDecoration(workgroup_variables[i], spv::DecorationAliased);
}
}
}
#endif

View File

@@ -154,6 +154,7 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<
spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets());
spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization);
spvValidatorOptionsSetScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
spvValidatorOptionsSetWorkgroupScalarBlockLayout(options, intermediate.usingScalarBlockLayout());
spvValidateWithOptions(context, options, &binary, &diagnostic);
// report

View File

@@ -967,6 +967,10 @@ const char* CapabilityString(int info)
case CapabilityAtomicFloat32AddEXT: return "AtomicFloat32AddEXT";
case CapabilityAtomicFloat64AddEXT: return "AtomicFloat64AddEXT";
case CapabilityWorkgroupMemoryExplicitLayoutKHR: return "CapabilityWorkgroupMemoryExplicitLayoutKHR";
case CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR";
case CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR";
default: return "Bad";
}
}