Commit 36831c9b by Jeff Bolz

GL_KHR_memory_scope_semantics

parent 97068d8b
...@@ -39,5 +39,6 @@ static const char* const E_SPV_KHR_16bit_storage = "SPV_KHR_16bit ...@@ -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
...@@ -1216,19 +1216,35 @@ Id Builder::createUndefined(Id type) ...@@ -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();
...@@ -1362,6 +1378,16 @@ void Builder::createNoResultOp(Op opCode, Id operand) ...@@ -1362,6 +1378,16 @@ void Builder::createNoResultOp(Op opCode, Id operand)
} }
// 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<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
void Builder::createNoResultOp(Op opCode, const std::vector<IdImmediate>& operands) void Builder::createNoResultOp(Op opCode, const std::vector<IdImmediate>& operands)
{ {
Instruction* op = new Instruction(opCode); Instruction* op = new Instruction(opCode);
...@@ -1679,6 +1705,12 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, ...@@ -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() ...@@ -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 ...@@ -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) ...@@ -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 ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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]; ...@@ -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() ...@@ -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() ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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 { ...@@ -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,
......
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 ...@@ -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 ...@@ -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
......
#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);
}
#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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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 { ...@@ -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 { ...@@ -784,6 +786,8 @@ enum TOperator {
EOpImageAtomicXor, EOpImageAtomicXor,
EOpImageAtomicExchange, EOpImageAtomicExchange,
EOpImageAtomicCompSwap, EOpImageAtomicCompSwap,
EOpImageAtomicLoad,
EOpImageAtomicStore,
EOpSubpassLoad, EOpSubpassLoad,
EOpSubpassLoadMS, EOpSubpassLoadMS,
......
...@@ -323,6 +323,7 @@ public: ...@@ -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() ...@@ -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() ...@@ -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() ...@@ -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 ...@@ -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&); ...@@ -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 ...@@ -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;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -871,6 +871,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node ...@@ -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 ...@@ -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;
......
...@@ -524,11 +524,16 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy ...@@ -524,11 +524,16 @@ 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().volatil != unitSymbol.getQualifier().volatil || symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent ||
symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict || symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent ||
symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly || symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent ||
symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) { symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent ||
symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate ||
symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil ||
symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict ||
symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly ||
symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) {
error(infoSink, "Memory qualifiers must match:"); error(infoSink, "Memory qualifiers must match:");
writeTypeComparison = true; writeTypeComparison = true;
} }
......
...@@ -233,6 +233,7 @@ public: ...@@ -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: ...@@ -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: ...@@ -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( ...@@ -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 @@ ...@@ -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"
} }
] ]
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment