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:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user