GL_KHR_memory_scope_semantics
This commit is contained in:
parent
97068d8b30
commit
36831c9bad
@ -39,5 +39,6 @@ static const char* const E_SPV_KHR_16bit_storage = "SPV_KHR_16bit
|
|||||||
static const char* const E_SPV_KHR_8bit_storage = "SPV_KHR_8bit_storage";
|
static const char* const E_SPV_KHR_8bit_storage = "SPV_KHR_8bit_storage";
|
||||||
static const char* const E_SPV_KHR_storage_buffer_storage_class = "SPV_KHR_storage_buffer_storage_class";
|
static const char* const E_SPV_KHR_storage_buffer_storage_class = "SPV_KHR_storage_buffer_storage_class";
|
||||||
static const char* const E_SPV_KHR_post_depth_coverage = "SPV_KHR_post_depth_coverage";
|
static const char* const E_SPV_KHR_post_depth_coverage = "SPV_KHR_post_depth_coverage";
|
||||||
|
static const char* const E_SPV_KHR_vulkan_memory_model = "SPV_KHR_vulkan_memory_model";
|
||||||
|
|
||||||
#endif // #ifndef GLSLextKHR_H
|
#endif // #ifndef GLSLextKHR_H
|
||||||
|
|||||||
@ -129,6 +129,10 @@ protected:
|
|||||||
spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier);
|
spv::Decoration TranslateInterpolationDecoration(const glslang::TQualifier& qualifier);
|
||||||
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
|
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
|
||||||
spv::Decoration TranslateNonUniformDecoration(const glslang::TQualifier& qualifier);
|
spv::Decoration TranslateNonUniformDecoration(const glslang::TQualifier& qualifier);
|
||||||
|
spv::Builder::AccessChain::CoherentFlags TranslateCoherent(const glslang::TType& type);
|
||||||
|
spv::MemoryAccessMask TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags &coherentFlags);
|
||||||
|
spv::ImageOperandsMask TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags &coherentFlags);
|
||||||
|
spv::Scope TranslateMemoryScope(const spv::Builder::AccessChain::CoherentFlags &coherentFlags);
|
||||||
spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration);
|
spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration);
|
||||||
spv::ImageFormat TranslateImageFormat(const glslang::TType& type);
|
spv::ImageFormat TranslateImageFormat(const glslang::TType& type);
|
||||||
spv::SelectionControlMask TranslateSelectionControl(const glslang::TIntermSelection&) const;
|
spv::SelectionControlMask TranslateSelectionControl(const glslang::TIntermSelection&) const;
|
||||||
@ -327,14 +331,16 @@ spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useSto
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Translate glslang type to SPIR-V memory decorations.
|
// Translate glslang type to SPIR-V memory decorations.
|
||||||
void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector<spv::Decoration>& memory)
|
void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector<spv::Decoration>& memory, bool useVulkanMemoryModel)
|
||||||
{
|
{
|
||||||
|
if (!useVulkanMemoryModel) {
|
||||||
if (qualifier.coherent)
|
if (qualifier.coherent)
|
||||||
memory.push_back(spv::DecorationCoherent);
|
memory.push_back(spv::DecorationCoherent);
|
||||||
if (qualifier.volatil) {
|
if (qualifier.volatil) {
|
||||||
memory.push_back(spv::DecorationVolatile);
|
memory.push_back(spv::DecorationVolatile);
|
||||||
memory.push_back(spv::DecorationCoherent);
|
memory.push_back(spv::DecorationCoherent);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (qualifier.restrict)
|
if (qualifier.restrict)
|
||||||
memory.push_back(spv::DecorationRestrict);
|
memory.push_back(spv::DecorationRestrict);
|
||||||
if (qualifier.readonly)
|
if (qualifier.readonly)
|
||||||
@ -450,6 +456,105 @@ spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glsl
|
|||||||
return spv::DecorationMax;
|
return spv::DecorationMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
|
||||||
|
{
|
||||||
|
if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage) {
|
||||||
|
return spv::MemoryAccessMaskNone;
|
||||||
|
}
|
||||||
|
spv::MemoryAccessMask mask = spv::MemoryAccessMaskNone;
|
||||||
|
if (coherentFlags.volatil ||
|
||||||
|
coherentFlags.coherent ||
|
||||||
|
coherentFlags.devicecoherent ||
|
||||||
|
coherentFlags.queuefamilycoherent ||
|
||||||
|
coherentFlags.workgroupcoherent ||
|
||||||
|
coherentFlags.subgroupcoherent) {
|
||||||
|
mask = mask | spv::MemoryAccessMakePointerAvailableKHRMask |
|
||||||
|
spv::MemoryAccessMakePointerVisibleKHRMask;
|
||||||
|
}
|
||||||
|
if (coherentFlags.nonprivate) {
|
||||||
|
mask = mask | spv::MemoryAccessNonPrivatePointerKHRMask;
|
||||||
|
}
|
||||||
|
if (coherentFlags.volatil) {
|
||||||
|
mask = mask | spv::MemoryAccessVolatileMask;
|
||||||
|
}
|
||||||
|
if (mask != spv::MemoryAccessMaskNone) {
|
||||||
|
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
|
||||||
|
{
|
||||||
|
if (!glslangIntermediate->usingVulkanMemoryModel()) {
|
||||||
|
return spv::ImageOperandsMaskNone;
|
||||||
|
}
|
||||||
|
spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
|
||||||
|
if (coherentFlags.volatil ||
|
||||||
|
coherentFlags.coherent ||
|
||||||
|
coherentFlags.devicecoherent ||
|
||||||
|
coherentFlags.queuefamilycoherent ||
|
||||||
|
coherentFlags.workgroupcoherent ||
|
||||||
|
coherentFlags.subgroupcoherent) {
|
||||||
|
mask = mask | spv::ImageOperandsMakeTexelAvailableKHRMask |
|
||||||
|
spv::ImageOperandsMakeTexelVisibleKHRMask;
|
||||||
|
}
|
||||||
|
if (coherentFlags.nonprivate) {
|
||||||
|
mask = mask | spv::ImageOperandsNonPrivateTexelKHRMask;
|
||||||
|
}
|
||||||
|
if (coherentFlags.volatil) {
|
||||||
|
mask = mask | spv::ImageOperandsVolatileTexelKHRMask;
|
||||||
|
}
|
||||||
|
if (mask != spv::ImageOperandsMaskNone) {
|
||||||
|
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCoherent(const glslang::TType& type)
|
||||||
|
{
|
||||||
|
spv::Builder::AccessChain::CoherentFlags flags;
|
||||||
|
flags.coherent = type.getQualifier().coherent;
|
||||||
|
flags.devicecoherent = type.getQualifier().devicecoherent;
|
||||||
|
flags.queuefamilycoherent = type.getQualifier().queuefamilycoherent;
|
||||||
|
// shared variables are implicitly workgroupcoherent in GLSL.
|
||||||
|
flags.workgroupcoherent = type.getQualifier().workgroupcoherent ||
|
||||||
|
type.getQualifier().storage == glslang::EvqShared;
|
||||||
|
flags.subgroupcoherent = type.getQualifier().subgroupcoherent;
|
||||||
|
// *coherent variables are implicitly nonprivate in GLSL
|
||||||
|
flags.nonprivate = type.getQualifier().nonprivate ||
|
||||||
|
type.getQualifier().subgroupcoherent ||
|
||||||
|
type.getQualifier().workgroupcoherent ||
|
||||||
|
type.getQualifier().queuefamilycoherent ||
|
||||||
|
type.getQualifier().devicecoherent ||
|
||||||
|
type.getQualifier().coherent;
|
||||||
|
flags.volatil = type.getQualifier().volatil;
|
||||||
|
flags.isImage = type.getBasicType() == glslang::EbtSampler;
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
|
||||||
|
{
|
||||||
|
spv::Scope scope;
|
||||||
|
if (coherentFlags.coherent) {
|
||||||
|
// coherent defaults to Device scope in the old model, QueueFamilyKHR scope in the new model
|
||||||
|
scope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
|
||||||
|
} else if (coherentFlags.devicecoherent) {
|
||||||
|
scope = spv::ScopeDevice;
|
||||||
|
} else if (coherentFlags.queuefamilycoherent) {
|
||||||
|
scope = spv::ScopeQueueFamilyKHR;
|
||||||
|
} else if (coherentFlags.workgroupcoherent) {
|
||||||
|
scope = spv::ScopeWorkgroup;
|
||||||
|
} else if (coherentFlags.subgroupcoherent) {
|
||||||
|
scope = spv::ScopeSubgroup;
|
||||||
|
} else {
|
||||||
|
scope = spv::ScopeMax;
|
||||||
|
}
|
||||||
|
if (glslangIntermediate->usingVulkanMemoryModel() && scope == spv::ScopeDevice) {
|
||||||
|
builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
|
||||||
|
}
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
|
||||||
// Translate a glslang built-in variable to a SPIR-V built in decoration. Also generate
|
// Translate a glslang built-in variable to a SPIR-V built in decoration. Also generate
|
||||||
// associated capabilities when required. For some built-in variables, a capability
|
// associated capabilities when required. For some built-in variables, a capability
|
||||||
// is generated only when using the variable in an executable instruction, but not when
|
// is generated only when using the variable in an executable instruction, but not when
|
||||||
@ -979,6 +1084,16 @@ void InheritQualifiers(glslang::TQualifier& child, const glslang::TQualifier& pa
|
|||||||
child.sample = true;
|
child.sample = true;
|
||||||
if (parent.coherent)
|
if (parent.coherent)
|
||||||
child.coherent = true;
|
child.coherent = true;
|
||||||
|
if (parent.devicecoherent)
|
||||||
|
child.devicecoherent = true;
|
||||||
|
if (parent.queuefamilycoherent)
|
||||||
|
child.queuefamilycoherent = true;
|
||||||
|
if (parent.workgroupcoherent)
|
||||||
|
child.workgroupcoherent = true;
|
||||||
|
if (parent.subgroupcoherent)
|
||||||
|
child.subgroupcoherent = true;
|
||||||
|
if (parent.nonprivate)
|
||||||
|
child.nonprivate = true;
|
||||||
if (parent.volatil)
|
if (parent.volatil)
|
||||||
child.volatil = true;
|
child.volatil = true;
|
||||||
if (parent.restrict)
|
if (parent.restrict)
|
||||||
@ -1045,7 +1160,12 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
|
|||||||
builder.setSourceText(text);
|
builder.setSourceText(text);
|
||||||
}
|
}
|
||||||
stdBuiltins = builder.import("GLSL.std.450");
|
stdBuiltins = builder.import("GLSL.std.450");
|
||||||
|
if (glslangIntermediate->usingVulkanMemoryModel()) {
|
||||||
|
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelVulkanKHR);
|
||||||
|
builder.addExtension(spv::E_SPV_KHR_vulkan_memory_model);
|
||||||
|
} else {
|
||||||
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
|
builder.setMemoryModel(spv::AddressingModelLogical, spv::MemoryModelGLSL450);
|
||||||
|
}
|
||||||
shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
|
shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
|
||||||
entryPoint = builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPointName().c_str());
|
entryPoint = builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPointName().c_str());
|
||||||
|
|
||||||
@ -1351,7 +1471,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||||||
|
|
||||||
// store the result
|
// store the result
|
||||||
builder.setAccessChain(lValue);
|
builder.setAccessChain(lValue);
|
||||||
multiTypeStore(node->getType(), rValue);
|
multiTypeStore(node->getLeft()->getType(), rValue);
|
||||||
|
|
||||||
// assignments are expressions having an rValue after they are evaluated...
|
// assignments are expressions having an rValue after they are evaluated...
|
||||||
builder.clearAccessChain();
|
builder.clearAccessChain();
|
||||||
@ -1388,7 +1508,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||||||
}
|
}
|
||||||
|
|
||||||
// normal case for indexing array or structure or block
|
// normal case for indexing array or structure or block
|
||||||
builder.accessChainPush(builder.makeIntConstant(spvIndex));
|
builder.accessChainPush(builder.makeIntConstant(spvIndex), TranslateCoherent(node->getLeft()->getType()));
|
||||||
|
|
||||||
// Add capabilities here for accessing PointSize and clip/cull distance.
|
// Add capabilities here for accessing PointSize and clip/cull distance.
|
||||||
// We have deferred generation of associated capabilities until now.
|
// We have deferred generation of associated capabilities until now.
|
||||||
@ -1424,7 +1544,7 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T
|
|||||||
if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector())
|
if (! node->getLeft()->getType().isArray() && node->getLeft()->getType().isVector())
|
||||||
builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()));
|
builder.accessChainPushComponent(index, convertGlslangToSpvType(node->getLeft()->getType()));
|
||||||
else
|
else
|
||||||
builder.accessChainPush(index);
|
builder.accessChainPush(index, TranslateCoherent(node->getLeft()->getType()));
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case glslang::EOpVectorSwizzle:
|
case glslang::EOpVectorSwizzle:
|
||||||
@ -1658,11 +1778,11 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||||||
builder.setAccessChainRValue(result);
|
builder.setAccessChainRValue(result);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
} else if (node->getOp() == glslang::EOpImageStore ||
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
} else if (node->getOp() == glslang::EOpImageStore || node->getOp() == glslang::EOpImageStoreLod) {
|
node->getOp() == glslang::EOpImageStoreLod ||
|
||||||
#else
|
|
||||||
} else if (node->getOp() == glslang::EOpImageStore) {
|
|
||||||
#endif
|
#endif
|
||||||
|
node->getOp() == glslang::EOpImageAtomicStore) {
|
||||||
// "imageStore" is a special case, which has no result
|
// "imageStore" is a special case, which has no result
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -1952,6 +2072,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||||||
// These all have 0 operands and will naturally finish up in the code below for 0 operands
|
// These all have 0 operands and will naturally finish up in the code below for 0 operands
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case glslang::EOpAtomicStore:
|
||||||
|
noReturnValue = true;
|
||||||
|
// fallthrough
|
||||||
|
case glslang::EOpAtomicLoad:
|
||||||
case glslang::EOpAtomicAdd:
|
case glslang::EOpAtomicAdd:
|
||||||
case glslang::EOpAtomicMin:
|
case glslang::EOpAtomicMin:
|
||||||
case glslang::EOpAtomicMax:
|
case glslang::EOpAtomicMax:
|
||||||
@ -2050,6 +2174,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||||||
case glslang::EOpAtomicXor:
|
case glslang::EOpAtomicXor:
|
||||||
case glslang::EOpAtomicExchange:
|
case glslang::EOpAtomicExchange:
|
||||||
case glslang::EOpAtomicCompSwap:
|
case glslang::EOpAtomicCompSwap:
|
||||||
|
case glslang::EOpAtomicLoad:
|
||||||
|
case glslang::EOpAtomicStore:
|
||||||
case glslang::EOpAtomicCounterAdd:
|
case glslang::EOpAtomicCounterAdd:
|
||||||
case glslang::EOpAtomicCounterSubtract:
|
case glslang::EOpAtomicCounterSubtract:
|
||||||
case glslang::EOpAtomicCounterMin:
|
case glslang::EOpAtomicCounterMin:
|
||||||
@ -2876,7 +3002,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
|
|||||||
qualifier.storage == glslang::EvqBuffer) {
|
qualifier.storage == glslang::EvqBuffer) {
|
||||||
// Add memory decorations only to top-level members of shader storage block
|
// Add memory decorations only to top-level members of shader storage block
|
||||||
std::vector<spv::Decoration> memory;
|
std::vector<spv::Decoration> memory;
|
||||||
TranslateMemoryDecoration(memberQualifier, memory);
|
TranslateMemoryDecoration(memberQualifier, memory, glslangIntermediate->usingVulkanMemoryModel());
|
||||||
for (unsigned int i = 0; i < memory.size(); ++i)
|
for (unsigned int i = 0; i < memory.size(); ++i)
|
||||||
builder.addMemberDecoration(spvType, member, memory[i]);
|
builder.addMemberDecoration(spvType, member, memory[i]);
|
||||||
}
|
}
|
||||||
@ -2987,8 +3113,15 @@ spv::Id TGlslangToSpvTraverser::makeArraySizeId(const glslang::TArraySizes& arra
|
|||||||
spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
|
spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type)
|
||||||
{
|
{
|
||||||
spv::Id nominalTypeId = builder.accessChainGetInferredType();
|
spv::Id nominalTypeId = builder.accessChainGetInferredType();
|
||||||
|
|
||||||
|
spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
|
||||||
|
coherentFlags |= TranslateCoherent(type);
|
||||||
|
|
||||||
spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
|
spv::Id loadedId = builder.accessChainLoad(TranslatePrecisionDecoration(type),
|
||||||
TranslateNonUniformDecoration(type.getQualifier()), nominalTypeId);
|
TranslateNonUniformDecoration(type.getQualifier()),
|
||||||
|
nominalTypeId,
|
||||||
|
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask),
|
||||||
|
TranslateMemoryScope(coherentFlags));
|
||||||
|
|
||||||
// Need to convert to abstract types when necessary
|
// Need to convert to abstract types when necessary
|
||||||
if (type.getBasicType() == glslang::EbtBool) {
|
if (type.getBasicType() == glslang::EbtBool) {
|
||||||
@ -3044,7 +3177,12 @@ void TGlslangToSpvTraverser::accessChainStore(const glslang::TType& type, spv::I
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.accessChainStore(rvalue);
|
spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags;
|
||||||
|
coherentFlags |= TranslateCoherent(type);
|
||||||
|
|
||||||
|
builder.accessChainStore(rvalue,
|
||||||
|
spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerVisibleKHRMask),
|
||||||
|
TranslateMemoryScope(coherentFlags));
|
||||||
}
|
}
|
||||||
|
|
||||||
// For storing when types match at the glslang level, but not might match at the
|
// For storing when types match at the glslang level, but not might match at the
|
||||||
@ -3090,7 +3228,7 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id
|
|||||||
// set up the target storage
|
// set up the target storage
|
||||||
builder.clearAccessChain();
|
builder.clearAccessChain();
|
||||||
builder.setAccessChainLValue(lValue);
|
builder.setAccessChainLValue(lValue);
|
||||||
builder.accessChainPush(builder.makeIntConstant(index));
|
builder.accessChainPush(builder.makeIntConstant(index), TranslateCoherent(type));
|
||||||
|
|
||||||
// store the member
|
// store the member
|
||||||
multiTypeStore(glslangElementType, elementRValue);
|
multiTypeStore(glslangElementType, elementRValue);
|
||||||
@ -3110,7 +3248,7 @@ void TGlslangToSpvTraverser::multiTypeStore(const glslang::TType& type, spv::Id
|
|||||||
// set up the target storage
|
// set up the target storage
|
||||||
builder.clearAccessChain();
|
builder.clearAccessChain();
|
||||||
builder.setAccessChainLValue(lValue);
|
builder.setAccessChainLValue(lValue);
|
||||||
builder.accessChainPush(builder.makeIntConstant(m));
|
builder.accessChainPush(builder.makeIntConstant(m), TranslateCoherent(type));
|
||||||
|
|
||||||
// store the member
|
// store the member
|
||||||
multiTypeStore(glslangMemberType, memberRValue);
|
multiTypeStore(glslangMemberType, memberRValue);
|
||||||
@ -3287,11 +3425,11 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier,
|
|||||||
// Make all the functions, skeletally, without actually visiting their bodies.
|
// Make all the functions, skeletally, without actually visiting their bodies.
|
||||||
void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions)
|
void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslFunctions)
|
||||||
{
|
{
|
||||||
const auto getParamDecorations = [](std::vector<spv::Decoration>& decorations, const glslang::TType& type) {
|
const auto getParamDecorations = [](std::vector<spv::Decoration>& decorations, const glslang::TType& type, bool useVulkanMemoryModel) {
|
||||||
spv::Decoration paramPrecision = TranslatePrecisionDecoration(type);
|
spv::Decoration paramPrecision = TranslatePrecisionDecoration(type);
|
||||||
if (paramPrecision != spv::NoPrecision)
|
if (paramPrecision != spv::NoPrecision)
|
||||||
decorations.push_back(paramPrecision);
|
decorations.push_back(paramPrecision);
|
||||||
TranslateMemoryDecoration(type.getQualifier(), decorations);
|
TranslateMemoryDecoration(type.getQualifier(), decorations, useVulkanMemoryModel);
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int f = 0; f < (int)glslFunctions.size(); ++f) {
|
for (int f = 0; f < (int)glslFunctions.size(); ++f) {
|
||||||
@ -3330,7 +3468,7 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
|
|||||||
typeId = builder.makePointer(spv::StorageClassFunction, typeId);
|
typeId = builder.makePointer(spv::StorageClassFunction, typeId);
|
||||||
else
|
else
|
||||||
rValueParameters.insert(parameters[p]->getAsSymbolNode()->getId());
|
rValueParameters.insert(parameters[p]->getAsSymbolNode()->getId());
|
||||||
getParamDecorations(paramDecorations[p], paramType);
|
getParamDecorations(paramDecorations[p], paramType, glslangIntermediate->usingVulkanMemoryModel());
|
||||||
paramTypes.push_back(typeId);
|
paramTypes.push_back(typeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3420,6 +3558,8 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate&
|
|||||||
case glslang::EOpImageAtomicXor:
|
case glslang::EOpImageAtomicXor:
|
||||||
case glslang::EOpImageAtomicExchange:
|
case glslang::EOpImageAtomicExchange:
|
||||||
case glslang::EOpImageAtomicCompSwap:
|
case glslang::EOpImageAtomicCompSwap:
|
||||||
|
case glslang::EOpImageAtomicLoad:
|
||||||
|
case glslang::EOpImageAtomicStore:
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
lvalue = true;
|
lvalue = true;
|
||||||
break;
|
break;
|
||||||
@ -3547,8 +3687,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||||||
builder.setLine(node->getLoc().line);
|
builder.setLine(node->getLoc().line);
|
||||||
|
|
||||||
// Process a GLSL texturing op (will be SPV image)
|
// Process a GLSL texturing op (will be SPV image)
|
||||||
const glslang::TSampler sampler = node->getAsAggregate() ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType().getSampler()
|
|
||||||
: node->getAsUnaryNode()->getOperand()->getAsTyped()->getType().getSampler();
|
const glslang::TType &imageType = node->getAsAggregate() ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType()
|
||||||
|
: node->getAsUnaryNode()->getOperand()->getAsTyped()->getType();
|
||||||
|
const glslang::TSampler sampler = imageType.getSampler();
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
bool f16ShadowCompare = (sampler.shadow && node->getAsAggregate())
|
bool f16ShadowCompare = (sampler.shadow && node->getAsAggregate())
|
||||||
? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16
|
? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16
|
||||||
@ -3651,22 +3793,38 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||||||
#else
|
#else
|
||||||
if (node->getOp() == glslang::EOpImageLoad) {
|
if (node->getOp() == glslang::EOpImageLoad) {
|
||||||
#endif
|
#endif
|
||||||
|
spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
|
||||||
if (sampler.ms) {
|
if (sampler.ms) {
|
||||||
spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
|
mask = mask | spv::ImageOperandsSampleMask;
|
||||||
operands.push_back(imageOperands);
|
}
|
||||||
spv::IdImmediate imageOperand = { true, *opIt };
|
|
||||||
operands.push_back(imageOperand);
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
} else if (cracked.lod) {
|
if (cracked.lod) {
|
||||||
builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
|
builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
|
||||||
builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
|
builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
|
||||||
|
mask = mask | spv::ImageOperandsLodMask;
|
||||||
spv::IdImmediate imageOperands = { false, spv::ImageOperandsLodMask };
|
|
||||||
operands.push_back(imageOperands);
|
|
||||||
spv::IdImmediate imageOperand = { true, *opIt };
|
|
||||||
operands.push_back(imageOperand);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
mask = mask | TranslateImageOperands(TranslateCoherent(imageType));
|
||||||
|
mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask);
|
||||||
|
if (mask) {
|
||||||
|
spv::IdImmediate imageOperands = { false, (unsigned int)mask };
|
||||||
|
operands.push_back(imageOperands);
|
||||||
|
}
|
||||||
|
if (mask & spv::ImageOperandsSampleMask) {
|
||||||
|
spv::IdImmediate imageOperand = { true, *opIt++ };
|
||||||
|
operands.push_back(imageOperand);
|
||||||
|
}
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
if (mask & spv::ImageOperandsLodMask) {
|
||||||
|
spv::IdImmediate imageOperand = { true, *opIt++ };
|
||||||
|
operands.push_back(imageOperand);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (mask & spv::ImageOperandsMakeTexelVisibleKHRMask) {
|
||||||
|
spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
|
||||||
|
operands.push_back(imageOperand);
|
||||||
|
}
|
||||||
|
|
||||||
if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
|
if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
|
||||||
builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
|
builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
|
||||||
|
|
||||||
@ -3683,29 +3841,52 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||||||
#else
|
#else
|
||||||
} else if (node->getOp() == glslang::EOpImageStore) {
|
} else if (node->getOp() == glslang::EOpImageStore) {
|
||||||
#endif
|
#endif
|
||||||
if (sampler.ms) {
|
|
||||||
spv::IdImmediate texel = { true, *(opIt + 1) };
|
|
||||||
operands.push_back(texel);
|
|
||||||
spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
|
|
||||||
operands.push_back(imageOperands);
|
|
||||||
spv::IdImmediate imageOperand = { true, *opIt };
|
|
||||||
operands.push_back(imageOperand);
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
} else if (cracked.lod) {
|
|
||||||
builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
|
|
||||||
builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
|
|
||||||
|
|
||||||
|
// Push the texel value before the operands
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
if (sampler.ms || cracked.lod) {
|
||||||
|
#else
|
||||||
|
if (sampler.ms) {
|
||||||
|
#endif
|
||||||
spv::IdImmediate texel = { true, *(opIt + 1) };
|
spv::IdImmediate texel = { true, *(opIt + 1) };
|
||||||
operands.push_back(texel);
|
operands.push_back(texel);
|
||||||
spv::IdImmediate imageOperands = { false, spv::ImageOperandsLodMask };
|
|
||||||
operands.push_back(imageOperands);
|
|
||||||
spv::IdImmediate imageOperand = { true, *opIt };
|
|
||||||
operands.push_back(imageOperand);
|
|
||||||
#endif
|
|
||||||
} else {
|
} else {
|
||||||
spv::IdImmediate texel = { true, *opIt };
|
spv::IdImmediate texel = { true, *opIt };
|
||||||
operands.push_back(texel);
|
operands.push_back(texel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
|
||||||
|
if (sampler.ms) {
|
||||||
|
mask = mask | spv::ImageOperandsSampleMask;
|
||||||
|
}
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
if (cracked.lod) {
|
||||||
|
builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
|
||||||
|
builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
|
||||||
|
mask = mask | spv::ImageOperandsLodMask;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
mask = mask | TranslateImageOperands(TranslateCoherent(imageType));
|
||||||
|
mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelVisibleKHRMask);
|
||||||
|
if (mask) {
|
||||||
|
spv::IdImmediate imageOperands = { false, (unsigned int)mask };
|
||||||
|
operands.push_back(imageOperands);
|
||||||
|
}
|
||||||
|
if (mask & spv::ImageOperandsSampleMask) {
|
||||||
|
spv::IdImmediate imageOperand = { true, *opIt++ };
|
||||||
|
operands.push_back(imageOperand);
|
||||||
|
}
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
if (mask & spv::ImageOperandsLodMask) {
|
||||||
|
spv::IdImmediate imageOperand = { true, *opIt++ };
|
||||||
|
operands.push_back(imageOperand);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (mask & spv::ImageOperandsMakeTexelAvailableKHRMask) {
|
||||||
|
spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
|
||||||
|
operands.push_back(imageOperand);
|
||||||
|
}
|
||||||
|
|
||||||
builder.createNoResultOp(spv::OpImageWrite, operands);
|
builder.createNoResultOp(spv::OpImageWrite, operands);
|
||||||
if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
|
if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
|
||||||
builder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat);
|
builder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat);
|
||||||
@ -3719,21 +3900,37 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||||||
if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
|
if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
|
||||||
builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
|
builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
|
||||||
|
|
||||||
|
spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
|
||||||
if (sampler.ms) {
|
if (sampler.ms) {
|
||||||
spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
|
mask = mask | spv::ImageOperandsSampleMask;
|
||||||
operands.push_back(imageOperands);
|
}
|
||||||
spv::IdImmediate imageOperand = { true, *opIt++ };
|
|
||||||
operands.push_back(imageOperand);
|
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
} else if (cracked.lod) {
|
if (cracked.lod) {
|
||||||
builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
|
builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
|
||||||
builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
|
builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
|
||||||
|
|
||||||
spv::IdImmediate imageOperands = { false, spv::ImageOperandsLodMask };
|
mask = mask | spv::ImageOperandsLodMask;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
mask = mask | TranslateImageOperands(TranslateCoherent(imageType));
|
||||||
|
mask = (spv::ImageOperandsMask)(mask & ~spv::ImageOperandsMakeTexelAvailableKHRMask);
|
||||||
|
if (mask) {
|
||||||
|
spv::IdImmediate imageOperands = { false, (unsigned int)mask };
|
||||||
operands.push_back(imageOperands);
|
operands.push_back(imageOperands);
|
||||||
|
}
|
||||||
|
if (mask & spv::ImageOperandsSampleMask) {
|
||||||
spv::IdImmediate imageOperand = { true, *opIt++ };
|
spv::IdImmediate imageOperand = { true, *opIt++ };
|
||||||
operands.push_back(imageOperand);
|
operands.push_back(imageOperand);
|
||||||
|
}
|
||||||
|
#ifdef AMD_EXTENSIONS
|
||||||
|
if (mask & spv::ImageOperandsLodMask) {
|
||||||
|
spv::IdImmediate imageOperand = { true, *opIt++ };
|
||||||
|
operands.push_back(imageOperand);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (mask & spv::ImageOperandsMakeTexelVisibleKHRMask) {
|
||||||
|
spv::IdImmediate imageOperand = { true, builder.makeUintConstant(TranslateMemoryScope(TranslateCoherent(imageType))) };
|
||||||
|
operands.push_back(imageOperand);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the return type that was a special structure
|
// Create the return type that was a special structure
|
||||||
@ -3756,7 +3953,14 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||||||
spv::IdImmediate sample = { true, sampler.ms ? *(opIt++) : builder.makeUintConstant(0) };
|
spv::IdImmediate sample = { true, sampler.ms ? *(opIt++) : builder.makeUintConstant(0) };
|
||||||
operands.push_back(sample);
|
operands.push_back(sample);
|
||||||
|
|
||||||
spv::Id resultTypeId = builder.makePointer(spv::StorageClassImage, resultType());
|
spv::Id resultTypeId;
|
||||||
|
// imageAtomicStore has a void return type so base the pointer type on
|
||||||
|
// the type of the value operand.
|
||||||
|
if (node->getOp() == glslang::EOpImageAtomicStore) {
|
||||||
|
resultTypeId = builder.makePointer(spv::StorageClassImage, builder.getTypeId(operands[2].word));
|
||||||
|
} else {
|
||||||
|
resultTypeId = builder.makePointer(spv::StorageClassImage, resultType());
|
||||||
|
}
|
||||||
spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, operands);
|
spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, operands);
|
||||||
|
|
||||||
std::vector<spv::Id> operands;
|
std::vector<spv::Id> operands;
|
||||||
@ -3972,6 +4176,16 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// nonprivate
|
||||||
|
if (imageType.getQualifier().nonprivate) {
|
||||||
|
params.nonprivate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// volatile
|
||||||
|
if (imageType.getQualifier().volatil) {
|
||||||
|
params.volatil = true;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<spv::Id> result( 1,
|
std::vector<spv::Id> result( 1,
|
||||||
builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params)
|
builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params)
|
||||||
);
|
);
|
||||||
@ -5340,8 +5554,14 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
|
|||||||
opCode = spv::OpAtomicIDecrement;
|
opCode = spv::OpAtomicIDecrement;
|
||||||
break;
|
break;
|
||||||
case glslang::EOpAtomicCounter:
|
case glslang::EOpAtomicCounter:
|
||||||
|
case glslang::EOpImageAtomicLoad:
|
||||||
|
case glslang::EOpAtomicLoad:
|
||||||
opCode = spv::OpAtomicLoad;
|
opCode = spv::OpAtomicLoad;
|
||||||
break;
|
break;
|
||||||
|
case glslang::EOpAtomicStore:
|
||||||
|
case glslang::EOpImageAtomicStore:
|
||||||
|
opCode = spv::OpAtomicStore;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
@ -5352,28 +5572,73 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
|
|||||||
|
|
||||||
// Sort out the operands
|
// Sort out the operands
|
||||||
// - mapping from glslang -> SPV
|
// - mapping from glslang -> SPV
|
||||||
// - there are extra SPV operands with no glslang source
|
// - there are extra SPV operands that are optional in glslang
|
||||||
// - compare-exchange swaps the value and comparator
|
// - compare-exchange swaps the value and comparator
|
||||||
// - compare-exchange has an extra memory semantics
|
// - compare-exchange has an extra memory semantics
|
||||||
// - EOpAtomicCounterDecrement needs a post decrement
|
// - EOpAtomicCounterDecrement needs a post decrement
|
||||||
std::vector<spv::Id> spvAtomicOperands; // hold the spv operands
|
spv::Id pointerId = 0, compareId = 0, valueId = 0;
|
||||||
auto opIt = operands.begin(); // walk the glslang operands
|
// scope defaults to Device in the old model, QueueFamilyKHR in the new model
|
||||||
spvAtomicOperands.push_back(*(opIt++));
|
spv::Id scopeId;
|
||||||
spvAtomicOperands.push_back(builder.makeUintConstant(spv::ScopeDevice)); // TBD: what is the correct scope?
|
if (glslangIntermediate->usingVulkanMemoryModel()) {
|
||||||
spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone)); // TBD: what are the correct memory semantics?
|
scopeId = builder.makeUintConstant(spv::ScopeQueueFamilyKHR);
|
||||||
if (opCode == spv::OpAtomicCompareExchange) {
|
} else {
|
||||||
// There are 2 memory semantics for compare-exchange. And the operand order of "comparator" and "new value" in GLSL
|
scopeId = builder.makeUintConstant(spv::ScopeDevice);
|
||||||
// differs from that in SPIR-V. Hence, special processing is required.
|
}
|
||||||
spvAtomicOperands.push_back(builder.makeUintConstant(spv::MemorySemanticsMaskNone));
|
// semantics default to relaxed
|
||||||
spvAtomicOperands.push_back(*(opIt + 1));
|
spv::Id semanticsId = builder.makeUintConstant(spv::MemorySemanticsMaskNone);
|
||||||
spvAtomicOperands.push_back(*opIt);
|
spv::Id semanticsId2 = semanticsId;
|
||||||
opIt += 2;
|
|
||||||
|
pointerId = operands[0];
|
||||||
|
if (opCode == spv::OpAtomicIIncrement || opCode == spv::OpAtomicIDecrement) {
|
||||||
|
// no additional operands
|
||||||
|
} else if (opCode == spv::OpAtomicCompareExchange) {
|
||||||
|
compareId = operands[1];
|
||||||
|
valueId = operands[2];
|
||||||
|
if (operands.size() > 3) {
|
||||||
|
scopeId = operands[3];
|
||||||
|
semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[4]) | builder.getConstantScalar(operands[5]));
|
||||||
|
semanticsId2 = builder.makeUintConstant(builder.getConstantScalar(operands[6]) | builder.getConstantScalar(operands[7]));
|
||||||
|
}
|
||||||
|
} else if (opCode == spv::OpAtomicLoad) {
|
||||||
|
if (operands.size() > 1) {
|
||||||
|
scopeId = operands[1];
|
||||||
|
semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// atomic store or RMW
|
||||||
|
valueId = operands[1];
|
||||||
|
if (operands.size() > 2) {
|
||||||
|
scopeId = operands[2];
|
||||||
|
semanticsId = builder.makeUintConstant(builder.getConstantScalar(operands[3]) | builder.getConstantScalar(operands[4]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the rest of the operands, skipping any that were dealt with above.
|
// Check for capabilities
|
||||||
for (; opIt != operands.end(); ++opIt)
|
unsigned semanticsImmediate = builder.getConstantScalar(semanticsId) | builder.getConstantScalar(semanticsId2);
|
||||||
spvAtomicOperands.push_back(*opIt);
|
if (semanticsImmediate & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) {
|
||||||
|
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (glslangIntermediate->usingVulkanMemoryModel() && builder.getConstantScalar(scopeId) == spv::ScopeDevice) {
|
||||||
|
builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<spv::Id> spvAtomicOperands; // hold the spv operands
|
||||||
|
spvAtomicOperands.push_back(pointerId);
|
||||||
|
spvAtomicOperands.push_back(scopeId);
|
||||||
|
spvAtomicOperands.push_back(semanticsId);
|
||||||
|
if (opCode == spv::OpAtomicCompareExchange) {
|
||||||
|
spvAtomicOperands.push_back(semanticsId2);
|
||||||
|
spvAtomicOperands.push_back(valueId);
|
||||||
|
spvAtomicOperands.push_back(compareId);
|
||||||
|
} else if (opCode != spv::OpAtomicLoad && opCode != spv::OpAtomicIIncrement && opCode != spv::OpAtomicIDecrement) {
|
||||||
|
spvAtomicOperands.push_back(valueId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (opCode == spv::OpAtomicStore) {
|
||||||
|
builder.createNoResultOp(opCode, spvAtomicOperands);
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
spv::Id resultId = builder.createOp(opCode, typeId, spvAtomicOperands);
|
spv::Id resultId = builder.createOp(opCode, typeId, spvAtomicOperands);
|
||||||
|
|
||||||
// GLSL and HLSL atomic-counter decrement return post-decrement value,
|
// GLSL and HLSL atomic-counter decrement return post-decrement value,
|
||||||
@ -5383,6 +5648,7 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
|
|||||||
|
|
||||||
return resultId;
|
return resultId;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create group invocation operations.
|
// Create group invocation operations.
|
||||||
spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
|
spv::Id TGlslangToSpvTraverser::createInvocationsOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
|
||||||
@ -6282,7 +6548,41 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
|
|||||||
libCall = spv::InterpolateAtVertexAMD;
|
libCall = spv::InterpolateAtVertexAMD;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case glslang::EOpBarrier:
|
||||||
|
{
|
||||||
|
// This is for the extended controlBarrier function, with four operands.
|
||||||
|
// The unextended barrier() goes through createNoArgOperation.
|
||||||
|
assert(operands.size() == 4);
|
||||||
|
unsigned int executionScope = builder.getConstantScalar(operands[0]);
|
||||||
|
unsigned int memoryScope = builder.getConstantScalar(operands[1]);
|
||||||
|
unsigned int semantics = builder.getConstantScalar(operands[2]) | builder.getConstantScalar(operands[3]);
|
||||||
|
builder.createControlBarrier((spv::Scope)executionScope, (spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics);
|
||||||
|
if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) {
|
||||||
|
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
|
||||||
|
}
|
||||||
|
if (glslangIntermediate->usingVulkanMemoryModel() && (executionScope == spv::ScopeDevice || memoryScope == spv::ScopeDevice)) {
|
||||||
|
builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case glslang::EOpMemoryBarrier:
|
||||||
|
{
|
||||||
|
// This is for the extended memoryBarrier function, with three operands.
|
||||||
|
// The unextended memoryBarrier() goes through createNoArgOperation.
|
||||||
|
assert(operands.size() == 3);
|
||||||
|
unsigned int memoryScope = builder.getConstantScalar(operands[0]);
|
||||||
|
unsigned int semantics = builder.getConstantScalar(operands[1]) | builder.getConstantScalar(operands[2]);
|
||||||
|
builder.createMemoryBarrier((spv::Scope)memoryScope, (spv::MemorySemanticsMask)semantics);
|
||||||
|
if (semantics & (spv::MemorySemanticsMakeAvailableKHRMask | spv::MemorySemanticsMakeVisibleKHRMask | spv::MemorySemanticsOutputMemoryKHRMask)) {
|
||||||
|
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
|
||||||
|
}
|
||||||
|
if (glslangIntermediate->usingVulkanMemoryModel() && memoryScope == spv::ScopeDevice) {
|
||||||
|
builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -6351,7 +6651,8 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
|
|||||||
// Intrinsics with no arguments (or no return value, and no precision).
|
// Intrinsics with no arguments (or no return value, and no precision).
|
||||||
spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId)
|
spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId)
|
||||||
{
|
{
|
||||||
// TODO: get the barrier operands correct
|
// GLSL memory barriers use queuefamily scope in new model, device scope in old model
|
||||||
|
spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case glslang::EOpEmitVertex:
|
case glslang::EOpEmitVertex:
|
||||||
@ -6362,11 +6663,14 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv:
|
|||||||
return 0;
|
return 0;
|
||||||
case glslang::EOpBarrier:
|
case glslang::EOpBarrier:
|
||||||
if (glslangIntermediate->getStage() == EShLangTessControl) {
|
if (glslangIntermediate->getStage() == EShLangTessControl) {
|
||||||
|
if (glslangIntermediate->usingVulkanMemoryModel()) {
|
||||||
|
builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup,
|
||||||
|
spv::MemorySemanticsOutputMemoryKHRMask |
|
||||||
|
spv::MemorySemanticsAcquireReleaseMask);
|
||||||
|
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
|
||||||
|
} else {
|
||||||
builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeInvocation, spv::MemorySemanticsMaskNone);
|
builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeInvocation, spv::MemorySemanticsMaskNone);
|
||||||
// TODO: prefer the following, when available:
|
}
|
||||||
// builder.createControlBarrier(spv::ScopePatch, spv::ScopePatch,
|
|
||||||
// spv::MemorySemanticsPatchMask |
|
|
||||||
// spv::MemorySemanticsAcquireReleaseMask);
|
|
||||||
} else {
|
} else {
|
||||||
builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup,
|
builder.createControlBarrier(spv::ScopeWorkgroup, spv::ScopeWorkgroup,
|
||||||
spv::MemorySemanticsWorkgroupMemoryMask |
|
spv::MemorySemanticsWorkgroupMemoryMask |
|
||||||
@ -6374,23 +6678,23 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv:
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case glslang::EOpMemoryBarrier:
|
case glslang::EOpMemoryBarrier:
|
||||||
builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAllMemory |
|
builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAllMemory |
|
||||||
spv::MemorySemanticsAcquireReleaseMask);
|
spv::MemorySemanticsAcquireReleaseMask);
|
||||||
return 0;
|
return 0;
|
||||||
case glslang::EOpMemoryBarrierAtomicCounter:
|
case glslang::EOpMemoryBarrierAtomicCounter:
|
||||||
builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsAtomicCounterMemoryMask |
|
builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAtomicCounterMemoryMask |
|
||||||
spv::MemorySemanticsAcquireReleaseMask);
|
spv::MemorySemanticsAcquireReleaseMask);
|
||||||
return 0;
|
return 0;
|
||||||
case glslang::EOpMemoryBarrierBuffer:
|
case glslang::EOpMemoryBarrierBuffer:
|
||||||
builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsUniformMemoryMask |
|
builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsUniformMemoryMask |
|
||||||
spv::MemorySemanticsAcquireReleaseMask);
|
spv::MemorySemanticsAcquireReleaseMask);
|
||||||
return 0;
|
return 0;
|
||||||
case glslang::EOpMemoryBarrierImage:
|
case glslang::EOpMemoryBarrierImage:
|
||||||
builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsImageMemoryMask |
|
builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsImageMemoryMask |
|
||||||
spv::MemorySemanticsAcquireReleaseMask);
|
spv::MemorySemanticsAcquireReleaseMask);
|
||||||
return 0;
|
return 0;
|
||||||
case glslang::EOpMemoryBarrierShared:
|
case glslang::EOpMemoryBarrierShared:
|
||||||
builder.createMemoryBarrier(spv::ScopeDevice, spv::MemorySemanticsWorkgroupMemoryMask |
|
builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsWorkgroupMemoryMask |
|
||||||
spv::MemorySemanticsAcquireReleaseMask);
|
spv::MemorySemanticsAcquireReleaseMask);
|
||||||
return 0;
|
return 0;
|
||||||
case glslang::EOpGroupMemoryBarrier:
|
case glslang::EOpGroupMemoryBarrier:
|
||||||
@ -6520,7 +6824,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|||||||
|
|
||||||
if (symbol->getType().isImage()) {
|
if (symbol->getType().isImage()) {
|
||||||
std::vector<spv::Decoration> memory;
|
std::vector<spv::Decoration> memory;
|
||||||
TranslateMemoryDecoration(symbol->getType().getQualifier(), memory);
|
TranslateMemoryDecoration(symbol->getType().getQualifier(), memory, glslangIntermediate->usingVulkanMemoryModel());
|
||||||
for (unsigned int i = 0; i < memory.size(); ++i)
|
for (unsigned int i = 0; i < memory.size(); ++i)
|
||||||
builder.addDecoration(id, memory[i]);
|
builder.addDecoration(id, memory[i]);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1216,19 +1216,35 @@ Id Builder::createUndefined(Id type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
void Builder::createStore(Id rValue, Id lValue)
|
void Builder::createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope)
|
||||||
{
|
{
|
||||||
Instruction* store = new Instruction(OpStore);
|
Instruction* store = new Instruction(OpStore);
|
||||||
store->addIdOperand(lValue);
|
store->addIdOperand(lValue);
|
||||||
store->addIdOperand(rValue);
|
store->addIdOperand(rValue);
|
||||||
|
|
||||||
|
if (memoryAccess != MemoryAccessMaskNone) {
|
||||||
|
store->addImmediateOperand(memoryAccess);
|
||||||
|
if (memoryAccess & spv::MemoryAccessMakePointerAvailableKHRMask) {
|
||||||
|
store->addIdOperand(makeUintConstant(scope));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(store));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(store));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Id Builder::createLoad(Id lValue)
|
Id Builder::createLoad(Id lValue, spv::MemoryAccessMask memoryAccess, spv::Scope scope)
|
||||||
{
|
{
|
||||||
Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
|
Instruction* load = new Instruction(getUniqueId(), getDerefTypeId(lValue), OpLoad);
|
||||||
load->addIdOperand(lValue);
|
load->addIdOperand(lValue);
|
||||||
|
|
||||||
|
if (memoryAccess != MemoryAccessMaskNone) {
|
||||||
|
load->addImmediateOperand(memoryAccess);
|
||||||
|
if (memoryAccess & spv::MemoryAccessMakePointerVisibleKHRMask) {
|
||||||
|
load->addIdOperand(makeUintConstant(scope));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(load));
|
||||||
|
|
||||||
return load->getResultId();
|
return load->getResultId();
|
||||||
@ -1361,6 +1377,16 @@ void Builder::createNoResultOp(Op opCode, Id operand)
|
|||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// An opcode that has multiple operands, no result id, and no type
|
||||||
|
void Builder::createNoResultOp(Op opCode, const std::vector<Id>& operands)
|
||||||
|
{
|
||||||
|
Instruction* op = new Instruction(opCode);
|
||||||
|
for (auto it = operands.cbegin(); it != operands.cend(); ++it) {
|
||||||
|
op->addIdOperand(*it);
|
||||||
|
}
|
||||||
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(op));
|
||||||
|
}
|
||||||
|
|
||||||
// An opcode that has multiple operands, no result id, and no type
|
// An opcode that has multiple operands, no result id, and no type
|
||||||
void Builder::createNoResultOp(Op opCode, const std::vector<IdImmediate>& operands)
|
void Builder::createNoResultOp(Op opCode, const std::vector<IdImmediate>& operands)
|
||||||
{
|
{
|
||||||
@ -1679,6 +1705,12 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
|||||||
mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask);
|
mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask);
|
||||||
texArgs[numArgs++] = parameters.lodClamp;
|
texArgs[numArgs++] = parameters.lodClamp;
|
||||||
}
|
}
|
||||||
|
if (parameters.nonprivate) {
|
||||||
|
mask = mask | ImageOperandsNonPrivateTexelKHRMask;
|
||||||
|
}
|
||||||
|
if (parameters.volatil) {
|
||||||
|
mask = mask | ImageOperandsVolatileTexelKHRMask;
|
||||||
|
}
|
||||||
if (mask == ImageOperandsMaskNone)
|
if (mask == ImageOperandsMaskNone)
|
||||||
--numArgs; // undo speculative reservation for the mask argument
|
--numArgs; // undo speculative reservation for the mask argument
|
||||||
else
|
else
|
||||||
@ -2352,6 +2384,7 @@ void Builder::clearAccessChain()
|
|||||||
accessChain.component = NoResult;
|
accessChain.component = NoResult;
|
||||||
accessChain.preSwizzleBaseType = NoType;
|
accessChain.preSwizzleBaseType = NoType;
|
||||||
accessChain.isRValue = false;
|
accessChain.isRValue = false;
|
||||||
|
accessChain.coherentFlags.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
@ -2378,7 +2411,7 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
void Builder::accessChainStore(Id rvalue)
|
void Builder::accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess, spv::Scope scope)
|
||||||
{
|
{
|
||||||
assert(accessChain.isRValue == false);
|
assert(accessChain.isRValue == false);
|
||||||
|
|
||||||
@ -2396,11 +2429,11 @@ void Builder::accessChainStore(Id rvalue)
|
|||||||
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
|
source = createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, source, accessChain.swizzle);
|
||||||
}
|
}
|
||||||
|
|
||||||
createStore(source, base);
|
createStore(source, base, memoryAccess, scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Comments in header
|
// Comments in header
|
||||||
Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType)
|
Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resultType, spv::MemoryAccessMask memoryAccess, spv::Scope scope)
|
||||||
{
|
{
|
||||||
Id id;
|
Id id;
|
||||||
|
|
||||||
@ -2444,7 +2477,7 @@ Id Builder::accessChainLoad(Decoration precision, Decoration nonUniform, Id resu
|
|||||||
} else {
|
} else {
|
||||||
transferAccessChainSwizzle(true);
|
transferAccessChainSwizzle(true);
|
||||||
// load through the access chain
|
// load through the access chain
|
||||||
id = createLoad(collapseAccessChain());
|
id = createLoad(collapseAccessChain(), memoryAccess, scope);
|
||||||
setPrecision(id, precision);
|
setPrecision(id, precision);
|
||||||
addDecoration(id, nonUniform);
|
addDecoration(id, nonUniform);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -274,10 +274,10 @@ public:
|
|||||||
Id createUndefined(Id type);
|
Id createUndefined(Id type);
|
||||||
|
|
||||||
// Store into an Id and return the l-value
|
// Store into an Id and return the l-value
|
||||||
void createStore(Id rValue, Id lValue);
|
void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax);
|
||||||
|
|
||||||
// Load from an Id and return it
|
// Load from an Id and return it
|
||||||
Id createLoad(Id lValue);
|
Id createLoad(Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax);
|
||||||
|
|
||||||
// Create an OpAccessChain instruction
|
// Create an OpAccessChain instruction
|
||||||
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
|
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
|
||||||
@ -296,6 +296,7 @@ public:
|
|||||||
|
|
||||||
void createNoResultOp(Op);
|
void createNoResultOp(Op);
|
||||||
void createNoResultOp(Op, Id operand);
|
void createNoResultOp(Op, Id operand);
|
||||||
|
void createNoResultOp(Op, const std::vector<Id>& operands);
|
||||||
void createNoResultOp(Op, const std::vector<IdImmediate>& operands);
|
void createNoResultOp(Op, const std::vector<IdImmediate>& operands);
|
||||||
void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask);
|
void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask);
|
||||||
void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
|
void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
|
||||||
@ -365,6 +366,8 @@ public:
|
|||||||
Id component;
|
Id component;
|
||||||
Id texelOut;
|
Id texelOut;
|
||||||
Id lodClamp;
|
Id lodClamp;
|
||||||
|
bool nonprivate;
|
||||||
|
bool volatil;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Select the correct texture operation based on all inputs, and emit the correct instruction
|
// Select the correct texture operation based on all inputs, and emit the correct instruction
|
||||||
@ -504,6 +507,43 @@ public:
|
|||||||
Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present
|
Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present
|
||||||
Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
|
Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
|
||||||
bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value
|
bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value
|
||||||
|
|
||||||
|
// Accumulate whether anything in the chain of structures has coherent decorations.
|
||||||
|
struct CoherentFlags {
|
||||||
|
unsigned coherent : 1;
|
||||||
|
unsigned devicecoherent : 1;
|
||||||
|
unsigned queuefamilycoherent : 1;
|
||||||
|
unsigned workgroupcoherent : 1;
|
||||||
|
unsigned subgroupcoherent : 1;
|
||||||
|
unsigned nonprivate : 1;
|
||||||
|
unsigned volatil : 1;
|
||||||
|
unsigned isImage : 1;
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
coherent = 0;
|
||||||
|
devicecoherent = 0;
|
||||||
|
queuefamilycoherent = 0;
|
||||||
|
workgroupcoherent = 0;
|
||||||
|
subgroupcoherent = 0;
|
||||||
|
nonprivate = 0;
|
||||||
|
volatil = 0;
|
||||||
|
isImage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoherentFlags() { clear(); }
|
||||||
|
CoherentFlags operator |=(const CoherentFlags &other) {
|
||||||
|
coherent |= other.coherent;
|
||||||
|
devicecoherent |= other.devicecoherent;
|
||||||
|
queuefamilycoherent |= other.queuefamilycoherent;
|
||||||
|
workgroupcoherent |= other.workgroupcoherent;
|
||||||
|
subgroupcoherent |= other.subgroupcoherent;
|
||||||
|
nonprivate |= other.nonprivate;
|
||||||
|
volatil |= other.volatil;
|
||||||
|
isImage |= other.isImage;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
CoherentFlags coherentFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -533,9 +573,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// push offset onto the end of the chain
|
// push offset onto the end of the chain
|
||||||
void accessChainPush(Id offset)
|
void accessChainPush(Id offset, AccessChain::CoherentFlags coherentFlags)
|
||||||
{
|
{
|
||||||
accessChain.indexChain.push_back(offset);
|
accessChain.indexChain.push_back(offset);
|
||||||
|
accessChain.coherentFlags |= coherentFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
||||||
@ -553,10 +594,10 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// use accessChain and swizzle to store value
|
// use accessChain and swizzle to store value
|
||||||
void accessChainStore(Id rvalue);
|
void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax);
|
||||||
|
|
||||||
// use accessChain and swizzle to load an r-value
|
// use accessChain and swizzle to load an r-value
|
||||||
Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType);
|
Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax);
|
||||||
|
|
||||||
// get the direct pointer for an l-value
|
// get the direct pointer for an l-value
|
||||||
Id accessChainGetLValue();
|
Id accessChainGetLValue();
|
||||||
|
|||||||
@ -535,6 +535,11 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
|||||||
case OperandLiteralString:
|
case OperandLiteralString:
|
||||||
numOperands -= disassembleString();
|
numOperands -= disassembleString();
|
||||||
break;
|
break;
|
||||||
|
case OperandMemoryAccess:
|
||||||
|
outputMask(OperandMemoryAccess, stream[word++]);
|
||||||
|
--numOperands;
|
||||||
|
disassembleIds(numOperands);
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
assert(operandClass >= OperandSource && operandClass < OperandOpcode);
|
assert(operandClass >= OperandSource && operandClass < OperandOpcode);
|
||||||
|
|
||||||
|
|||||||
@ -117,9 +117,10 @@ const char* AddressingString(int addr)
|
|||||||
const char* MemoryString(int mem)
|
const char* MemoryString(int mem)
|
||||||
{
|
{
|
||||||
switch (mem) {
|
switch (mem) {
|
||||||
case 0: return "Simple";
|
case MemoryModelSimple: return "Simple";
|
||||||
case 1: return "GLSL450";
|
case MemoryModelGLSL450: return "GLSL450";
|
||||||
case 2: return "OpenCL";
|
case MemoryModelOpenCL: return "OpenCL";
|
||||||
|
case MemoryModelVulkanKHR: return "VulkanKHR";
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
@ -499,19 +500,23 @@ const char* ImageChannelDataTypeString(int type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const int ImageOperandsCeiling = 8;
|
const int ImageOperandsCeiling = 12;
|
||||||
|
|
||||||
const char* ImageOperandsString(int format)
|
const char* ImageOperandsString(int format)
|
||||||
{
|
{
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case 0: return "Bias";
|
case ImageOperandsBiasShift: return "Bias";
|
||||||
case 1: return "Lod";
|
case ImageOperandsLodShift: return "Lod";
|
||||||
case 2: return "Grad";
|
case ImageOperandsGradShift: return "Grad";
|
||||||
case 3: return "ConstOffset";
|
case ImageOperandsConstOffsetShift: return "ConstOffset";
|
||||||
case 4: return "Offset";
|
case ImageOperandsOffsetShift: return "Offset";
|
||||||
case 5: return "ConstOffsets";
|
case ImageOperandsConstOffsetsShift: return "ConstOffsets";
|
||||||
case 6: return "Sample";
|
case ImageOperandsSampleShift: return "Sample";
|
||||||
case 7: return "MinLod";
|
case ImageOperandsMinLodShift: return "MinLod";
|
||||||
|
case ImageOperandsMakeTexelAvailableKHRShift: return "MakeTexelAvailableKHR";
|
||||||
|
case ImageOperandsMakeTexelVisibleKHRShift: return "MakeTexelVisibleKHR";
|
||||||
|
case ImageOperandsNonPrivateTexelKHRShift: return "NonPrivateTexelKHR";
|
||||||
|
case ImageOperandsVolatileTexelKHRShift: return "VolatileTexelKHR";
|
||||||
|
|
||||||
case ImageOperandsCeiling:
|
case ImageOperandsCeiling:
|
||||||
default:
|
default:
|
||||||
@ -645,12 +650,17 @@ const char* MemorySemanticsString(int mem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const int MemoryAccessCeiling = 6;
|
||||||
|
|
||||||
const char* MemoryAccessString(int mem)
|
const char* MemoryAccessString(int mem)
|
||||||
{
|
{
|
||||||
switch (mem) {
|
switch (mem) {
|
||||||
case 0: return "Volatile";
|
case MemoryAccessVolatileShift: return "Volatile";
|
||||||
case 1: return "Aligned";
|
case MemoryAccessAlignedShift: return "Aligned";
|
||||||
case 2: return "Nontemporal";
|
case MemoryAccessNontemporalShift: return "Nontemporal";
|
||||||
|
case MemoryAccessMakePointerAvailableKHRShift: return "MakePointerAvailableKHR";
|
||||||
|
case MemoryAccessMakePointerVisibleKHRShift: return "MakePointerVisibleKHR";
|
||||||
|
case MemoryAccessNonPrivatePointerKHRShift: return "NonPrivatePointerKHR";
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
@ -833,6 +843,9 @@ const char* CapabilityString(int info)
|
|||||||
case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "CapabilityUniformTexelBufferArrayNonUniformIndexingEXT";
|
case CapabilityUniformTexelBufferArrayNonUniformIndexingEXT: return "CapabilityUniformTexelBufferArrayNonUniformIndexingEXT";
|
||||||
case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "CapabilityStorageTexelBufferArrayNonUniformIndexingEXT";
|
case CapabilityStorageTexelBufferArrayNonUniformIndexingEXT: return "CapabilityStorageTexelBufferArrayNonUniformIndexingEXT";
|
||||||
|
|
||||||
|
case CapabilityVulkanMemoryModelKHR: return "CapabilityVulkanMemoryModelKHR";
|
||||||
|
case CapabilityVulkanMemoryModelDeviceScopeKHR: return "CapabilityVulkanMemoryModelDeviceScopeKHR";
|
||||||
|
|
||||||
default: return "Bad";
|
default: return "Bad";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1245,6 +1258,7 @@ EnumParameters DecorationParams[DecorationCeiling];
|
|||||||
EnumParameters LoopControlParams[FunctionControlCeiling];
|
EnumParameters LoopControlParams[FunctionControlCeiling];
|
||||||
EnumParameters SelectionControlParams[SelectControlCeiling];
|
EnumParameters SelectionControlParams[SelectControlCeiling];
|
||||||
EnumParameters FunctionControlParams[FunctionControlCeiling];
|
EnumParameters FunctionControlParams[FunctionControlCeiling];
|
||||||
|
EnumParameters MemoryAccessParams[MemoryAccessCeiling];
|
||||||
|
|
||||||
// Set up all the parameterizing descriptions of the opcodes, operands, etc.
|
// Set up all the parameterizing descriptions of the opcodes, operands, etc.
|
||||||
void Parameterize()
|
void Parameterize()
|
||||||
@ -1400,7 +1414,7 @@ void Parameterize()
|
|||||||
OperandClassParams[OperandLoop].set(LoopControlCeiling, LoopControlString, LoopControlParams, true);
|
OperandClassParams[OperandLoop].set(LoopControlCeiling, LoopControlString, LoopControlParams, true);
|
||||||
OperandClassParams[OperandFunction].set(FunctionControlCeiling, FunctionControlString, FunctionControlParams, true);
|
OperandClassParams[OperandFunction].set(FunctionControlCeiling, FunctionControlString, FunctionControlParams, true);
|
||||||
OperandClassParams[OperandMemorySemantics].set(0, MemorySemanticsString, nullptr, true);
|
OperandClassParams[OperandMemorySemantics].set(0, MemorySemanticsString, nullptr, true);
|
||||||
OperandClassParams[OperandMemoryAccess].set(0, MemoryAccessString, nullptr, true);
|
OperandClassParams[OperandMemoryAccess].set(MemoryAccessCeiling, MemoryAccessString, MemoryAccessParams, true);
|
||||||
OperandClassParams[OperandScope].set(0, ScopeString, nullptr);
|
OperandClassParams[OperandScope].set(0, ScopeString, nullptr);
|
||||||
OperandClassParams[OperandGroupOperation].set(0, GroupOperationString, nullptr);
|
OperandClassParams[OperandGroupOperation].set(0, GroupOperationString, nullptr);
|
||||||
OperandClassParams[OperandKernelEnqueueFlags].set(0, KernelEnqueueFlagsString, nullptr);
|
OperandClassParams[OperandKernelEnqueueFlags].set(0, KernelEnqueueFlagsString, nullptr);
|
||||||
@ -1522,10 +1536,14 @@ void Parameterize()
|
|||||||
|
|
||||||
InstructionDesc[OpLoad].operands.push(OperandId, "'Pointer'");
|
InstructionDesc[OpLoad].operands.push(OperandId, "'Pointer'");
|
||||||
InstructionDesc[OpLoad].operands.push(OperandMemoryAccess, "", true);
|
InstructionDesc[OpLoad].operands.push(OperandMemoryAccess, "", true);
|
||||||
|
InstructionDesc[OpLoad].operands.push(OperandLiteralNumber, "", true);
|
||||||
|
InstructionDesc[OpLoad].operands.push(OperandId, "", true);
|
||||||
|
|
||||||
InstructionDesc[OpStore].operands.push(OperandId, "'Pointer'");
|
InstructionDesc[OpStore].operands.push(OperandId, "'Pointer'");
|
||||||
InstructionDesc[OpStore].operands.push(OperandId, "'Object'");
|
InstructionDesc[OpStore].operands.push(OperandId, "'Object'");
|
||||||
InstructionDesc[OpStore].operands.push(OperandMemoryAccess, "", true);
|
InstructionDesc[OpStore].operands.push(OperandMemoryAccess, "", true);
|
||||||
|
InstructionDesc[OpStore].operands.push(OperandLiteralNumber, "", true);
|
||||||
|
InstructionDesc[OpStore].operands.push(OperandId, "", true);
|
||||||
|
|
||||||
InstructionDesc[OpPhi].operands.push(OperandVariableIds, "'Variable, Parent, ...'");
|
InstructionDesc[OpPhi].operands.push(OperandVariableIds, "'Variable, Parent, ...'");
|
||||||
|
|
||||||
|
|||||||
@ -87,6 +87,7 @@ enum MemoryModel {
|
|||||||
MemoryModelSimple = 0,
|
MemoryModelSimple = 0,
|
||||||
MemoryModelGLSL450 = 1,
|
MemoryModelGLSL450 = 1,
|
||||||
MemoryModelOpenCL = 2,
|
MemoryModelOpenCL = 2,
|
||||||
|
MemoryModelVulkanKHR = 3,
|
||||||
MemoryModelMax = 0x7fffffff,
|
MemoryModelMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -275,6 +276,10 @@ enum ImageOperandsShift {
|
|||||||
ImageOperandsConstOffsetsShift = 5,
|
ImageOperandsConstOffsetsShift = 5,
|
||||||
ImageOperandsSampleShift = 6,
|
ImageOperandsSampleShift = 6,
|
||||||
ImageOperandsMinLodShift = 7,
|
ImageOperandsMinLodShift = 7,
|
||||||
|
ImageOperandsMakeTexelAvailableKHRShift = 8,
|
||||||
|
ImageOperandsMakeTexelVisibleKHRShift = 9,
|
||||||
|
ImageOperandsNonPrivateTexelKHRShift = 10,
|
||||||
|
ImageOperandsVolatileTexelKHRShift = 11,
|
||||||
ImageOperandsMax = 0x7fffffff,
|
ImageOperandsMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -288,6 +293,10 @@ enum ImageOperandsMask {
|
|||||||
ImageOperandsConstOffsetsMask = 0x00000020,
|
ImageOperandsConstOffsetsMask = 0x00000020,
|
||||||
ImageOperandsSampleMask = 0x00000040,
|
ImageOperandsSampleMask = 0x00000040,
|
||||||
ImageOperandsMinLodMask = 0x00000080,
|
ImageOperandsMinLodMask = 0x00000080,
|
||||||
|
ImageOperandsMakeTexelAvailableKHRMask = 0x00000100,
|
||||||
|
ImageOperandsMakeTexelVisibleKHRMask = 0x00000200,
|
||||||
|
ImageOperandsNonPrivateTexelKHRMask = 0x00000400,
|
||||||
|
ImageOperandsVolatileTexelKHRMask = 0x00000800,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum FPFastMathModeShift {
|
enum FPFastMathModeShift {
|
||||||
@ -528,6 +537,9 @@ enum MemorySemanticsShift {
|
|||||||
MemorySemanticsCrossWorkgroupMemoryShift = 9,
|
MemorySemanticsCrossWorkgroupMemoryShift = 9,
|
||||||
MemorySemanticsAtomicCounterMemoryShift = 10,
|
MemorySemanticsAtomicCounterMemoryShift = 10,
|
||||||
MemorySemanticsImageMemoryShift = 11,
|
MemorySemanticsImageMemoryShift = 11,
|
||||||
|
MemorySemanticsOutputMemoryKHRShift = 12,
|
||||||
|
MemorySemanticsMakeAvailableKHRShift = 13,
|
||||||
|
MemorySemanticsMakeVisibleKHRShift = 14,
|
||||||
MemorySemanticsMax = 0x7fffffff,
|
MemorySemanticsMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -543,12 +555,18 @@ enum MemorySemanticsMask {
|
|||||||
MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200,
|
MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200,
|
||||||
MemorySemanticsAtomicCounterMemoryMask = 0x00000400,
|
MemorySemanticsAtomicCounterMemoryMask = 0x00000400,
|
||||||
MemorySemanticsImageMemoryMask = 0x00000800,
|
MemorySemanticsImageMemoryMask = 0x00000800,
|
||||||
|
MemorySemanticsOutputMemoryKHRMask = 0x00001000,
|
||||||
|
MemorySemanticsMakeAvailableKHRMask = 0x00002000,
|
||||||
|
MemorySemanticsMakeVisibleKHRMask = 0x00004000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum MemoryAccessShift {
|
enum MemoryAccessShift {
|
||||||
MemoryAccessVolatileShift = 0,
|
MemoryAccessVolatileShift = 0,
|
||||||
MemoryAccessAlignedShift = 1,
|
MemoryAccessAlignedShift = 1,
|
||||||
MemoryAccessNontemporalShift = 2,
|
MemoryAccessNontemporalShift = 2,
|
||||||
|
MemoryAccessMakePointerAvailableKHRShift = 3,
|
||||||
|
MemoryAccessMakePointerVisibleKHRShift = 4,
|
||||||
|
MemoryAccessNonPrivatePointerKHRShift = 5,
|
||||||
MemoryAccessMax = 0x7fffffff,
|
MemoryAccessMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -557,6 +575,9 @@ enum MemoryAccessMask {
|
|||||||
MemoryAccessVolatileMask = 0x00000001,
|
MemoryAccessVolatileMask = 0x00000001,
|
||||||
MemoryAccessAlignedMask = 0x00000002,
|
MemoryAccessAlignedMask = 0x00000002,
|
||||||
MemoryAccessNontemporalMask = 0x00000004,
|
MemoryAccessNontemporalMask = 0x00000004,
|
||||||
|
MemoryAccessMakePointerAvailableKHRMask = 0x00000008,
|
||||||
|
MemoryAccessMakePointerVisibleKHRMask = 0x00000010,
|
||||||
|
MemoryAccessNonPrivatePointerKHRMask = 0x00000020,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Scope {
|
enum Scope {
|
||||||
@ -565,6 +586,7 @@ enum Scope {
|
|||||||
ScopeWorkgroup = 2,
|
ScopeWorkgroup = 2,
|
||||||
ScopeSubgroup = 3,
|
ScopeSubgroup = 3,
|
||||||
ScopeInvocation = 4,
|
ScopeInvocation = 4,
|
||||||
|
ScopeQueueFamilyKHR = 5,
|
||||||
ScopeMax = 0x7fffffff,
|
ScopeMax = 0x7fffffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -708,6 +730,8 @@ enum Capability {
|
|||||||
CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310,
|
CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310,
|
||||||
CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311,
|
CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311,
|
||||||
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
|
CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312,
|
||||||
|
CapabilityVulkanMemoryModelKHR = 5345,
|
||||||
|
CapabilityVulkanMemoryModelDeviceScopeKHR = 5346,
|
||||||
CapabilitySubgroupShuffleINTEL = 5568,
|
CapabilitySubgroupShuffleINTEL = 5568,
|
||||||
CapabilitySubgroupBufferBlockIOINTEL = 5569,
|
CapabilitySubgroupBufferBlockIOINTEL = 5569,
|
||||||
CapabilitySubgroupImageBlockIOINTEL = 5570,
|
CapabilitySubgroupImageBlockIOINTEL = 5570,
|
||||||
|
|||||||
243
Test/baseResults/spv.memoryScopeSemantics.comp.out
Normal file
243
Test/baseResults/spv.memoryScopeSemantics.comp.out
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
spv.memoryScopeSemantics.comp
|
||||||
|
error: SPIRV-Tools Validation Errors
|
||||||
|
error: Capability Int64Atomics is not allowed by Vulkan 1.0 specification (or requires extension)
|
||||||
|
OpCapability Int64Atomics
|
||||||
|
|
||||||
|
// Module Version 10000
|
||||||
|
// Generated by (magic number): 80007
|
||||||
|
// Id's are bound by 142
|
||||||
|
|
||||||
|
Capability Shader
|
||||||
|
Capability Int64
|
||||||
|
Capability Int64Atomics
|
||||||
|
Capability CapabilityVulkanMemoryModelKHR
|
||||||
|
Capability CapabilityVulkanMemoryModelDeviceScopeKHR
|
||||||
|
Extension "SPV_KHR_vulkan_memory_model"
|
||||||
|
1: ExtInstImport "GLSL.std.450"
|
||||||
|
MemoryModel Logical VulkanKHR
|
||||||
|
EntryPoint GLCompute 4 "main"
|
||||||
|
ExecutionMode 4 LocalSize 1 1 1
|
||||||
|
Source GLSL 450
|
||||||
|
SourceExtension "GL_ARB_gpu_shader_int64"
|
||||||
|
SourceExtension "GL_KHR_memory_scope_semantics"
|
||||||
|
Name 4 "main"
|
||||||
|
Name 8 "origi"
|
||||||
|
Name 10 "atomi"
|
||||||
|
Name 21 "origu"
|
||||||
|
Name 23 "atomu"
|
||||||
|
Name 24 "value"
|
||||||
|
Name 36 "imagei"
|
||||||
|
Name 45 "imageu"
|
||||||
|
Name 65 "BufferU"
|
||||||
|
MemberName 65(BufferU) 0 "x"
|
||||||
|
Name 67 "bufferu"
|
||||||
|
Name 72 "y"
|
||||||
|
Name 77 "BufferI"
|
||||||
|
MemberName 77(BufferI) 0 "x"
|
||||||
|
Name 79 "bufferi"
|
||||||
|
Name 83 "A"
|
||||||
|
MemberName 83(A) 0 "x"
|
||||||
|
Name 84 "BufferJ"
|
||||||
|
MemberName 84(BufferJ) 0 "a"
|
||||||
|
Name 87 "bufferj"
|
||||||
|
Name 98 "BufferK"
|
||||||
|
MemberName 98(BufferK) 0 "x"
|
||||||
|
Name 100 "bufferk"
|
||||||
|
Name 109 "imagej"
|
||||||
|
Name 121 "samp"
|
||||||
|
Name 132 "atomu64"
|
||||||
|
Name 137 "atomi64"
|
||||||
|
Decorate 36(imagei) DescriptorSet 0
|
||||||
|
Decorate 36(imagei) Binding 1
|
||||||
|
Decorate 45(imageu) DescriptorSet 0
|
||||||
|
Decorate 45(imageu) Binding 0
|
||||||
|
MemberDecorate 65(BufferU) 0 Offset 0
|
||||||
|
Decorate 65(BufferU) BufferBlock
|
||||||
|
Decorate 67(bufferu) DescriptorSet 0
|
||||||
|
Decorate 67(bufferu) Binding 2
|
||||||
|
MemberDecorate 77(BufferI) 0 Offset 0
|
||||||
|
Decorate 77(BufferI) BufferBlock
|
||||||
|
Decorate 79(bufferi) DescriptorSet 0
|
||||||
|
Decorate 79(bufferi) Binding 3
|
||||||
|
Decorate 82 ArrayStride 4
|
||||||
|
MemberDecorate 83(A) 0 Offset 0
|
||||||
|
MemberDecorate 84(BufferJ) 0 Offset 0
|
||||||
|
Decorate 84(BufferJ) BufferBlock
|
||||||
|
Decorate 87(bufferj) DescriptorSet 0
|
||||||
|
Decorate 87(bufferj) Binding 4
|
||||||
|
MemberDecorate 98(BufferK) 0 Offset 0
|
||||||
|
Decorate 98(BufferK) Block
|
||||||
|
Decorate 100(bufferk) DescriptorSet 0
|
||||||
|
Decorate 100(bufferk) Binding 7
|
||||||
|
Decorate 109(imagej) DescriptorSet 0
|
||||||
|
Decorate 109(imagej) Binding 5
|
||||||
|
Decorate 121(samp) DescriptorSet 0
|
||||||
|
Decorate 121(samp) Binding 6
|
||||||
|
2: TypeVoid
|
||||||
|
3: TypeFunction 2
|
||||||
|
6: TypeInt 32 1
|
||||||
|
7: TypePointer Function 6(int)
|
||||||
|
9: TypePointer Workgroup 6(int)
|
||||||
|
10(atomi): 9(ptr) Variable Workgroup
|
||||||
|
11: 6(int) Constant 3
|
||||||
|
12: 6(int) Constant 1
|
||||||
|
13: 6(int) Constant 320
|
||||||
|
14: 6(int) Constant 4
|
||||||
|
15: TypeInt 32 0
|
||||||
|
16: 15(int) Constant 5
|
||||||
|
17: 15(int) Constant 0
|
||||||
|
18: 15(int) Constant 324
|
||||||
|
20: TypePointer Function 15(int)
|
||||||
|
22: TypePointer Workgroup 15(int)
|
||||||
|
23(atomu): 22(ptr) Variable Workgroup
|
||||||
|
24(value): 22(ptr) Variable Workgroup
|
||||||
|
26: 15(int) Constant 2
|
||||||
|
28: 6(int) Constant 64
|
||||||
|
29: 6(int) Constant 2
|
||||||
|
30: 15(int) Constant 66
|
||||||
|
33: 15(int) Constant 68
|
||||||
|
34: TypeImage 6(int) 2D nonsampled format:R32i
|
||||||
|
35: TypePointer UniformConstant 34
|
||||||
|
36(imagei): 35(ptr) Variable UniformConstant
|
||||||
|
37: TypeVector 6(int) 2
|
||||||
|
38: 6(int) Constant 0
|
||||||
|
39: 37(ivec2) ConstantComposite 38 38
|
||||||
|
40: TypePointer Image 6(int)
|
||||||
|
43: TypeImage 15(int) 2D nonsampled format:R32ui
|
||||||
|
44: TypePointer UniformConstant 43
|
||||||
|
45(imageu): 44(ptr) Variable UniformConstant
|
||||||
|
46: 15(int) Constant 3
|
||||||
|
47: TypePointer Image 15(int)
|
||||||
|
50: 15(int) Constant 4
|
||||||
|
52: 15(int) Constant 7
|
||||||
|
57: 6(int) Constant 7
|
||||||
|
61: 15(int) Constant 10
|
||||||
|
63: 15(int) Constant 322
|
||||||
|
65(BufferU): TypeStruct 15(int)
|
||||||
|
66: TypePointer Uniform 65(BufferU)
|
||||||
|
67(bufferu): 66(ptr) Variable Uniform
|
||||||
|
68: TypePointer Uniform 15(int)
|
||||||
|
70: 15(int) Constant 1
|
||||||
|
77(BufferI): TypeStruct 15(int)
|
||||||
|
78: TypePointer Uniform 77(BufferI)
|
||||||
|
79(bufferi): 78(ptr) Variable Uniform
|
||||||
|
82: TypeArray 15(int) 26
|
||||||
|
83(A): TypeStruct 82
|
||||||
|
84(BufferJ): TypeStruct 83(A)
|
||||||
|
85: TypeArray 84(BufferJ) 26
|
||||||
|
86: TypePointer Uniform 85
|
||||||
|
87(bufferj): 86(ptr) Variable Uniform
|
||||||
|
94: TypePointer Uniform 83(A)
|
||||||
|
98(BufferK): TypeStruct 15(int)
|
||||||
|
99: TypePointer Uniform 98(BufferK)
|
||||||
|
100(bufferk): 99(ptr) Variable Uniform
|
||||||
|
105: TypeVector 6(int) 4
|
||||||
|
107: TypeArray 34 26
|
||||||
|
108: TypePointer UniformConstant 107
|
||||||
|
109(imagej): 108(ptr) Variable UniformConstant
|
||||||
|
115: 105(ivec4) ConstantComposite 38 38 38 38
|
||||||
|
116: TypeFloat 32
|
||||||
|
117: TypeImage 116(float) 2D sampled format:Unknown
|
||||||
|
118: TypeSampledImage 117
|
||||||
|
119: TypeArray 118 26
|
||||||
|
120: TypePointer UniformConstant 119
|
||||||
|
121(samp): 120(ptr) Variable UniformConstant
|
||||||
|
122: TypePointer UniformConstant 118
|
||||||
|
125: TypeVector 116(float) 2
|
||||||
|
126: 116(float) Constant 0
|
||||||
|
127: 125(fvec2) ConstantComposite 126 126
|
||||||
|
128: TypeVector 116(float) 4
|
||||||
|
130: TypeInt 64 0
|
||||||
|
131: TypePointer Workgroup 130(int64_t)
|
||||||
|
132(atomu64): 131(ptr) Variable Workgroup
|
||||||
|
133:130(int64_t) Constant 7 0
|
||||||
|
135: TypeInt 64 1
|
||||||
|
136: TypePointer Workgroup 135(int64_t)
|
||||||
|
137(atomi64): 136(ptr) Variable Workgroup
|
||||||
|
138:135(int64_t) Constant 10 0
|
||||||
|
4(main): 2 Function None 3
|
||||||
|
5: Label
|
||||||
|
8(origi): 7(ptr) Variable Function
|
||||||
|
21(origu): 20(ptr) Variable Function
|
||||||
|
72(y): 20(ptr) Variable Function
|
||||||
|
19: 6(int) AtomicIAdd 10(atomi) 12 18 11
|
||||||
|
Store 8(origi) 19
|
||||||
|
25: 15(int) Load 24(value) MakePointerVisibleKHR 26
|
||||||
|
27: 15(int) AtomicAnd 23(atomu) 16 17 25
|
||||||
|
Store 21(origu) 27
|
||||||
|
31: 6(int) AtomicLoad 10(atomi) 12 30
|
||||||
|
Store 8(origi) 31
|
||||||
|
32: 15(int) Load 24(value) MakePointerVisibleKHR 26
|
||||||
|
AtomicStore 23(atomu) 12 33 32
|
||||||
|
41: 40(ptr) ImageTexelPointer 36(imagei) 39 17
|
||||||
|
42: 6(int) AtomicLoad 41 12 30
|
||||||
|
Store 8(origi) 42
|
||||||
|
48: 47(ptr) ImageTexelPointer 45(imageu) 39 17
|
||||||
|
49: 15(int) AtomicIAdd 48 12 30 46
|
||||||
|
Store 21(origu) 49
|
||||||
|
51: 47(ptr) ImageTexelPointer 45(imageu) 39 17
|
||||||
|
AtomicStore 51 12 33 50
|
||||||
|
53: 15(int) AtomicOr 23(atomu) 12 17 52
|
||||||
|
Store 21(origu) 53
|
||||||
|
54: 15(int) AtomicXor 23(atomu) 12 17 52
|
||||||
|
Store 21(origu) 54
|
||||||
|
55: 15(int) Load 24(value) MakePointerVisibleKHR 26
|
||||||
|
56: 15(int) AtomicUMin 23(atomu) 12 17 55
|
||||||
|
Store 21(origu) 56
|
||||||
|
58: 6(int) AtomicSMax 10(atomi) 12 17 57
|
||||||
|
Store 8(origi) 58
|
||||||
|
59: 6(int) Load 8(origi)
|
||||||
|
60: 6(int) AtomicExchange 10(atomi) 12 17 59
|
||||||
|
Store 8(origi) 60
|
||||||
|
62: 15(int) Load 24(value) MakePointerVisibleKHR 26
|
||||||
|
64: 15(int) AtomicCompareExchange 23(atomu) 12 63 63 62 61
|
||||||
|
Store 21(origu) 64
|
||||||
|
69: 68(ptr) AccessChain 67(bufferu) 38
|
||||||
|
71: 15(int) AtomicIAdd 69 12 18 70
|
||||||
|
MemoryBarrier 26 18
|
||||||
|
ControlBarrier 26 26 63
|
||||||
|
ControlBarrier 26 26 17
|
||||||
|
73: 68(ptr) AccessChain 67(bufferu) 38
|
||||||
|
74: 15(int) Load 73 MakePointerVisibleKHR NonPrivatePointerKHR 26
|
||||||
|
Store 72(y) 74
|
||||||
|
75: 15(int) Load 72(y)
|
||||||
|
76: 68(ptr) AccessChain 67(bufferu) 38
|
||||||
|
Store 76 75 MakePointerAvailableKHR NonPrivatePointerKHR 26
|
||||||
|
80: 68(ptr) AccessChain 79(bufferi) 38
|
||||||
|
81: 15(int) Load 80 MakePointerVisibleKHR NonPrivatePointerKHR 16
|
||||||
|
Store 72(y) 81
|
||||||
|
88: 68(ptr) AccessChain 87(bufferj) 38 38 38 12
|
||||||
|
89: 15(int) Load 88 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 46
|
||||||
|
Store 72(y) 89
|
||||||
|
90: 15(int) Load 72(y)
|
||||||
|
91: 68(ptr) AccessChain 79(bufferi) 38
|
||||||
|
Store 91 90 MakePointerAvailableKHR NonPrivatePointerKHR 16
|
||||||
|
92: 15(int) Load 72(y)
|
||||||
|
93: 68(ptr) AccessChain 87(bufferj) 38 38 38 12
|
||||||
|
Store 93 92 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 46
|
||||||
|
95: 94(ptr) AccessChain 87(bufferj) 12 38
|
||||||
|
96: 83(A) Load 95 Volatile MakePointerVisibleKHR NonPrivatePointerKHR 46
|
||||||
|
97: 94(ptr) AccessChain 87(bufferj) 38 38
|
||||||
|
Store 97 96 Volatile MakePointerAvailableKHR NonPrivatePointerKHR 46
|
||||||
|
101: 68(ptr) AccessChain 100(bufferk) 38
|
||||||
|
102: 15(int) Load 101 NonPrivatePointerKHR
|
||||||
|
103: 68(ptr) AccessChain 79(bufferi) 38
|
||||||
|
Store 103 102 MakePointerAvailableKHR NonPrivatePointerKHR 16
|
||||||
|
104: 34 Load 36(imagei)
|
||||||
|
106: 105(ivec4) ImageRead 104 39 MakeTexelVisibleKHR NonPrivateTexelKHR VolatileTexelKHR 16
|
||||||
|
110: 35(ptr) AccessChain 109(imagej) 38
|
||||||
|
111: 34 Load 110
|
||||||
|
112: 105(ivec4) ImageRead 111 39 NonPrivateTexelKHR
|
||||||
|
113: 35(ptr) AccessChain 109(imagej) 12
|
||||||
|
114: 34 Load 113
|
||||||
|
ImageWrite 114 39 115 NonPrivateTexelKHR
|
||||||
|
123: 122(ptr) AccessChain 121(samp) 38
|
||||||
|
124: 118 Load 123
|
||||||
|
129: 128(fvec4) ImageSampleExplicitLod 124 127 Lod NonPrivateTexelKHR 126
|
||||||
|
134:130(int64_t) AtomicUMax 132(atomu64) 12 17 133
|
||||||
|
Store 132(atomu64) 134 MakePointerAvailableKHR 26
|
||||||
|
139:130(int64_t) Load 132(atomu64) MakePointerVisibleKHR 26
|
||||||
|
140:135(int64_t) Bitcast 139
|
||||||
|
141:135(int64_t) AtomicCompareExchange 137(atomi64) 12 63 63 140 138
|
||||||
|
Return
|
||||||
|
FunctionEnd
|
||||||
17
Test/baseResults/spv.memoryScopeSemantics_Error.comp.out
Normal file
17
Test/baseResults/spv.memoryScopeSemantics_Error.comp.out
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
spv.memoryScopeSemantics_Error.comp
|
||||||
|
ERROR: 0:15: 'atomicStore' : gl_SemanticsAcquire must not be used with (image) atomic store
|
||||||
|
ERROR: 0:16: 'imageAtomicLoad' : gl_SemanticsRelease must not be used with (image) atomic load
|
||||||
|
ERROR: 0:17: 'atomicStore' : gl_SemanticsAcquireRelease must not be used with (image) atomic load/store
|
||||||
|
ERROR: 0:18: 'atomicStore' : Invalid semantics value
|
||||||
|
ERROR: 0:19: 'imageAtomicLoad' : Invalid storage class semantics value
|
||||||
|
ERROR: 0:20: 'memoryBarrier' : Semantics must include exactly one of gl_SemanticsRelease, gl_SemanticsAcquire, or gl_SemanticsAcquireRelease
|
||||||
|
ERROR: 0:21: 'memoryBarrier' : Storage class semantics must not be zero
|
||||||
|
ERROR: 0:22: 'memoryBarrier' : Semantics must include exactly one of gl_SemanticsRelease, gl_SemanticsAcquire, or gl_SemanticsAcquireRelease
|
||||||
|
ERROR: 0:23: 'atomicAdd' : Semantics must not include multiple of gl_SemanticsRelease, gl_SemanticsAcquire, or gl_SemanticsAcquireRelease
|
||||||
|
ERROR: 0:24: 'atomicCompSwap' : semUnequal must not be gl_SemanticsRelease or gl_SemanticsAcquireRelease
|
||||||
|
ERROR: 0:25: 'memoryBarrier' : gl_SemanticsMakeVisible requires gl_SemanticsAcquire or gl_SemanticsAcquireRelease
|
||||||
|
ERROR: 0:26: 'memoryBarrier' : gl_SemanticsMakeAvailable requires gl_SemanticsRelease or gl_SemanticsAcquireRelease
|
||||||
|
ERROR: 12 compilation errors. No code generated.
|
||||||
|
|
||||||
|
|
||||||
|
SPIR-V is not generated for failed compile or link
|
||||||
@ -11,7 +11,7 @@ spv.specConstant.vert
|
|||||||
Source GLSL 400
|
Source GLSL 400
|
||||||
Name 4 "main"
|
Name 4 "main"
|
||||||
Name 9 "arraySize"
|
Name 9 "arraySize"
|
||||||
Name 14 "foo(vf4[s2543];"
|
Name 14 "foo(vf4[s2765];"
|
||||||
Name 13 "p"
|
Name 13 "p"
|
||||||
Name 17 "builtin_spec_constant("
|
Name 17 "builtin_spec_constant("
|
||||||
Name 20 "color"
|
Name 20 "color"
|
||||||
@ -102,10 +102,10 @@ spv.specConstant.vert
|
|||||||
Store 20(color) 46
|
Store 20(color) 46
|
||||||
48: 10 Load 22(ucol)
|
48: 10 Load 22(ucol)
|
||||||
Store 47(param) 48
|
Store 47(param) 48
|
||||||
49: 2 FunctionCall 14(foo(vf4[s2543];) 47(param)
|
49: 2 FunctionCall 14(foo(vf4[s2765];) 47(param)
|
||||||
Return
|
Return
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
14(foo(vf4[s2543];): 2 Function None 12
|
14(foo(vf4[s2765];): 2 Function None 12
|
||||||
13(p): 11(ptr) FunctionParameter
|
13(p): 11(ptr) FunctionParameter
|
||||||
15: Label
|
15: Label
|
||||||
54: 24(ptr) AccessChain 53(dupUcol) 23
|
54: 24(ptr) AccessChain 53(dupUcol) 23
|
||||||
|
|||||||
61
Test/spv.memoryScopeSemantics.comp
Normal file
61
Test/spv.memoryScopeSemantics.comp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_KHR_memory_scope_semantics : require
|
||||||
|
#extension GL_ARB_gpu_shader_int64 : require
|
||||||
|
|
||||||
|
#pragma use_vulkan_memory_model
|
||||||
|
|
||||||
|
shared uint value;
|
||||||
|
shared int atomi;
|
||||||
|
shared uint atomu;
|
||||||
|
layout(binding = 0, r32ui) workgroupcoherent uniform uimage2D imageu;
|
||||||
|
layout(binding = 1, r32i) volatile coherent uniform iimage2D imagei;
|
||||||
|
layout(binding = 5, r32i) nonprivate uniform iimage2D imagej[2];
|
||||||
|
layout (binding = 2) buffer BufferU { workgroupcoherent uint x; } bufferu;
|
||||||
|
layout (binding = 3) coherent buffer BufferI { uint x; } bufferi;
|
||||||
|
struct A { uint x[2]; };
|
||||||
|
layout (binding = 4) volatile buffer BufferJ { subgroupcoherent A a; } bufferj[2];
|
||||||
|
layout (binding = 6) nonprivate uniform sampler2D samp[2];
|
||||||
|
layout (binding = 7) nonprivate uniform BufferK { uint x; } bufferk;
|
||||||
|
shared uint64_t atomu64;
|
||||||
|
shared int64_t atomi64;
|
||||||
|
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
int origi = atomicAdd(atomi, 3, gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsRelease);
|
||||||
|
uint origu = atomicAnd(atomu, value);
|
||||||
|
origi = atomicLoad(atomi, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquire);
|
||||||
|
atomicStore(atomu, value, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelease);
|
||||||
|
origi = imageAtomicLoad(imagei, ivec2(0,0), gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquire);
|
||||||
|
origu = imageAtomicAdd(imageu, ivec2(0,0), 3u, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquire);
|
||||||
|
imageAtomicStore(imageu, ivec2(0,0), 4u, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelease);
|
||||||
|
origu = atomicOr(atomu, 7u, gl_ScopeDevice, 0, 0);
|
||||||
|
origu = atomicXor(atomu, 7u, gl_ScopeDevice, 0, 0);
|
||||||
|
origu = atomicMin(atomu, value, gl_ScopeDevice, 0, 0);
|
||||||
|
origi = atomicMax(atomi, 7, gl_ScopeDevice, 0, 0);
|
||||||
|
origi = atomicExchange(atomi, origi, gl_ScopeDevice, 0, 0);
|
||||||
|
origu = atomicCompSwap(atomu, 10u, value, gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire);
|
||||||
|
atomicAdd(bufferu.x, 1, gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsRelease);
|
||||||
|
memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsRelease);
|
||||||
|
controlBarrier(gl_ScopeWorkgroup, gl_ScopeWorkgroup, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire);
|
||||||
|
controlBarrier(gl_ScopeWorkgroup, gl_ScopeWorkgroup, 0, 0);
|
||||||
|
|
||||||
|
uint y;
|
||||||
|
y = bufferu.x;
|
||||||
|
bufferu.x = y;
|
||||||
|
y = bufferi.x;
|
||||||
|
y = bufferj[0].a.x[1];
|
||||||
|
bufferi.x = y;
|
||||||
|
bufferj[0].a.x[1] = y;
|
||||||
|
bufferj[0].a = bufferj[1].a;
|
||||||
|
bufferi.x = bufferk.x;
|
||||||
|
|
||||||
|
imageLoad(imagei, ivec2(0,0));
|
||||||
|
imageLoad(imagej[0], ivec2(0,0));
|
||||||
|
imageStore(imagej[1], ivec2(0,0), ivec4(0,0,0,0));
|
||||||
|
texture(samp[0], vec2(0,0));
|
||||||
|
|
||||||
|
atomu64 = atomicMax(atomu64, uint64_t(7), gl_ScopeDevice, 0, 0);
|
||||||
|
atomicCompSwap(atomi64, int64_t(10), int64_t(atomu64), gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire);
|
||||||
|
}
|
||||||
|
|
||||||
28
Test/spv.memoryScopeSemantics_Error.comp
Normal file
28
Test/spv.memoryScopeSemantics_Error.comp
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#version 450
|
||||||
|
#extension GL_KHR_memory_scope_semantics : require
|
||||||
|
|
||||||
|
|
||||||
|
shared uint value;
|
||||||
|
shared int atomi;
|
||||||
|
shared uint atomu;
|
||||||
|
layout(binding = 0, r32ui) workgroupcoherent uniform uimage2D imageu;
|
||||||
|
layout(binding = 1, r32i) coherent uniform iimage2D imagei;
|
||||||
|
layout (binding = 2) buffer BufferU { workgroupcoherent uint x; } bufferu;
|
||||||
|
layout (binding = 3) subgroupcoherent buffer BufferI { uint x; } bufferi;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
atomicStore(atomu, value, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquire);
|
||||||
|
int origi = imageAtomicLoad(imagei, ivec2(0,0), gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelease);
|
||||||
|
atomicStore(atomu, value, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsAcquireRelease);
|
||||||
|
atomicStore(atomu, value, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_StorageSemanticsBuffer);
|
||||||
|
origi = imageAtomicLoad(imagei, ivec2(0,0), gl_ScopeDevice, gl_SemanticsAcquire, gl_SemanticsAcquire);
|
||||||
|
memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, 0);
|
||||||
|
memoryBarrier(gl_ScopeWorkgroup, 0, gl_SemanticsRelease);
|
||||||
|
memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsRelease | gl_SemanticsAcquire);
|
||||||
|
atomicAdd(atomu, value, gl_ScopeDevice, gl_StorageSemanticsBuffer, gl_SemanticsRelease | gl_SemanticsAcquire);
|
||||||
|
uint origu = atomicCompSwap(atomu, 10u, value, gl_ScopeDevice, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquire, gl_StorageSemanticsBuffer | gl_StorageSemanticsShared, gl_SemanticsAcquireRelease);
|
||||||
|
memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer, gl_SemanticsRelease | gl_SemanticsMakeVisible);
|
||||||
|
memoryBarrier(gl_ScopeWorkgroup, gl_StorageSemanticsBuffer, gl_SemanticsAcquire | gl_SemanticsMakeAvailable);
|
||||||
|
}
|
||||||
|
|
||||||
@ -462,6 +462,11 @@ public:
|
|||||||
void clearMemory()
|
void clearMemory()
|
||||||
{
|
{
|
||||||
coherent = false;
|
coherent = false;
|
||||||
|
devicecoherent = false;
|
||||||
|
queuefamilycoherent = false;
|
||||||
|
workgroupcoherent = false;
|
||||||
|
subgroupcoherent = false;
|
||||||
|
nonprivate = false;
|
||||||
volatil = false;
|
volatil = false;
|
||||||
restrict = false;
|
restrict = false;
|
||||||
readonly = false;
|
readonly = false;
|
||||||
@ -499,6 +504,11 @@ public:
|
|||||||
bool patch : 1;
|
bool patch : 1;
|
||||||
bool sample : 1;
|
bool sample : 1;
|
||||||
bool coherent : 1;
|
bool coherent : 1;
|
||||||
|
bool devicecoherent : 1;
|
||||||
|
bool queuefamilycoherent : 1;
|
||||||
|
bool workgroupcoherent : 1;
|
||||||
|
bool subgroupcoherent : 1;
|
||||||
|
bool nonprivate : 1;
|
||||||
bool volatil : 1;
|
bool volatil : 1;
|
||||||
bool restrict : 1;
|
bool restrict : 1;
|
||||||
bool readonly : 1;
|
bool readonly : 1;
|
||||||
@ -508,7 +518,11 @@ public:
|
|||||||
|
|
||||||
bool isMemory() const
|
bool isMemory() const
|
||||||
{
|
{
|
||||||
return coherent || volatil || restrict || readonly || writeonly;
|
return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly || nonprivate;
|
||||||
|
}
|
||||||
|
bool isMemoryQualifierImageAndSSBOOnly() const
|
||||||
|
{
|
||||||
|
return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly;
|
||||||
}
|
}
|
||||||
bool isInterpolation() const
|
bool isInterpolation() const
|
||||||
{
|
{
|
||||||
@ -1713,6 +1727,16 @@ public:
|
|||||||
appendStr(" sample");
|
appendStr(" sample");
|
||||||
if (qualifier.coherent)
|
if (qualifier.coherent)
|
||||||
appendStr(" coherent");
|
appendStr(" coherent");
|
||||||
|
if (qualifier.devicecoherent)
|
||||||
|
appendStr(" devicecoherent");
|
||||||
|
if (qualifier.queuefamilycoherent)
|
||||||
|
appendStr(" queuefamilycoherent");
|
||||||
|
if (qualifier.workgroupcoherent)
|
||||||
|
appendStr(" workgroupcoherent");
|
||||||
|
if (qualifier.subgroupcoherent)
|
||||||
|
appendStr(" subgroupcoherent");
|
||||||
|
if (qualifier.nonprivate)
|
||||||
|
appendStr(" nonprivate");
|
||||||
if (qualifier.volatil)
|
if (qualifier.volatil)
|
||||||
appendStr(" volatile");
|
appendStr(" volatile");
|
||||||
if (qualifier.restrict)
|
if (qualifier.restrict)
|
||||||
|
|||||||
@ -592,6 +592,8 @@ enum TOperator {
|
|||||||
EOpAtomicXor,
|
EOpAtomicXor,
|
||||||
EOpAtomicExchange,
|
EOpAtomicExchange,
|
||||||
EOpAtomicCompSwap,
|
EOpAtomicCompSwap,
|
||||||
|
EOpAtomicLoad,
|
||||||
|
EOpAtomicStore,
|
||||||
|
|
||||||
EOpAtomicCounterIncrement, // results in pre-increment value
|
EOpAtomicCounterIncrement, // results in pre-increment value
|
||||||
EOpAtomicCounterDecrement, // results in post-decrement value
|
EOpAtomicCounterDecrement, // results in post-decrement value
|
||||||
@ -784,6 +786,8 @@ enum TOperator {
|
|||||||
EOpImageAtomicXor,
|
EOpImageAtomicXor,
|
||||||
EOpImageAtomicExchange,
|
EOpImageAtomicExchange,
|
||||||
EOpImageAtomicCompSwap,
|
EOpImageAtomicCompSwap,
|
||||||
|
EOpImageAtomicLoad,
|
||||||
|
EOpImageAtomicStore,
|
||||||
|
|
||||||
EOpSubpassLoad,
|
EOpSubpassLoad,
|
||||||
EOpSubpassLoadMS,
|
EOpSubpassLoadMS,
|
||||||
|
|||||||
@ -935,27 +935,49 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
commonBuiltins.append(
|
commonBuiltins.append(
|
||||||
"uint atomicAdd(coherent volatile inout uint, uint);"
|
"uint atomicAdd(coherent volatile inout uint, uint);"
|
||||||
" int atomicAdd(coherent volatile inout int, int);"
|
" int atomicAdd(coherent volatile inout int, int);"
|
||||||
|
"uint atomicAdd(coherent volatile inout uint, uint, int, int, int);"
|
||||||
|
" int atomicAdd(coherent volatile inout int, int, int, int, int);"
|
||||||
|
|
||||||
"uint atomicMin(coherent volatile inout uint, uint);"
|
"uint atomicMin(coherent volatile inout uint, uint);"
|
||||||
" int atomicMin(coherent volatile inout int, int);"
|
" int atomicMin(coherent volatile inout int, int);"
|
||||||
|
"uint atomicMin(coherent volatile inout uint, uint, int, int, int);"
|
||||||
|
" int atomicMin(coherent volatile inout int, int, int, int, int);"
|
||||||
|
|
||||||
"uint atomicMax(coherent volatile inout uint, uint);"
|
"uint atomicMax(coherent volatile inout uint, uint);"
|
||||||
" int atomicMax(coherent volatile inout int, int);"
|
" int atomicMax(coherent volatile inout int, int);"
|
||||||
|
"uint atomicMax(coherent volatile inout uint, uint, int, int, int);"
|
||||||
|
" int atomicMax(coherent volatile inout int, int, int, int, int);"
|
||||||
|
|
||||||
"uint atomicAnd(coherent volatile inout uint, uint);"
|
"uint atomicAnd(coherent volatile inout uint, uint);"
|
||||||
" int atomicAnd(coherent volatile inout int, int);"
|
" int atomicAnd(coherent volatile inout int, int);"
|
||||||
|
"uint atomicAnd(coherent volatile inout uint, uint, int, int, int);"
|
||||||
|
" int atomicAnd(coherent volatile inout int, int, int, int, int);"
|
||||||
|
|
||||||
"uint atomicOr (coherent volatile inout uint, uint);"
|
"uint atomicOr (coherent volatile inout uint, uint);"
|
||||||
" int atomicOr (coherent volatile inout int, int);"
|
" int atomicOr (coherent volatile inout int, int);"
|
||||||
|
"uint atomicOr (coherent volatile inout uint, uint, int, int, int);"
|
||||||
|
" int atomicOr (coherent volatile inout int, int, int, int, int);"
|
||||||
|
|
||||||
"uint atomicXor(coherent volatile inout uint, uint);"
|
"uint atomicXor(coherent volatile inout uint, uint);"
|
||||||
" int atomicXor(coherent volatile inout int, int);"
|
" int atomicXor(coherent volatile inout int, int);"
|
||||||
|
"uint atomicXor(coherent volatile inout uint, uint, int, int, int);"
|
||||||
|
" int atomicXor(coherent volatile inout int, int, int, int, int);"
|
||||||
|
|
||||||
"uint atomicExchange(coherent volatile inout uint, uint);"
|
"uint atomicExchange(coherent volatile inout uint, uint);"
|
||||||
" int atomicExchange(coherent volatile inout int, int);"
|
" int atomicExchange(coherent volatile inout int, int);"
|
||||||
|
"uint atomicExchange(coherent volatile inout uint, uint, int, int, int);"
|
||||||
|
" int atomicExchange(coherent volatile inout int, int, int, int, int);"
|
||||||
|
|
||||||
"uint atomicCompSwap(coherent volatile inout uint, uint, uint);"
|
"uint atomicCompSwap(coherent volatile inout uint, uint, uint);"
|
||||||
" int atomicCompSwap(coherent volatile inout int, int, int);"
|
" int atomicCompSwap(coherent volatile inout int, int, int);"
|
||||||
|
"uint atomicCompSwap(coherent volatile inout uint, uint, uint, int, int, int, int, int);"
|
||||||
|
" int atomicCompSwap(coherent volatile inout int, int, int, int, int, int, int, int);"
|
||||||
|
|
||||||
|
"uint atomicLoad(coherent volatile in uint, int, int, int);"
|
||||||
|
" int atomicLoad(coherent volatile in int, int, int, int);"
|
||||||
|
|
||||||
|
"void atomicStore(coherent volatile out uint, uint, int, int, int);"
|
||||||
|
"void atomicStore(coherent volatile out int, int, int, int, int);"
|
||||||
|
|
||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
@ -965,23 +987,49 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
commonBuiltins.append(
|
commonBuiltins.append(
|
||||||
"uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t);"
|
"uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t);"
|
||||||
" int64_t atomicMin(coherent volatile inout int64_t, int64_t);"
|
" int64_t atomicMin(coherent volatile inout int64_t, int64_t);"
|
||||||
|
"uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t, int, int, int);"
|
||||||
|
" int64_t atomicMin(coherent volatile inout int64_t, int64_t, int, int, int);"
|
||||||
|
|
||||||
"uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t);"
|
"uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t);"
|
||||||
" int64_t atomicMax(coherent volatile inout int64_t, int64_t);"
|
" int64_t atomicMax(coherent volatile inout int64_t, int64_t);"
|
||||||
|
"uint64_t atomicMax(coherent volatile inout uint64_t, uint64_t, int, int, int);"
|
||||||
|
" int64_t atomicMax(coherent volatile inout int64_t, int64_t, int, int, int);"
|
||||||
|
|
||||||
"uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t);"
|
"uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t);"
|
||||||
" int64_t atomicAnd(coherent volatile inout int64_t, int64_t);"
|
" int64_t atomicAnd(coherent volatile inout int64_t, int64_t);"
|
||||||
|
"uint64_t atomicAnd(coherent volatile inout uint64_t, uint64_t, int, int, int);"
|
||||||
|
" int64_t atomicAnd(coherent volatile inout int64_t, int64_t, int, int, int);"
|
||||||
|
|
||||||
"uint64_t atomicOr (coherent volatile inout uint64_t, uint64_t);"
|
"uint64_t atomicOr (coherent volatile inout uint64_t, uint64_t);"
|
||||||
" int64_t atomicOr (coherent volatile inout int64_t, int64_t);"
|
" int64_t atomicOr (coherent volatile inout int64_t, int64_t);"
|
||||||
|
"uint64_t atomicOr (coherent volatile inout uint64_t, uint64_t, int, int, int);"
|
||||||
|
" int64_t atomicOr (coherent volatile inout int64_t, int64_t, int, int, int);"
|
||||||
|
|
||||||
"uint64_t atomicXor(coherent volatile inout uint64_t, uint64_t);"
|
"uint64_t atomicXor(coherent volatile inout uint64_t, uint64_t);"
|
||||||
" int64_t atomicXor(coherent volatile inout int64_t, int64_t);"
|
" int64_t atomicXor(coherent volatile inout int64_t, int64_t);"
|
||||||
|
"uint64_t atomicXor(coherent volatile inout uint64_t, uint64_t, int, int, int);"
|
||||||
|
" int64_t atomicXor(coherent volatile inout int64_t, int64_t, int, int, int);"
|
||||||
|
|
||||||
|
"uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t);"
|
||||||
" int64_t atomicAdd(coherent volatile inout int64_t, int64_t);"
|
" int64_t atomicAdd(coherent volatile inout int64_t, int64_t);"
|
||||||
" int64_t atomicExchange(coherent volatile inout int64_t, int64_t);"
|
"uint64_t atomicAdd(coherent volatile inout uint64_t, uint64_t, int, int, int);"
|
||||||
" int64_t atomicCompSwap(coherent volatile inout int64_t, int64_t, int64_t);"
|
" int64_t atomicAdd(coherent volatile inout int64_t, int64_t, int, int, int);"
|
||||||
|
|
||||||
|
"uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t);"
|
||||||
|
" int64_t atomicExchange(coherent volatile inout int64_t, int64_t);"
|
||||||
|
"uint64_t atomicExchange(coherent volatile inout uint64_t, uint64_t, int, int, int);"
|
||||||
|
" int64_t atomicExchange(coherent volatile inout int64_t, int64_t, int, int, int);"
|
||||||
|
|
||||||
|
"uint64_t atomicCompSwap(coherent volatile inout uint64_t, uint64_t, uint64_t);"
|
||||||
|
" int64_t atomicCompSwap(coherent volatile inout int64_t, int64_t, int64_t);"
|
||||||
|
"uint64_t atomicCompSwap(coherent volatile inout uint64_t, uint64_t, uint64_t, int, int, int, int, int);"
|
||||||
|
" int64_t atomicCompSwap(coherent volatile inout int64_t, int64_t, int64_t, int, int, int, int, int);"
|
||||||
|
|
||||||
|
"uint64_t atomicLoad(coherent volatile in uint64_t, int, int, int);"
|
||||||
|
" int64_t atomicLoad(coherent volatile in int64_t, int, int, int);"
|
||||||
|
|
||||||
|
"void atomicStore(coherent volatile out uint64_t, uint64_t, int, int, int);"
|
||||||
|
"void atomicStore(coherent volatile out int64_t, int64_t, int, int, int);"
|
||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -4693,6 +4741,9 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
commonBuiltins.append("void controlBarrier(int, int, int, int);\n"
|
||||||
|
"void memoryBarrier(int, int, int);\n");
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
//
|
//
|
||||||
// Prototypes for built-in functions seen by fragment shaders only.
|
// Prototypes for built-in functions seen by fragment shaders only.
|
||||||
@ -5807,6 +5858,28 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||||||
"\n");
|
"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((profile != EEsProfile && version >= 420) ||
|
||||||
|
(profile == EEsProfile && version >= 310)) {
|
||||||
|
commonBuiltins.append("const int gl_ScopeDevice = 1;\n");
|
||||||
|
commonBuiltins.append("const int gl_ScopeWorkgroup = 2;\n");
|
||||||
|
commonBuiltins.append("const int gl_ScopeSubgroup = 3;\n");
|
||||||
|
commonBuiltins.append("const int gl_ScopeInvocation = 4;\n");
|
||||||
|
commonBuiltins.append("const int gl_ScopeQueueFamily = 5;\n");
|
||||||
|
|
||||||
|
commonBuiltins.append("const int gl_SemanticsRelaxed = 0x0;\n");
|
||||||
|
commonBuiltins.append("const int gl_SemanticsAcquire = 0x2;\n");
|
||||||
|
commonBuiltins.append("const int gl_SemanticsRelease = 0x4;\n");
|
||||||
|
commonBuiltins.append("const int gl_SemanticsAcquireRelease = 0x8;\n");
|
||||||
|
commonBuiltins.append("const int gl_SemanticsMakeAvailable = 0x2000;\n");
|
||||||
|
commonBuiltins.append("const int gl_SemanticsMakeVisible = 0x4000;\n");
|
||||||
|
|
||||||
|
commonBuiltins.append("const int gl_StorageSemanticsNone = 0x0;\n");
|
||||||
|
commonBuiltins.append("const int gl_StorageSemanticsBuffer = 0x40;\n");
|
||||||
|
commonBuiltins.append("const int gl_StorageSemanticsShared = 0x100;\n");
|
||||||
|
commonBuiltins.append("const int gl_StorageSemanticsImage = 0x800;\n");
|
||||||
|
commonBuiltins.append("const int gl_StorageSemanticsOutput = 0x1000;\n");
|
||||||
|
}
|
||||||
|
|
||||||
// printf("%s\n", commonBuiltins.c_str());
|
// printf("%s\n", commonBuiltins.c_str());
|
||||||
// printf("%s\n", stageBuiltins[EShLangFragment].c_str());
|
// printf("%s\n", stageBuiltins[EShLangFragment].c_str());
|
||||||
}
|
}
|
||||||
@ -6106,12 +6179,17 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int
|
|||||||
" imageAtomicExchange(volatile coherent "
|
" imageAtomicExchange(volatile coherent "
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Loop twice to add prototypes with/without scope/semantics
|
||||||
|
for (int j = 0; j < 2; ++j) {
|
||||||
for (size_t i = 0; i < numBuiltins; ++i) {
|
for (size_t i = 0; i < numBuiltins; ++i) {
|
||||||
commonBuiltins.append(dataType);
|
commonBuiltins.append(dataType);
|
||||||
commonBuiltins.append(atomicFunc[i]);
|
commonBuiltins.append(atomicFunc[i]);
|
||||||
commonBuiltins.append(imageParams);
|
commonBuiltins.append(imageParams);
|
||||||
commonBuiltins.append(", ");
|
commonBuiltins.append(", ");
|
||||||
commonBuiltins.append(dataType);
|
commonBuiltins.append(dataType);
|
||||||
|
if (j == 1) {
|
||||||
|
commonBuiltins.append(", int, int, int");
|
||||||
|
}
|
||||||
commonBuiltins.append(");\n");
|
commonBuiltins.append(");\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6122,7 +6200,23 @@ void TBuiltIns::addImageFunctions(TSampler sampler, const TString& typeName, int
|
|||||||
commonBuiltins.append(dataType);
|
commonBuiltins.append(dataType);
|
||||||
commonBuiltins.append(", ");
|
commonBuiltins.append(", ");
|
||||||
commonBuiltins.append(dataType);
|
commonBuiltins.append(dataType);
|
||||||
|
if (j == 1) {
|
||||||
|
commonBuiltins.append(", int, int, int, int, int");
|
||||||
|
}
|
||||||
commonBuiltins.append(");\n");
|
commonBuiltins.append(");\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
commonBuiltins.append(dataType);
|
||||||
|
commonBuiltins.append(" imageAtomicLoad(volatile coherent ");
|
||||||
|
commonBuiltins.append(imageParams);
|
||||||
|
commonBuiltins.append(", int, int, int);\n");
|
||||||
|
|
||||||
|
commonBuiltins.append("void imageAtomicStore(volatile coherent ");
|
||||||
|
commonBuiltins.append(imageParams);
|
||||||
|
commonBuiltins.append(", ");
|
||||||
|
commonBuiltins.append(dataType);
|
||||||
|
commonBuiltins.append(", int, int, int);\n");
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// not int or uint
|
// not int or uint
|
||||||
// GL_ARB_ES3_1_compatibility
|
// GL_ARB_ES3_1_compatibility
|
||||||
@ -7969,6 +8063,26 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||||||
symbolTable.setFunctionExtensions("shadow2DEXT", 1, &E_GL_EXT_shadow_samplers);
|
symbolTable.setFunctionExtensions("shadow2DEXT", 1, &E_GL_EXT_shadow_samplers);
|
||||||
symbolTable.setFunctionExtensions("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers);
|
symbolTable.setFunctionExtensions("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (spvVersion.vulkan > 0) {
|
||||||
|
symbolTable.setVariableExtensions("gl_ScopeDevice", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
symbolTable.setVariableExtensions("gl_ScopeWorkgroup", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
symbolTable.setVariableExtensions("gl_ScopeSubgroup", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
symbolTable.setVariableExtensions("gl_ScopeInvocation", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
|
||||||
|
symbolTable.setVariableExtensions("gl_SemanticsRelaxed", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
symbolTable.setVariableExtensions("gl_SemanticsAcquire", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
symbolTable.setVariableExtensions("gl_SemanticsRelease", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
symbolTable.setVariableExtensions("gl_SemanticsAcquireRelease", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
symbolTable.setVariableExtensions("gl_SemanticsMakeAvailable", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
symbolTable.setVariableExtensions("gl_SemanticsMakeVisible", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
|
||||||
|
symbolTable.setVariableExtensions("gl_StorageSemanticsNone", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
symbolTable.setVariableExtensions("gl_StorageSemanticsBuffer", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
symbolTable.setVariableExtensions("gl_StorageSemanticsShared", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
symbolTable.setVariableExtensions("gl_StorageSemanticsImage", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
symbolTable.setVariableExtensions("gl_StorageSemanticsOutput", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EShLangCompute:
|
case EShLangCompute:
|
||||||
@ -8003,6 +8117,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||||||
symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_ARB_compute_shader);
|
symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_ARB_compute_shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
symbolTable.setFunctionExtensions("controlBarrier", 1, &E_GL_KHR_memory_scope_semantics);
|
||||||
|
|
||||||
// GL_ARB_shader_ballot
|
// GL_ARB_shader_ballot
|
||||||
if (profile != EEsProfile) {
|
if (profile != EEsProfile) {
|
||||||
symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot);
|
symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot);
|
||||||
@ -8213,6 +8329,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||||||
symbolTable.relateToOperator("all", EOpAll);
|
symbolTable.relateToOperator("all", EOpAll);
|
||||||
|
|
||||||
symbolTable.relateToOperator("barrier", EOpBarrier);
|
symbolTable.relateToOperator("barrier", EOpBarrier);
|
||||||
|
symbolTable.relateToOperator("controlBarrier", EOpBarrier);
|
||||||
symbolTable.relateToOperator("memoryBarrier", EOpMemoryBarrier);
|
symbolTable.relateToOperator("memoryBarrier", EOpMemoryBarrier);
|
||||||
symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierAtomicCounter);
|
symbolTable.relateToOperator("memoryBarrierAtomicCounter", EOpMemoryBarrierAtomicCounter);
|
||||||
symbolTable.relateToOperator("memoryBarrierBuffer", EOpMemoryBarrierBuffer);
|
symbolTable.relateToOperator("memoryBarrierBuffer", EOpMemoryBarrierBuffer);
|
||||||
@ -8226,6 +8343,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||||||
symbolTable.relateToOperator("atomicXor", EOpAtomicXor);
|
symbolTable.relateToOperator("atomicXor", EOpAtomicXor);
|
||||||
symbolTable.relateToOperator("atomicExchange", EOpAtomicExchange);
|
symbolTable.relateToOperator("atomicExchange", EOpAtomicExchange);
|
||||||
symbolTable.relateToOperator("atomicCompSwap", EOpAtomicCompSwap);
|
symbolTable.relateToOperator("atomicCompSwap", EOpAtomicCompSwap);
|
||||||
|
symbolTable.relateToOperator("atomicLoad", EOpAtomicLoad);
|
||||||
|
symbolTable.relateToOperator("atomicStore", EOpAtomicStore);
|
||||||
|
|
||||||
symbolTable.relateToOperator("atomicCounterIncrement", EOpAtomicCounterIncrement);
|
symbolTable.relateToOperator("atomicCounterIncrement", EOpAtomicCounterIncrement);
|
||||||
symbolTable.relateToOperator("atomicCounterDecrement", EOpAtomicCounterDecrement);
|
symbolTable.relateToOperator("atomicCounterDecrement", EOpAtomicCounterDecrement);
|
||||||
@ -8270,6 +8389,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||||||
symbolTable.relateToOperator("imageAtomicXor", EOpImageAtomicXor);
|
symbolTable.relateToOperator("imageAtomicXor", EOpImageAtomicXor);
|
||||||
symbolTable.relateToOperator("imageAtomicExchange", EOpImageAtomicExchange);
|
symbolTable.relateToOperator("imageAtomicExchange", EOpImageAtomicExchange);
|
||||||
symbolTable.relateToOperator("imageAtomicCompSwap", EOpImageAtomicCompSwap);
|
symbolTable.relateToOperator("imageAtomicCompSwap", EOpImageAtomicCompSwap);
|
||||||
|
symbolTable.relateToOperator("imageAtomicLoad", EOpImageAtomicLoad);
|
||||||
|
symbolTable.relateToOperator("imageAtomicStore", EOpImageAtomicStore);
|
||||||
|
|
||||||
symbolTable.relateToOperator("subpassLoad", EOpSubpassLoad);
|
symbolTable.relateToOperator("subpassLoad", EOpSubpassLoad);
|
||||||
symbolTable.relateToOperator("subpassLoadMS", EOpSubpassLoadMS);
|
symbolTable.relateToOperator("subpassLoadMS", EOpSubpassLoadMS);
|
||||||
|
|||||||
@ -267,6 +267,10 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
|
|||||||
if (tokens.size() != 1)
|
if (tokens.size() != 1)
|
||||||
error(loc, "extra tokens", "#pragma", "");
|
error(loc, "extra tokens", "#pragma", "");
|
||||||
intermediate.setUseStorageBuffer();
|
intermediate.setUseStorageBuffer();
|
||||||
|
} else if (spvVersion.spv > 0 && tokens[0].compare("use_vulkan_memory_model") == 0) {
|
||||||
|
if (tokens.size() != 1)
|
||||||
|
error(loc, "extra tokens", "#pragma", "");
|
||||||
|
intermediate.setUseVulkanMemoryModel();
|
||||||
} else if (tokens[0].compare("once") == 0) {
|
} else if (tokens[0].compare("once") == 0) {
|
||||||
warn(loc, "not implemented", "#pragma once", "");
|
warn(loc, "not implemented", "#pragma once", "");
|
||||||
} else if (tokens[0].compare("glslang_binary_double_output") == 0)
|
} else if (tokens[0].compare("glslang_binary_double_output") == 0)
|
||||||
@ -1028,8 +1032,16 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
|
|||||||
const char* message = "argument cannot drop memory qualifier when passed to formal parameter";
|
const char* message = "argument cannot drop memory qualifier when passed to formal parameter";
|
||||||
if (argQualifier.volatil && ! formalQualifier.volatil)
|
if (argQualifier.volatil && ! formalQualifier.volatil)
|
||||||
error(arguments->getLoc(), message, "volatile", "");
|
error(arguments->getLoc(), message, "volatile", "");
|
||||||
if (argQualifier.coherent && ! formalQualifier.coherent)
|
if (argQualifier.coherent && ! (formalQualifier.devicecoherent || formalQualifier.coherent))
|
||||||
error(arguments->getLoc(), message, "coherent", "");
|
error(arguments->getLoc(), message, "coherent", "");
|
||||||
|
if (argQualifier.devicecoherent && ! (formalQualifier.devicecoherent || formalQualifier.coherent))
|
||||||
|
error(arguments->getLoc(), message, "devicecoherent", "");
|
||||||
|
if (argQualifier.queuefamilycoherent && ! (formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent))
|
||||||
|
error(arguments->getLoc(), message, "queuefamilycoherent", "");
|
||||||
|
if (argQualifier.workgroupcoherent && ! (formalQualifier.workgroupcoherent || formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent))
|
||||||
|
error(arguments->getLoc(), message, "workgroupcoherent", "");
|
||||||
|
if (argQualifier.subgroupcoherent && ! (formalQualifier.subgroupcoherent || formalQualifier.workgroupcoherent || formalQualifier.queuefamilycoherent || formalQualifier.devicecoherent || formalQualifier.coherent))
|
||||||
|
error(arguments->getLoc(), message, "subgroupcoherent", "");
|
||||||
if (argQualifier.readonly && ! formalQualifier.readonly)
|
if (argQualifier.readonly && ! formalQualifier.readonly)
|
||||||
error(arguments->getLoc(), message, "readonly", "");
|
error(arguments->getLoc(), message, "readonly", "");
|
||||||
if (argQualifier.writeonly && ! formalQualifier.writeonly)
|
if (argQualifier.writeonly && ! formalQualifier.writeonly)
|
||||||
@ -1428,6 +1440,159 @@ TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& funct
|
|||||||
return conversionTree;
|
return conversionTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& fnCandidate, const TIntermOperator& callNode)
|
||||||
|
{
|
||||||
|
const TIntermSequence* argp = &callNode.getAsAggregate()->getSequence();
|
||||||
|
|
||||||
|
const int gl_SemanticsRelaxed = 0x0;
|
||||||
|
const int gl_SemanticsAcquire = 0x2;
|
||||||
|
const int gl_SemanticsRelease = 0x4;
|
||||||
|
const int gl_SemanticsAcquireRelease = 0x8;
|
||||||
|
const int gl_SemanticsMakeAvailable = 0x2000;
|
||||||
|
const int gl_SemanticsMakeVisible = 0x4000;
|
||||||
|
|
||||||
|
const int gl_StorageSemanticsNone = 0x0;
|
||||||
|
const int gl_StorageSemanticsBuffer = 0x40;
|
||||||
|
const int gl_StorageSemanticsShared = 0x100;
|
||||||
|
const int gl_StorageSemanticsImage = 0x800;
|
||||||
|
const int gl_StorageSemanticsOutput = 0x1000;
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int semantics = 0, storageClassSemantics = 0;
|
||||||
|
unsigned int semantics2 = 0, storageClassSemantics2 = 0;
|
||||||
|
|
||||||
|
// Grab the semantics and storage class semantics from the operands, based on opcode
|
||||||
|
switch (callNode.getOp()) {
|
||||||
|
case EOpAtomicAdd:
|
||||||
|
case EOpAtomicMin:
|
||||||
|
case EOpAtomicMax:
|
||||||
|
case EOpAtomicAnd:
|
||||||
|
case EOpAtomicOr:
|
||||||
|
case EOpAtomicXor:
|
||||||
|
case EOpAtomicExchange:
|
||||||
|
case EOpAtomicStore:
|
||||||
|
storageClassSemantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
semantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
break;
|
||||||
|
case EOpAtomicLoad:
|
||||||
|
storageClassSemantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
semantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
break;
|
||||||
|
case EOpAtomicCompSwap:
|
||||||
|
storageClassSemantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
semantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
storageClassSemantics2 = (*argp)[6]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
semantics2 = (*argp)[7]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EOpImageAtomicAdd:
|
||||||
|
case EOpImageAtomicMin:
|
||||||
|
case EOpImageAtomicMax:
|
||||||
|
case EOpImageAtomicAnd:
|
||||||
|
case EOpImageAtomicOr:
|
||||||
|
case EOpImageAtomicXor:
|
||||||
|
case EOpImageAtomicExchange:
|
||||||
|
case EOpImageAtomicStore:
|
||||||
|
storageClassSemantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
semantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
break;
|
||||||
|
case EOpImageAtomicLoad:
|
||||||
|
storageClassSemantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
semantics = (*argp)[4]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
break;
|
||||||
|
case EOpImageAtomicCompSwap:
|
||||||
|
storageClassSemantics = (*argp)[5]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
semantics = (*argp)[6]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
storageClassSemantics2 = (*argp)[7]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
semantics2 = (*argp)[8]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EOpBarrier:
|
||||||
|
storageClassSemantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
semantics = (*argp)[3]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
break;
|
||||||
|
case EOpMemoryBarrier:
|
||||||
|
storageClassSemantics = (*argp)[1]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
semantics = (*argp)[2]->getAsConstantUnion()->getConstArray()[0].getIConst();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((semantics & gl_SemanticsAcquire) &&
|
||||||
|
(callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore)) {
|
||||||
|
error(loc, "gl_SemanticsAcquire must not be used with (image) atomic store",
|
||||||
|
fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
|
if ((semantics & gl_SemanticsRelease) &&
|
||||||
|
(callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpImageAtomicLoad)) {
|
||||||
|
error(loc, "gl_SemanticsRelease must not be used with (image) atomic load",
|
||||||
|
fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
|
if ((semantics & gl_SemanticsAcquireRelease) &&
|
||||||
|
(callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore ||
|
||||||
|
callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpImageAtomicLoad)) {
|
||||||
|
error(loc, "gl_SemanticsAcquireRelease must not be used with (image) atomic load/store",
|
||||||
|
fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
|
if (((semantics | semantics2) & ~(gl_SemanticsAcquire |
|
||||||
|
gl_SemanticsRelease |
|
||||||
|
gl_SemanticsAcquireRelease |
|
||||||
|
gl_SemanticsMakeAvailable |
|
||||||
|
gl_SemanticsMakeVisible))) {
|
||||||
|
error(loc, "Invalid semantics value", fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
|
if (((storageClassSemantics | storageClassSemantics2) & ~(gl_StorageSemanticsBuffer |
|
||||||
|
gl_StorageSemanticsShared |
|
||||||
|
gl_StorageSemanticsImage |
|
||||||
|
gl_StorageSemanticsOutput))) {
|
||||||
|
error(loc, "Invalid storage class semantics value", fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callNode.getOp() == EOpMemoryBarrier) {
|
||||||
|
if (!IsPow2(semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
|
||||||
|
error(loc, "Semantics must include exactly one of gl_SemanticsRelease, gl_SemanticsAcquire, or "
|
||||||
|
"gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease)) {
|
||||||
|
if (!IsPow2(semantics & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
|
||||||
|
error(loc, "Semantics must not include multiple of gl_SemanticsRelease, gl_SemanticsAcquire, or "
|
||||||
|
"gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (semantics2 & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease)) {
|
||||||
|
if (!IsPow2(semantics2 & (gl_SemanticsAcquire | gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
|
||||||
|
error(loc, "semUnequal must not include multiple of gl_SemanticsRelease, gl_SemanticsAcquire, or "
|
||||||
|
"gl_SemanticsAcquireRelease", fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (callNode.getOp() == EOpMemoryBarrier) {
|
||||||
|
if (storageClassSemantics == 0) {
|
||||||
|
error(loc, "Storage class semantics must not be zero", fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (callNode.getOp() == EOpBarrier && semantics != 0 && storageClassSemantics == 0) {
|
||||||
|
error(loc, "Storage class semantics must not be zero", fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
|
if ((callNode.getOp() == EOpAtomicCompSwap || callNode.getOp() == EOpImageAtomicCompSwap) &&
|
||||||
|
(semantics2 & (gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
|
||||||
|
error(loc, "semUnequal must not be gl_SemanticsRelease or gl_SemanticsAcquireRelease",
|
||||||
|
fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
|
if ((semantics & gl_SemanticsMakeAvailable) &&
|
||||||
|
!(semantics & (gl_SemanticsRelease | gl_SemanticsAcquireRelease))) {
|
||||||
|
error(loc, "gl_SemanticsMakeAvailable requires gl_SemanticsRelease or gl_SemanticsAcquireRelease",
|
||||||
|
fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
|
if ((semantics & gl_SemanticsMakeVisible) &&
|
||||||
|
!(semantics & (gl_SemanticsAcquire | gl_SemanticsAcquireRelease))) {
|
||||||
|
error(loc, "gl_SemanticsMakeVisible requires gl_SemanticsAcquire or gl_SemanticsAcquireRelease",
|
||||||
|
fnCandidate.getName().c_str(), "");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Do additional checking of built-in function calls that is not caught
|
// Do additional checking of built-in function calls that is not caught
|
||||||
// by normal semantic checks on argument type, extension tagging, etc.
|
// by normal semantic checks on argument type, extension tagging, etc.
|
||||||
@ -1656,6 +1821,8 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||||||
case EOpImageAtomicXor:
|
case EOpImageAtomicXor:
|
||||||
case EOpImageAtomicExchange:
|
case EOpImageAtomicExchange:
|
||||||
case EOpImageAtomicCompSwap:
|
case EOpImageAtomicCompSwap:
|
||||||
|
case EOpImageAtomicLoad:
|
||||||
|
case EOpImageAtomicStore:
|
||||||
{
|
{
|
||||||
// Make sure the image types have the correct layout() format and correct argument types
|
// Make sure the image types have the correct layout() format and correct argument types
|
||||||
const TType& imageType = arg0->getType();
|
const TType& imageType = arg0->getType();
|
||||||
@ -1669,10 +1836,14 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||||||
error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
|
error(loc, "only supported on image with format r32f", fnCandidate.getName().c_str(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argp->size() > 4) {
|
||||||
|
requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
|
||||||
|
memorySemanticsCheck(loc, fnCandidate, callNode);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EOpAtomicAdd:
|
case EOpAtomicAdd:
|
||||||
case EOpAtomicMin:
|
case EOpAtomicMin:
|
||||||
case EOpAtomicMax:
|
case EOpAtomicMax:
|
||||||
@ -1681,13 +1852,19 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||||||
case EOpAtomicXor:
|
case EOpAtomicXor:
|
||||||
case EOpAtomicExchange:
|
case EOpAtomicExchange:
|
||||||
case EOpAtomicCompSwap:
|
case EOpAtomicCompSwap:
|
||||||
|
case EOpAtomicLoad:
|
||||||
|
case EOpAtomicStore:
|
||||||
{
|
{
|
||||||
if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64)
|
if (argp->size() > 3) {
|
||||||
|
requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
|
||||||
|
memorySemanticsCheck(loc, fnCandidate, callNode);
|
||||||
|
}
|
||||||
|
#ifdef NV_EXTENSIONS
|
||||||
|
else if (arg0->getType().getBasicType() == EbtInt64 || arg0->getType().getBasicType() == EbtUint64)
|
||||||
requireExtensions(loc, 1, &E_GL_NV_shader_atomic_int64, fnCandidate.getName().c_str());
|
requireExtensions(loc, 1, &E_GL_NV_shader_atomic_int64, fnCandidate.getName().c_str());
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpInterpolateAtCentroid:
|
case EOpInterpolateAtCentroid:
|
||||||
case EOpInterpolateAtSample:
|
case EOpInterpolateAtSample:
|
||||||
@ -1751,6 +1928,14 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EOpBarrier:
|
||||||
|
case EOpMemoryBarrier:
|
||||||
|
if (argp->size() > 0) {
|
||||||
|
requireExtensions(loc, 1, &E_GL_KHR_memory_scope_semantics, fnCandidate.getName().c_str());
|
||||||
|
memorySemanticsCheck(loc, fnCandidate, callNode);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2806,8 +2991,11 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
|
|||||||
if (! symbolTable.atGlobalLevel())
|
if (! symbolTable.atGlobalLevel())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (qualifier.isMemory() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer)
|
if (qualifier.isMemoryQualifierImageAndSSBOOnly() && ! publicType.isImage() && publicType.qualifier.storage != EvqBuffer) {
|
||||||
error(loc, "memory qualifiers cannot be used on this type", "", "");
|
error(loc, "memory qualifiers cannot be used on this type", "", "");
|
||||||
|
} else if (qualifier.isMemory() && (publicType.basicType != EbtSampler) && !publicType.qualifier.isUniformOrBuffer()) {
|
||||||
|
error(loc, "memory qualifiers cannot be used on this type", "", "");
|
||||||
|
}
|
||||||
|
|
||||||
if (qualifier.storage == EvqBuffer && publicType.basicType != EbtBlock)
|
if (qualifier.storage == EvqBuffer && publicType.basicType != EbtBlock)
|
||||||
error(loc, "buffers can be declared only as blocks", "buffer", "");
|
error(loc, "buffers can be declared only as blocks", "buffer", "");
|
||||||
@ -3020,6 +3208,13 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
|
|||||||
if (dst.precision == EpqNone || (force && src.precision != EpqNone))
|
if (dst.precision == EpqNone || (force && src.precision != EpqNone))
|
||||||
dst.precision = src.precision;
|
dst.precision = src.precision;
|
||||||
|
|
||||||
|
if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) ||
|
||||||
|
(src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) ||
|
||||||
|
(src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent)) ||
|
||||||
|
(src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent)) ||
|
||||||
|
(src.subgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent)))) {
|
||||||
|
error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent qualifier allowed", GetPrecisionQualifierString(src.precision), "");
|
||||||
|
}
|
||||||
// Layout qualifiers
|
// Layout qualifiers
|
||||||
mergeObjectLayoutQualifiers(dst, src, false);
|
mergeObjectLayoutQualifiers(dst, src, false);
|
||||||
|
|
||||||
@ -3038,6 +3233,11 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
|
|||||||
MERGE_SINGLETON(patch);
|
MERGE_SINGLETON(patch);
|
||||||
MERGE_SINGLETON(sample);
|
MERGE_SINGLETON(sample);
|
||||||
MERGE_SINGLETON(coherent);
|
MERGE_SINGLETON(coherent);
|
||||||
|
MERGE_SINGLETON(devicecoherent);
|
||||||
|
MERGE_SINGLETON(queuefamilycoherent);
|
||||||
|
MERGE_SINGLETON(workgroupcoherent);
|
||||||
|
MERGE_SINGLETON(subgroupcoherent);
|
||||||
|
MERGE_SINGLETON(nonprivate);
|
||||||
MERGE_SINGLETON(volatil);
|
MERGE_SINGLETON(volatil);
|
||||||
MERGE_SINGLETON(restrict);
|
MERGE_SINGLETON(restrict);
|
||||||
MERGE_SINGLETON(readonly);
|
MERGE_SINGLETON(readonly);
|
||||||
@ -3862,6 +4062,11 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali
|
|||||||
if (qualifier.isMemory()) {
|
if (qualifier.isMemory()) {
|
||||||
type.getQualifier().volatil = qualifier.volatil;
|
type.getQualifier().volatil = qualifier.volatil;
|
||||||
type.getQualifier().coherent = qualifier.coherent;
|
type.getQualifier().coherent = qualifier.coherent;
|
||||||
|
type.getQualifier().devicecoherent = qualifier.devicecoherent ;
|
||||||
|
type.getQualifier().queuefamilycoherent = qualifier.queuefamilycoherent;
|
||||||
|
type.getQualifier().workgroupcoherent = qualifier.workgroupcoherent;
|
||||||
|
type.getQualifier().subgroupcoherent = qualifier.subgroupcoherent;
|
||||||
|
type.getQualifier().nonprivate = qualifier.nonprivate;
|
||||||
type.getQualifier().readonly = qualifier.readonly;
|
type.getQualifier().readonly = qualifier.readonly;
|
||||||
type.getQualifier().writeonly = qualifier.writeonly;
|
type.getQualifier().writeonly = qualifier.writeonly;
|
||||||
type.getQualifier().restrict = qualifier.restrict;
|
type.getQualifier().restrict = qualifier.restrict;
|
||||||
|
|||||||
@ -323,6 +323,7 @@ public:
|
|||||||
TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
|
TFunction* handleConstructorCall(const TSourceLoc&, const TPublicType&);
|
||||||
void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier);
|
void handlePrecisionQualifier(const TSourceLoc&, TQualifier&, TPrecisionQualifier);
|
||||||
void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
|
void checkPrecisionQualifier(const TSourceLoc&, TPrecisionQualifier);
|
||||||
|
void memorySemanticsCheck(const TSourceLoc&, const TFunction&, const TIntermOperator& callNode);
|
||||||
|
|
||||||
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
|
void assignError(const TSourceLoc&, const char* op, TString left, TString right);
|
||||||
void unaryOpError(const TSourceLoc&, const char* op, TString operand);
|
void unaryOpError(const TSourceLoc&, const char* op, TString operand);
|
||||||
|
|||||||
@ -380,6 +380,11 @@ void TScanContext::fillInKeywordMap()
|
|||||||
(*KeywordMap)["varying"] = VARYING;
|
(*KeywordMap)["varying"] = VARYING;
|
||||||
(*KeywordMap)["buffer"] = BUFFER;
|
(*KeywordMap)["buffer"] = BUFFER;
|
||||||
(*KeywordMap)["coherent"] = COHERENT;
|
(*KeywordMap)["coherent"] = COHERENT;
|
||||||
|
(*KeywordMap)["devicecoherent"] = DEVICECOHERENT;
|
||||||
|
(*KeywordMap)["queuefamilycoherent"] = QUEUEFAMILYCOHERENT;
|
||||||
|
(*KeywordMap)["workgroupcoherent"] = WORKGROUPCOHERENT;
|
||||||
|
(*KeywordMap)["subgroupcoherent"] = SUBGROUPCOHERENT;
|
||||||
|
(*KeywordMap)["nonprivate"] = NONPRIVATE;
|
||||||
(*KeywordMap)["restrict"] = RESTRICT;
|
(*KeywordMap)["restrict"] = RESTRICT;
|
||||||
(*KeywordMap)["readonly"] = READONLY;
|
(*KeywordMap)["readonly"] = READONLY;
|
||||||
(*KeywordMap)["writeonly"] = WRITEONLY;
|
(*KeywordMap)["writeonly"] = WRITEONLY;
|
||||||
@ -937,6 +942,11 @@ int TScanContext::tokenizeIdentifier()
|
|||||||
return es30ReservedFromGLSL(420);
|
return es30ReservedFromGLSL(420);
|
||||||
|
|
||||||
case COHERENT:
|
case COHERENT:
|
||||||
|
case DEVICECOHERENT:
|
||||||
|
case QUEUEFAMILYCOHERENT:
|
||||||
|
case WORKGROUPCOHERENT:
|
||||||
|
case SUBGROUPCOHERENT:
|
||||||
|
case NONPRIVATE:
|
||||||
case RESTRICT:
|
case RESTRICT:
|
||||||
case READONLY:
|
case READONLY:
|
||||||
case WRITEONLY:
|
case WRITEONLY:
|
||||||
|
|||||||
@ -194,6 +194,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_KHR_shader_subgroup_shuffle_relative] = EBhDisable;
|
extensionBehavior[E_GL_KHR_shader_subgroup_shuffle_relative] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHR_shader_subgroup_clustered] = EBhDisable;
|
extensionBehavior[E_GL_KHR_shader_subgroup_clustered] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHR_shader_subgroup_quad] = EBhDisable;
|
extensionBehavior[E_GL_KHR_shader_subgroup_quad] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_KHR_memory_scope_semantics] = EBhDisable;
|
||||||
|
|
||||||
extensionBehavior[E_GL_EXT_shader_non_constant_global_initializers] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_non_constant_global_initializers] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_image_load_formatted] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_image_load_formatted] = EBhDisable;
|
||||||
|
|||||||
@ -148,6 +148,7 @@ const char* const E_GL_KHR_shader_subgroup_shuffle = "GL_KHR_shader_sub
|
|||||||
const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_subgroup_shuffle_relative";
|
const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_subgroup_shuffle_relative";
|
||||||
const char* const E_GL_KHR_shader_subgroup_clustered = "GL_KHR_shader_subgroup_clustered";
|
const char* const E_GL_KHR_shader_subgroup_clustered = "GL_KHR_shader_subgroup_clustered";
|
||||||
const char* const E_GL_KHR_shader_subgroup_quad = "GL_KHR_shader_subgroup_quad";
|
const char* const E_GL_KHR_shader_subgroup_quad = "GL_KHR_shader_subgroup_quad";
|
||||||
|
const char* const E_GL_KHR_memory_scope_semantics = "GL_KHR_memory_scope_semantics";
|
||||||
|
|
||||||
const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
|
const char* const E_GL_EXT_shader_non_constant_global_initializers = "GL_EXT_shader_non_constant_global_initializers";
|
||||||
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
|
const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_load_formatted";
|
||||||
|
|||||||
@ -141,7 +141,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
|
|||||||
%token <lex> VEC2 VEC3 VEC4
|
%token <lex> VEC2 VEC3 VEC4
|
||||||
%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
|
%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
|
||||||
%token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED NONUNIFORM
|
%token <lex> UNIFORM PATCH SAMPLE BUFFER SHARED NONUNIFORM
|
||||||
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY
|
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY DEVICECOHERENT QUEUEFAMILYCOHERENT WORKGROUPCOHERENT SUBGROUPCOHERENT NONPRIVATE
|
||||||
%token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4
|
%token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4
|
||||||
%token <lex> F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4
|
%token <lex> F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4
|
||||||
%token <lex> F32VEC2 F32VEC3 F32VEC4 F32MAT2 F32MAT3 F32MAT4
|
%token <lex> F32VEC2 F32VEC3 F32VEC4 F32MAT2 F32MAT3 F32MAT4
|
||||||
@ -1317,6 +1317,31 @@ storage_qualifier
|
|||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
$$.qualifier.coherent = true;
|
$$.qualifier.coherent = true;
|
||||||
}
|
}
|
||||||
|
| DEVICECOHERENT {
|
||||||
|
$$.init($1.loc);
|
||||||
|
parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "devicecoherent");
|
||||||
|
$$.qualifier.devicecoherent = true;
|
||||||
|
}
|
||||||
|
| QUEUEFAMILYCOHERENT {
|
||||||
|
$$.init($1.loc);
|
||||||
|
parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "queuefamilycoherent");
|
||||||
|
$$.qualifier.queuefamilycoherent = true;
|
||||||
|
}
|
||||||
|
| WORKGROUPCOHERENT {
|
||||||
|
$$.init($1.loc);
|
||||||
|
parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "workgroupcoherent");
|
||||||
|
$$.qualifier.workgroupcoherent = true;
|
||||||
|
}
|
||||||
|
| SUBGROUPCOHERENT {
|
||||||
|
$$.init($1.loc);
|
||||||
|
parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "subgroupcoherent");
|
||||||
|
$$.qualifier.subgroupcoherent = true;
|
||||||
|
}
|
||||||
|
| NONPRIVATE {
|
||||||
|
$$.init($1.loc);
|
||||||
|
parseContext.requireExtensions($1.loc, 1, &E_GL_KHR_memory_scope_semantics, "nonprivate");
|
||||||
|
$$.qualifier.nonprivate = true;
|
||||||
|
}
|
||||||
| VOLATILE {
|
| VOLATILE {
|
||||||
$$.init($1.loc);
|
$$.init($1.loc);
|
||||||
$$.qualifier.volatil = true;
|
$$.qualifier.volatil = true;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,8 @@
|
|||||||
/* A Bison parser, made by GNU Bison 3.0. */
|
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||||
|
|
||||||
/* Bison interface for Yacc-like parsers in C
|
/* Bison interface for Yacc-like parsers in C
|
||||||
|
|
||||||
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
|
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -130,315 +130,320 @@ extern int yydebug;
|
|||||||
RESTRICT = 340,
|
RESTRICT = 340,
|
||||||
READONLY = 341,
|
READONLY = 341,
|
||||||
WRITEONLY = 342,
|
WRITEONLY = 342,
|
||||||
DVEC2 = 343,
|
DEVICECOHERENT = 343,
|
||||||
DVEC3 = 344,
|
QUEUEFAMILYCOHERENT = 344,
|
||||||
DVEC4 = 345,
|
WORKGROUPCOHERENT = 345,
|
||||||
DMAT2 = 346,
|
SUBGROUPCOHERENT = 346,
|
||||||
DMAT3 = 347,
|
NONPRIVATE = 347,
|
||||||
DMAT4 = 348,
|
DVEC2 = 348,
|
||||||
F16VEC2 = 349,
|
DVEC3 = 349,
|
||||||
F16VEC3 = 350,
|
DVEC4 = 350,
|
||||||
F16VEC4 = 351,
|
DMAT2 = 351,
|
||||||
F16MAT2 = 352,
|
DMAT3 = 352,
|
||||||
F16MAT3 = 353,
|
DMAT4 = 353,
|
||||||
F16MAT4 = 354,
|
F16VEC2 = 354,
|
||||||
F32VEC2 = 355,
|
F16VEC3 = 355,
|
||||||
F32VEC3 = 356,
|
F16VEC4 = 356,
|
||||||
F32VEC4 = 357,
|
F16MAT2 = 357,
|
||||||
F32MAT2 = 358,
|
F16MAT3 = 358,
|
||||||
F32MAT3 = 359,
|
F16MAT4 = 359,
|
||||||
F32MAT4 = 360,
|
F32VEC2 = 360,
|
||||||
F64VEC2 = 361,
|
F32VEC3 = 361,
|
||||||
F64VEC3 = 362,
|
F32VEC4 = 362,
|
||||||
F64VEC4 = 363,
|
F32MAT2 = 363,
|
||||||
F64MAT2 = 364,
|
F32MAT3 = 364,
|
||||||
F64MAT3 = 365,
|
F32MAT4 = 365,
|
||||||
F64MAT4 = 366,
|
F64VEC2 = 366,
|
||||||
NOPERSPECTIVE = 367,
|
F64VEC3 = 367,
|
||||||
FLAT = 368,
|
F64VEC4 = 368,
|
||||||
SMOOTH = 369,
|
F64MAT2 = 369,
|
||||||
LAYOUT = 370,
|
F64MAT3 = 370,
|
||||||
EXPLICITINTERPAMD = 371,
|
F64MAT4 = 371,
|
||||||
MAT2X2 = 372,
|
NOPERSPECTIVE = 372,
|
||||||
MAT2X3 = 373,
|
FLAT = 373,
|
||||||
MAT2X4 = 374,
|
SMOOTH = 374,
|
||||||
MAT3X2 = 375,
|
LAYOUT = 375,
|
||||||
MAT3X3 = 376,
|
EXPLICITINTERPAMD = 376,
|
||||||
MAT3X4 = 377,
|
MAT2X2 = 377,
|
||||||
MAT4X2 = 378,
|
MAT2X3 = 378,
|
||||||
MAT4X3 = 379,
|
MAT2X4 = 379,
|
||||||
MAT4X4 = 380,
|
MAT3X2 = 380,
|
||||||
DMAT2X2 = 381,
|
MAT3X3 = 381,
|
||||||
DMAT2X3 = 382,
|
MAT3X4 = 382,
|
||||||
DMAT2X4 = 383,
|
MAT4X2 = 383,
|
||||||
DMAT3X2 = 384,
|
MAT4X3 = 384,
|
||||||
DMAT3X3 = 385,
|
MAT4X4 = 385,
|
||||||
DMAT3X4 = 386,
|
DMAT2X2 = 386,
|
||||||
DMAT4X2 = 387,
|
DMAT2X3 = 387,
|
||||||
DMAT4X3 = 388,
|
DMAT2X4 = 388,
|
||||||
DMAT4X4 = 389,
|
DMAT3X2 = 389,
|
||||||
F16MAT2X2 = 390,
|
DMAT3X3 = 390,
|
||||||
F16MAT2X3 = 391,
|
DMAT3X4 = 391,
|
||||||
F16MAT2X4 = 392,
|
DMAT4X2 = 392,
|
||||||
F16MAT3X2 = 393,
|
DMAT4X3 = 393,
|
||||||
F16MAT3X3 = 394,
|
DMAT4X4 = 394,
|
||||||
F16MAT3X4 = 395,
|
F16MAT2X2 = 395,
|
||||||
F16MAT4X2 = 396,
|
F16MAT2X3 = 396,
|
||||||
F16MAT4X3 = 397,
|
F16MAT2X4 = 397,
|
||||||
F16MAT4X4 = 398,
|
F16MAT3X2 = 398,
|
||||||
F32MAT2X2 = 399,
|
F16MAT3X3 = 399,
|
||||||
F32MAT2X3 = 400,
|
F16MAT3X4 = 400,
|
||||||
F32MAT2X4 = 401,
|
F16MAT4X2 = 401,
|
||||||
F32MAT3X2 = 402,
|
F16MAT4X3 = 402,
|
||||||
F32MAT3X3 = 403,
|
F16MAT4X4 = 403,
|
||||||
F32MAT3X4 = 404,
|
F32MAT2X2 = 404,
|
||||||
F32MAT4X2 = 405,
|
F32MAT2X3 = 405,
|
||||||
F32MAT4X3 = 406,
|
F32MAT2X4 = 406,
|
||||||
F32MAT4X4 = 407,
|
F32MAT3X2 = 407,
|
||||||
F64MAT2X2 = 408,
|
F32MAT3X3 = 408,
|
||||||
F64MAT2X3 = 409,
|
F32MAT3X4 = 409,
|
||||||
F64MAT2X4 = 410,
|
F32MAT4X2 = 410,
|
||||||
F64MAT3X2 = 411,
|
F32MAT4X3 = 411,
|
||||||
F64MAT3X3 = 412,
|
F32MAT4X4 = 412,
|
||||||
F64MAT3X4 = 413,
|
F64MAT2X2 = 413,
|
||||||
F64MAT4X2 = 414,
|
F64MAT2X3 = 414,
|
||||||
F64MAT4X3 = 415,
|
F64MAT2X4 = 415,
|
||||||
F64MAT4X4 = 416,
|
F64MAT3X2 = 416,
|
||||||
ATOMIC_UINT = 417,
|
F64MAT3X3 = 417,
|
||||||
SAMPLER1D = 418,
|
F64MAT3X4 = 418,
|
||||||
SAMPLER2D = 419,
|
F64MAT4X2 = 419,
|
||||||
SAMPLER3D = 420,
|
F64MAT4X3 = 420,
|
||||||
SAMPLERCUBE = 421,
|
F64MAT4X4 = 421,
|
||||||
SAMPLER1DSHADOW = 422,
|
ATOMIC_UINT = 422,
|
||||||
SAMPLER2DSHADOW = 423,
|
SAMPLER1D = 423,
|
||||||
SAMPLERCUBESHADOW = 424,
|
SAMPLER2D = 424,
|
||||||
SAMPLER1DARRAY = 425,
|
SAMPLER3D = 425,
|
||||||
SAMPLER2DARRAY = 426,
|
SAMPLERCUBE = 426,
|
||||||
SAMPLER1DARRAYSHADOW = 427,
|
SAMPLER1DSHADOW = 427,
|
||||||
SAMPLER2DARRAYSHADOW = 428,
|
SAMPLER2DSHADOW = 428,
|
||||||
ISAMPLER1D = 429,
|
SAMPLERCUBESHADOW = 429,
|
||||||
ISAMPLER2D = 430,
|
SAMPLER1DARRAY = 430,
|
||||||
ISAMPLER3D = 431,
|
SAMPLER2DARRAY = 431,
|
||||||
ISAMPLERCUBE = 432,
|
SAMPLER1DARRAYSHADOW = 432,
|
||||||
ISAMPLER1DARRAY = 433,
|
SAMPLER2DARRAYSHADOW = 433,
|
||||||
ISAMPLER2DARRAY = 434,
|
ISAMPLER1D = 434,
|
||||||
USAMPLER1D = 435,
|
ISAMPLER2D = 435,
|
||||||
USAMPLER2D = 436,
|
ISAMPLER3D = 436,
|
||||||
USAMPLER3D = 437,
|
ISAMPLERCUBE = 437,
|
||||||
USAMPLERCUBE = 438,
|
ISAMPLER1DARRAY = 438,
|
||||||
USAMPLER1DARRAY = 439,
|
ISAMPLER2DARRAY = 439,
|
||||||
USAMPLER2DARRAY = 440,
|
USAMPLER1D = 440,
|
||||||
SAMPLER2DRECT = 441,
|
USAMPLER2D = 441,
|
||||||
SAMPLER2DRECTSHADOW = 442,
|
USAMPLER3D = 442,
|
||||||
ISAMPLER2DRECT = 443,
|
USAMPLERCUBE = 443,
|
||||||
USAMPLER2DRECT = 444,
|
USAMPLER1DARRAY = 444,
|
||||||
SAMPLERBUFFER = 445,
|
USAMPLER2DARRAY = 445,
|
||||||
ISAMPLERBUFFER = 446,
|
SAMPLER2DRECT = 446,
|
||||||
USAMPLERBUFFER = 447,
|
SAMPLER2DRECTSHADOW = 447,
|
||||||
SAMPLERCUBEARRAY = 448,
|
ISAMPLER2DRECT = 448,
|
||||||
SAMPLERCUBEARRAYSHADOW = 449,
|
USAMPLER2DRECT = 449,
|
||||||
ISAMPLERCUBEARRAY = 450,
|
SAMPLERBUFFER = 450,
|
||||||
USAMPLERCUBEARRAY = 451,
|
ISAMPLERBUFFER = 451,
|
||||||
SAMPLER2DMS = 452,
|
USAMPLERBUFFER = 452,
|
||||||
ISAMPLER2DMS = 453,
|
SAMPLERCUBEARRAY = 453,
|
||||||
USAMPLER2DMS = 454,
|
SAMPLERCUBEARRAYSHADOW = 454,
|
||||||
SAMPLER2DMSARRAY = 455,
|
ISAMPLERCUBEARRAY = 455,
|
||||||
ISAMPLER2DMSARRAY = 456,
|
USAMPLERCUBEARRAY = 456,
|
||||||
USAMPLER2DMSARRAY = 457,
|
SAMPLER2DMS = 457,
|
||||||
SAMPLEREXTERNALOES = 458,
|
ISAMPLER2DMS = 458,
|
||||||
F16SAMPLER1D = 459,
|
USAMPLER2DMS = 459,
|
||||||
F16SAMPLER2D = 460,
|
SAMPLER2DMSARRAY = 460,
|
||||||
F16SAMPLER3D = 461,
|
ISAMPLER2DMSARRAY = 461,
|
||||||
F16SAMPLER2DRECT = 462,
|
USAMPLER2DMSARRAY = 462,
|
||||||
F16SAMPLERCUBE = 463,
|
SAMPLEREXTERNALOES = 463,
|
||||||
F16SAMPLER1DARRAY = 464,
|
F16SAMPLER1D = 464,
|
||||||
F16SAMPLER2DARRAY = 465,
|
F16SAMPLER2D = 465,
|
||||||
F16SAMPLERCUBEARRAY = 466,
|
F16SAMPLER3D = 466,
|
||||||
F16SAMPLERBUFFER = 467,
|
F16SAMPLER2DRECT = 467,
|
||||||
F16SAMPLER2DMS = 468,
|
F16SAMPLERCUBE = 468,
|
||||||
F16SAMPLER2DMSARRAY = 469,
|
F16SAMPLER1DARRAY = 469,
|
||||||
F16SAMPLER1DSHADOW = 470,
|
F16SAMPLER2DARRAY = 470,
|
||||||
F16SAMPLER2DSHADOW = 471,
|
F16SAMPLERCUBEARRAY = 471,
|
||||||
F16SAMPLER1DARRAYSHADOW = 472,
|
F16SAMPLERBUFFER = 472,
|
||||||
F16SAMPLER2DARRAYSHADOW = 473,
|
F16SAMPLER2DMS = 473,
|
||||||
F16SAMPLER2DRECTSHADOW = 474,
|
F16SAMPLER2DMSARRAY = 474,
|
||||||
F16SAMPLERCUBESHADOW = 475,
|
F16SAMPLER1DSHADOW = 475,
|
||||||
F16SAMPLERCUBEARRAYSHADOW = 476,
|
F16SAMPLER2DSHADOW = 476,
|
||||||
SAMPLER = 477,
|
F16SAMPLER1DARRAYSHADOW = 477,
|
||||||
SAMPLERSHADOW = 478,
|
F16SAMPLER2DARRAYSHADOW = 478,
|
||||||
TEXTURE1D = 479,
|
F16SAMPLER2DRECTSHADOW = 479,
|
||||||
TEXTURE2D = 480,
|
F16SAMPLERCUBESHADOW = 480,
|
||||||
TEXTURE3D = 481,
|
F16SAMPLERCUBEARRAYSHADOW = 481,
|
||||||
TEXTURECUBE = 482,
|
SAMPLER = 482,
|
||||||
TEXTURE1DARRAY = 483,
|
SAMPLERSHADOW = 483,
|
||||||
TEXTURE2DARRAY = 484,
|
TEXTURE1D = 484,
|
||||||
ITEXTURE1D = 485,
|
TEXTURE2D = 485,
|
||||||
ITEXTURE2D = 486,
|
TEXTURE3D = 486,
|
||||||
ITEXTURE3D = 487,
|
TEXTURECUBE = 487,
|
||||||
ITEXTURECUBE = 488,
|
TEXTURE1DARRAY = 488,
|
||||||
ITEXTURE1DARRAY = 489,
|
TEXTURE2DARRAY = 489,
|
||||||
ITEXTURE2DARRAY = 490,
|
ITEXTURE1D = 490,
|
||||||
UTEXTURE1D = 491,
|
ITEXTURE2D = 491,
|
||||||
UTEXTURE2D = 492,
|
ITEXTURE3D = 492,
|
||||||
UTEXTURE3D = 493,
|
ITEXTURECUBE = 493,
|
||||||
UTEXTURECUBE = 494,
|
ITEXTURE1DARRAY = 494,
|
||||||
UTEXTURE1DARRAY = 495,
|
ITEXTURE2DARRAY = 495,
|
||||||
UTEXTURE2DARRAY = 496,
|
UTEXTURE1D = 496,
|
||||||
TEXTURE2DRECT = 497,
|
UTEXTURE2D = 497,
|
||||||
ITEXTURE2DRECT = 498,
|
UTEXTURE3D = 498,
|
||||||
UTEXTURE2DRECT = 499,
|
UTEXTURECUBE = 499,
|
||||||
TEXTUREBUFFER = 500,
|
UTEXTURE1DARRAY = 500,
|
||||||
ITEXTUREBUFFER = 501,
|
UTEXTURE2DARRAY = 501,
|
||||||
UTEXTUREBUFFER = 502,
|
TEXTURE2DRECT = 502,
|
||||||
TEXTURECUBEARRAY = 503,
|
ITEXTURE2DRECT = 503,
|
||||||
ITEXTURECUBEARRAY = 504,
|
UTEXTURE2DRECT = 504,
|
||||||
UTEXTURECUBEARRAY = 505,
|
TEXTUREBUFFER = 505,
|
||||||
TEXTURE2DMS = 506,
|
ITEXTUREBUFFER = 506,
|
||||||
ITEXTURE2DMS = 507,
|
UTEXTUREBUFFER = 507,
|
||||||
UTEXTURE2DMS = 508,
|
TEXTURECUBEARRAY = 508,
|
||||||
TEXTURE2DMSARRAY = 509,
|
ITEXTURECUBEARRAY = 509,
|
||||||
ITEXTURE2DMSARRAY = 510,
|
UTEXTURECUBEARRAY = 510,
|
||||||
UTEXTURE2DMSARRAY = 511,
|
TEXTURE2DMS = 511,
|
||||||
F16TEXTURE1D = 512,
|
ITEXTURE2DMS = 512,
|
||||||
F16TEXTURE2D = 513,
|
UTEXTURE2DMS = 513,
|
||||||
F16TEXTURE3D = 514,
|
TEXTURE2DMSARRAY = 514,
|
||||||
F16TEXTURE2DRECT = 515,
|
ITEXTURE2DMSARRAY = 515,
|
||||||
F16TEXTURECUBE = 516,
|
UTEXTURE2DMSARRAY = 516,
|
||||||
F16TEXTURE1DARRAY = 517,
|
F16TEXTURE1D = 517,
|
||||||
F16TEXTURE2DARRAY = 518,
|
F16TEXTURE2D = 518,
|
||||||
F16TEXTURECUBEARRAY = 519,
|
F16TEXTURE3D = 519,
|
||||||
F16TEXTUREBUFFER = 520,
|
F16TEXTURE2DRECT = 520,
|
||||||
F16TEXTURE2DMS = 521,
|
F16TEXTURECUBE = 521,
|
||||||
F16TEXTURE2DMSARRAY = 522,
|
F16TEXTURE1DARRAY = 522,
|
||||||
SUBPASSINPUT = 523,
|
F16TEXTURE2DARRAY = 523,
|
||||||
SUBPASSINPUTMS = 524,
|
F16TEXTURECUBEARRAY = 524,
|
||||||
ISUBPASSINPUT = 525,
|
F16TEXTUREBUFFER = 525,
|
||||||
ISUBPASSINPUTMS = 526,
|
F16TEXTURE2DMS = 526,
|
||||||
USUBPASSINPUT = 527,
|
F16TEXTURE2DMSARRAY = 527,
|
||||||
USUBPASSINPUTMS = 528,
|
SUBPASSINPUT = 528,
|
||||||
F16SUBPASSINPUT = 529,
|
SUBPASSINPUTMS = 529,
|
||||||
F16SUBPASSINPUTMS = 530,
|
ISUBPASSINPUT = 530,
|
||||||
IMAGE1D = 531,
|
ISUBPASSINPUTMS = 531,
|
||||||
IIMAGE1D = 532,
|
USUBPASSINPUT = 532,
|
||||||
UIMAGE1D = 533,
|
USUBPASSINPUTMS = 533,
|
||||||
IMAGE2D = 534,
|
F16SUBPASSINPUT = 534,
|
||||||
IIMAGE2D = 535,
|
F16SUBPASSINPUTMS = 535,
|
||||||
UIMAGE2D = 536,
|
IMAGE1D = 536,
|
||||||
IMAGE3D = 537,
|
IIMAGE1D = 537,
|
||||||
IIMAGE3D = 538,
|
UIMAGE1D = 538,
|
||||||
UIMAGE3D = 539,
|
IMAGE2D = 539,
|
||||||
IMAGE2DRECT = 540,
|
IIMAGE2D = 540,
|
||||||
IIMAGE2DRECT = 541,
|
UIMAGE2D = 541,
|
||||||
UIMAGE2DRECT = 542,
|
IMAGE3D = 542,
|
||||||
IMAGECUBE = 543,
|
IIMAGE3D = 543,
|
||||||
IIMAGECUBE = 544,
|
UIMAGE3D = 544,
|
||||||
UIMAGECUBE = 545,
|
IMAGE2DRECT = 545,
|
||||||
IMAGEBUFFER = 546,
|
IIMAGE2DRECT = 546,
|
||||||
IIMAGEBUFFER = 547,
|
UIMAGE2DRECT = 547,
|
||||||
UIMAGEBUFFER = 548,
|
IMAGECUBE = 548,
|
||||||
IMAGE1DARRAY = 549,
|
IIMAGECUBE = 549,
|
||||||
IIMAGE1DARRAY = 550,
|
UIMAGECUBE = 550,
|
||||||
UIMAGE1DARRAY = 551,
|
IMAGEBUFFER = 551,
|
||||||
IMAGE2DARRAY = 552,
|
IIMAGEBUFFER = 552,
|
||||||
IIMAGE2DARRAY = 553,
|
UIMAGEBUFFER = 553,
|
||||||
UIMAGE2DARRAY = 554,
|
IMAGE1DARRAY = 554,
|
||||||
IMAGECUBEARRAY = 555,
|
IIMAGE1DARRAY = 555,
|
||||||
IIMAGECUBEARRAY = 556,
|
UIMAGE1DARRAY = 556,
|
||||||
UIMAGECUBEARRAY = 557,
|
IMAGE2DARRAY = 557,
|
||||||
IMAGE2DMS = 558,
|
IIMAGE2DARRAY = 558,
|
||||||
IIMAGE2DMS = 559,
|
UIMAGE2DARRAY = 559,
|
||||||
UIMAGE2DMS = 560,
|
IMAGECUBEARRAY = 560,
|
||||||
IMAGE2DMSARRAY = 561,
|
IIMAGECUBEARRAY = 561,
|
||||||
IIMAGE2DMSARRAY = 562,
|
UIMAGECUBEARRAY = 562,
|
||||||
UIMAGE2DMSARRAY = 563,
|
IMAGE2DMS = 563,
|
||||||
F16IMAGE1D = 564,
|
IIMAGE2DMS = 564,
|
||||||
F16IMAGE2D = 565,
|
UIMAGE2DMS = 565,
|
||||||
F16IMAGE3D = 566,
|
IMAGE2DMSARRAY = 566,
|
||||||
F16IMAGE2DRECT = 567,
|
IIMAGE2DMSARRAY = 567,
|
||||||
F16IMAGECUBE = 568,
|
UIMAGE2DMSARRAY = 568,
|
||||||
F16IMAGE1DARRAY = 569,
|
F16IMAGE1D = 569,
|
||||||
F16IMAGE2DARRAY = 570,
|
F16IMAGE2D = 570,
|
||||||
F16IMAGECUBEARRAY = 571,
|
F16IMAGE3D = 571,
|
||||||
F16IMAGEBUFFER = 572,
|
F16IMAGE2DRECT = 572,
|
||||||
F16IMAGE2DMS = 573,
|
F16IMAGECUBE = 573,
|
||||||
F16IMAGE2DMSARRAY = 574,
|
F16IMAGE1DARRAY = 574,
|
||||||
STRUCT = 575,
|
F16IMAGE2DARRAY = 575,
|
||||||
VOID = 576,
|
F16IMAGECUBEARRAY = 576,
|
||||||
WHILE = 577,
|
F16IMAGEBUFFER = 577,
|
||||||
IDENTIFIER = 578,
|
F16IMAGE2DMS = 578,
|
||||||
TYPE_NAME = 579,
|
F16IMAGE2DMSARRAY = 579,
|
||||||
FLOATCONSTANT = 580,
|
STRUCT = 580,
|
||||||
DOUBLECONSTANT = 581,
|
VOID = 581,
|
||||||
INT16CONSTANT = 582,
|
WHILE = 582,
|
||||||
UINT16CONSTANT = 583,
|
IDENTIFIER = 583,
|
||||||
INT32CONSTANT = 584,
|
TYPE_NAME = 584,
|
||||||
UINT32CONSTANT = 585,
|
FLOATCONSTANT = 585,
|
||||||
INTCONSTANT = 586,
|
DOUBLECONSTANT = 586,
|
||||||
UINTCONSTANT = 587,
|
INT16CONSTANT = 587,
|
||||||
INT64CONSTANT = 588,
|
UINT16CONSTANT = 588,
|
||||||
UINT64CONSTANT = 589,
|
INT32CONSTANT = 589,
|
||||||
BOOLCONSTANT = 590,
|
UINT32CONSTANT = 590,
|
||||||
FLOAT16CONSTANT = 591,
|
INTCONSTANT = 591,
|
||||||
LEFT_OP = 592,
|
UINTCONSTANT = 592,
|
||||||
RIGHT_OP = 593,
|
INT64CONSTANT = 593,
|
||||||
INC_OP = 594,
|
UINT64CONSTANT = 594,
|
||||||
DEC_OP = 595,
|
BOOLCONSTANT = 595,
|
||||||
LE_OP = 596,
|
FLOAT16CONSTANT = 596,
|
||||||
GE_OP = 597,
|
LEFT_OP = 597,
|
||||||
EQ_OP = 598,
|
RIGHT_OP = 598,
|
||||||
NE_OP = 599,
|
INC_OP = 599,
|
||||||
AND_OP = 600,
|
DEC_OP = 600,
|
||||||
OR_OP = 601,
|
LE_OP = 601,
|
||||||
XOR_OP = 602,
|
GE_OP = 602,
|
||||||
MUL_ASSIGN = 603,
|
EQ_OP = 603,
|
||||||
DIV_ASSIGN = 604,
|
NE_OP = 604,
|
||||||
ADD_ASSIGN = 605,
|
AND_OP = 605,
|
||||||
MOD_ASSIGN = 606,
|
OR_OP = 606,
|
||||||
LEFT_ASSIGN = 607,
|
XOR_OP = 607,
|
||||||
RIGHT_ASSIGN = 608,
|
MUL_ASSIGN = 608,
|
||||||
AND_ASSIGN = 609,
|
DIV_ASSIGN = 609,
|
||||||
XOR_ASSIGN = 610,
|
ADD_ASSIGN = 610,
|
||||||
OR_ASSIGN = 611,
|
MOD_ASSIGN = 611,
|
||||||
SUB_ASSIGN = 612,
|
LEFT_ASSIGN = 612,
|
||||||
LEFT_PAREN = 613,
|
RIGHT_ASSIGN = 613,
|
||||||
RIGHT_PAREN = 614,
|
AND_ASSIGN = 614,
|
||||||
LEFT_BRACKET = 615,
|
XOR_ASSIGN = 615,
|
||||||
RIGHT_BRACKET = 616,
|
OR_ASSIGN = 616,
|
||||||
LEFT_BRACE = 617,
|
SUB_ASSIGN = 617,
|
||||||
RIGHT_BRACE = 618,
|
LEFT_PAREN = 618,
|
||||||
DOT = 619,
|
RIGHT_PAREN = 619,
|
||||||
COMMA = 620,
|
LEFT_BRACKET = 620,
|
||||||
COLON = 621,
|
RIGHT_BRACKET = 621,
|
||||||
EQUAL = 622,
|
LEFT_BRACE = 622,
|
||||||
SEMICOLON = 623,
|
RIGHT_BRACE = 623,
|
||||||
BANG = 624,
|
DOT = 624,
|
||||||
DASH = 625,
|
COMMA = 625,
|
||||||
TILDE = 626,
|
COLON = 626,
|
||||||
PLUS = 627,
|
EQUAL = 627,
|
||||||
STAR = 628,
|
SEMICOLON = 628,
|
||||||
SLASH = 629,
|
BANG = 629,
|
||||||
PERCENT = 630,
|
DASH = 630,
|
||||||
LEFT_ANGLE = 631,
|
TILDE = 631,
|
||||||
RIGHT_ANGLE = 632,
|
PLUS = 632,
|
||||||
VERTICAL_BAR = 633,
|
STAR = 633,
|
||||||
CARET = 634,
|
SLASH = 634,
|
||||||
AMPERSAND = 635,
|
PERCENT = 635,
|
||||||
QUESTION = 636,
|
LEFT_ANGLE = 636,
|
||||||
INVARIANT = 637,
|
RIGHT_ANGLE = 637,
|
||||||
PRECISE = 638,
|
VERTICAL_BAR = 638,
|
||||||
HIGH_PRECISION = 639,
|
CARET = 639,
|
||||||
MEDIUM_PRECISION = 640,
|
AMPERSAND = 640,
|
||||||
LOW_PRECISION = 641,
|
QUESTION = 641,
|
||||||
PRECISION = 642,
|
INVARIANT = 642,
|
||||||
PACKED = 643,
|
PRECISE = 643,
|
||||||
RESOURCE = 644,
|
HIGH_PRECISION = 644,
|
||||||
SUPERP = 645
|
MEDIUM_PRECISION = 645,
|
||||||
|
LOW_PRECISION = 646,
|
||||||
|
PRECISION = 647,
|
||||||
|
PACKED = 648,
|
||||||
|
RESOURCE = 649,
|
||||||
|
SUPERP = 650
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Value type. */
|
/* Value type. */
|
||||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||||
typedef union YYSTYPE YYSTYPE;
|
|
||||||
union YYSTYPE
|
union YYSTYPE
|
||||||
{
|
{
|
||||||
#line 70 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
#line 70 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
||||||
@ -476,8 +481,10 @@ union YYSTYPE
|
|||||||
};
|
};
|
||||||
} interm;
|
} interm;
|
||||||
|
|
||||||
#line 480 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
#line 485 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef union YYSTYPE YYSTYPE;
|
||||||
# define YYSTYPE_IS_TRIVIAL 1
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
# define YYSTYPE_IS_DECLARED 1
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -871,6 +871,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
case EOpAtomicXor: out.debug << "AtomicXor"; break;
|
case EOpAtomicXor: out.debug << "AtomicXor"; break;
|
||||||
case EOpAtomicExchange: out.debug << "AtomicExchange"; break;
|
case EOpAtomicExchange: out.debug << "AtomicExchange"; break;
|
||||||
case EOpAtomicCompSwap: out.debug << "AtomicCompSwap"; break;
|
case EOpAtomicCompSwap: out.debug << "AtomicCompSwap"; break;
|
||||||
|
case EOpAtomicLoad: out.debug << "AtomicLoad"; break;
|
||||||
|
case EOpAtomicStore: out.debug << "AtomicStore"; break;
|
||||||
|
|
||||||
case EOpAtomicCounterAdd: out.debug << "AtomicCounterAdd"; break;
|
case EOpAtomicCounterAdd: out.debug << "AtomicCounterAdd"; break;
|
||||||
case EOpAtomicCounterSubtract: out.debug << "AtomicCounterSubtract"; break;
|
case EOpAtomicCounterSubtract: out.debug << "AtomicCounterSubtract"; break;
|
||||||
@ -894,6 +896,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
case EOpImageAtomicXor: out.debug << "imageAtomicXor"; break;
|
case EOpImageAtomicXor: out.debug << "imageAtomicXor"; break;
|
||||||
case EOpImageAtomicExchange: out.debug << "imageAtomicExchange"; break;
|
case EOpImageAtomicExchange: out.debug << "imageAtomicExchange"; break;
|
||||||
case EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break;
|
case EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break;
|
||||||
|
case EOpImageAtomicLoad: out.debug << "imageAtomicLoad"; break;
|
||||||
|
case EOpImageAtomicStore: out.debug << "imageAtomicStore"; break;
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifdef AMD_EXTENSIONS
|
||||||
case EOpImageLoadLod: out.debug << "imageLoadLod"; break;
|
case EOpImageLoadLod: out.debug << "imageLoadLod"; break;
|
||||||
case EOpImageStoreLod: out.debug << "imageStoreLod"; break;
|
case EOpImageStoreLod: out.debug << "imageStoreLod"; break;
|
||||||
|
|||||||
@ -525,6 +525,11 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
|||||||
|
|
||||||
// Memory...
|
// Memory...
|
||||||
if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent ||
|
if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent ||
|
||||||
|
symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent ||
|
||||||
|
symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent ||
|
||||||
|
symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent ||
|
||||||
|
symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent ||
|
||||||
|
symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate ||
|
||||||
symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil ||
|
symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil ||
|
||||||
symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict ||
|
symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict ||
|
||||||
symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly ||
|
symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly ||
|
||||||
|
|||||||
@ -233,6 +233,7 @@ public:
|
|||||||
useUnknownFormat(false),
|
useUnknownFormat(false),
|
||||||
hlslOffsets(false),
|
hlslOffsets(false),
|
||||||
useStorageBuffer(false),
|
useStorageBuffer(false),
|
||||||
|
useVulkanMemoryModel(false),
|
||||||
hlslIoMapping(false),
|
hlslIoMapping(false),
|
||||||
textureSamplerTransformMode(EShTexSampTransKeep),
|
textureSamplerTransformMode(EShTexSampTransKeep),
|
||||||
needToLegalize(false),
|
needToLegalize(false),
|
||||||
@ -365,6 +366,12 @@ public:
|
|||||||
processes.addProcess("hlsl-iomap");
|
processes.addProcess("hlsl-iomap");
|
||||||
}
|
}
|
||||||
bool usingHlslIoMapping() { return hlslIoMapping; }
|
bool usingHlslIoMapping() { return hlslIoMapping; }
|
||||||
|
void setUseVulkanMemoryModel()
|
||||||
|
{
|
||||||
|
useVulkanMemoryModel = true;
|
||||||
|
processes.addProcess("use-vulkan-memory-model");
|
||||||
|
}
|
||||||
|
bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; }
|
||||||
|
|
||||||
template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
|
template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
|
||||||
bool hasCounterBufferName(const TString& name) const {
|
bool hasCounterBufferName(const TString& name) const {
|
||||||
@ -734,6 +741,7 @@ protected:
|
|||||||
bool useUnknownFormat;
|
bool useUnknownFormat;
|
||||||
bool hlslOffsets;
|
bool hlslOffsets;
|
||||||
bool useStorageBuffer;
|
bool useStorageBuffer;
|
||||||
|
bool useVulkanMemoryModel;
|
||||||
bool hlslIoMapping;
|
bool hlslIoMapping;
|
||||||
|
|
||||||
std::set<TString> ioAccessed; // set of names of statically read/written I/O that might need extra checking
|
std::set<TString> ioAccessed; // set of names of statically read/written I/O that might need extra checking
|
||||||
|
|||||||
@ -286,6 +286,8 @@ INSTANTIATE_TEST_CASE_P(
|
|||||||
"spv.matrix.frag",
|
"spv.matrix.frag",
|
||||||
"spv.matrix2.frag",
|
"spv.matrix2.frag",
|
||||||
"spv.memoryQualifier.frag",
|
"spv.memoryQualifier.frag",
|
||||||
|
"spv.memoryScopeSemantics.comp",
|
||||||
|
"spv.memoryScopeSemantics_Error.comp",
|
||||||
"spv.merge-unreachable.frag",
|
"spv.merge-unreachable.frag",
|
||||||
"spv.multiStruct.comp",
|
"spv.multiStruct.comp",
|
||||||
"spv.multiStructFuncall.frag",
|
"spv.multiStructFuncall.frag",
|
||||||
|
|||||||
@ -5,14 +5,14 @@
|
|||||||
"site" : "github",
|
"site" : "github",
|
||||||
"subrepo" : "KhronosGroup/SPIRV-Tools",
|
"subrepo" : "KhronosGroup/SPIRV-Tools",
|
||||||
"subdir" : "External/spirv-tools",
|
"subdir" : "External/spirv-tools",
|
||||||
"commit" : "6d27a8350fbc339909834a6ef339c805cb1ab69b"
|
"commit" : "7600fc0e19c3a99bd3ef2c24515cc508ca1d3cfb"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name" : "spirv-tools/external/spirv-headers",
|
"name" : "spirv-tools/external/spirv-headers",
|
||||||
"site" : "github",
|
"site" : "github",
|
||||||
"subrepo" : "KhronosGroup/SPIRV-Headers",
|
"subrepo" : "KhronosGroup/SPIRV-Headers",
|
||||||
"subdir" : "External/spirv-tools/external/spirv-headers",
|
"subdir" : "External/spirv-tools/external/spirv-headers",
|
||||||
"commit" : "ff684ffc6a35d2a58f0f63108877d0064ea33feb"
|
"commit" : "dcf23bdabacc3c54b83b1f9367e7a8adb27f8d87"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user