Web: Make switched methods all be non-virtual, more web-dependent code,

added a few more HLSL flag tests.  This was mostly focused on the SPV generator.
Saves about 17K.
This commit is contained in:
John Kessenich 2019-08-11 07:41:45 -06:00
parent d8834df992
commit b9197c812e
19 changed files with 329 additions and 211 deletions

View File

@ -87,9 +87,29 @@ private:
}; };
struct OpDecorations { struct OpDecorations {
public:
OpDecorations(spv::Decoration precision, spv::Decoration noContraction, spv::Decoration nonUniform) :
precision(precision)
#ifndef GLSLANG_WEB
,
noContraction(noContraction),
nonUniform(nonUniform)
#endif
{ }
spv::Decoration precision; spv::Decoration precision;
#ifdef GLSLANG_WEB
void addNoContraction(spv::Builder&, spv::Id) const { };
void addNonUniform(spv::Builder&, spv::Id) const { };
#else
void addNoContraction(spv::Builder& builder, spv::Id t) { builder.addDecoration(t, noContraction); };
void addNonUniform(spv::Builder& builder, spv::Id t) { builder.addDecoration(t, nonUniform); };
protected:
spv::Decoration noContraction; spv::Decoration noContraction;
spv::Decoration nonUniform; spv::Decoration nonUniform;
#endif
}; };
} // namespace } // namespace
@ -359,6 +379,7 @@ 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, bool useVulkanMemoryModel) void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector<spv::Decoration>& memory, bool useVulkanMemoryModel)
{ {
#ifndef GLSLANG_WEB
if (!useVulkanMemoryModel) { if (!useVulkanMemoryModel) {
if (qualifier.coherent) if (qualifier.coherent)
memory.push_back(spv::DecorationCoherent); memory.push_back(spv::DecorationCoherent);
@ -373,6 +394,7 @@ void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector
memory.push_back(spv::DecorationNonWritable); memory.push_back(spv::DecorationNonWritable);
if (qualifier.writeonly) if (qualifier.writeonly)
memory.push_back(spv::DecorationNonReadable); memory.push_back(spv::DecorationNonReadable);
#endif
} }
// Translate glslang type to SPIR-V layout decorations. // Translate glslang type to SPIR-V layout decorations.
@ -456,14 +478,17 @@ spv::Decoration TGlslangToSpvTraverser::TranslateInterpolationDecoration(const g
// should be applied. // should be applied.
spv::Decoration TGlslangToSpvTraverser::TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier) spv::Decoration TGlslangToSpvTraverser::TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier)
{ {
if (qualifier.patch) if (qualifier.centroid)
return spv::DecorationPatch;
else if (qualifier.centroid)
return spv::DecorationCentroid; return spv::DecorationCentroid;
#ifndef GLSLANG_WEB
else if (qualifier.patch)
return spv::DecorationPatch;
else if (qualifier.sample) { else if (qualifier.sample) {
builder.addCapability(spv::CapabilitySampleRateShading); builder.addCapability(spv::CapabilitySampleRateShading);
return spv::DecorationSample; return spv::DecorationSample;
} else }
#endif
return spv::DecorationMax; return spv::DecorationMax;
} }
@ -479,29 +504,36 @@ spv::Decoration TranslateInvariantDecoration(const glslang::TQualifier& qualifie
// If glslang type is noContraction, return SPIR-V NoContraction decoration. // If glslang type is noContraction, return SPIR-V NoContraction decoration.
spv::Decoration TranslateNoContractionDecoration(const glslang::TQualifier& qualifier) spv::Decoration TranslateNoContractionDecoration(const glslang::TQualifier& qualifier)
{ {
#ifndef GLSLANG_WEB
if (qualifier.isNoContraction()) if (qualifier.isNoContraction())
return spv::DecorationNoContraction; return spv::DecorationNoContraction;
else else
#endif
return spv::DecorationMax; return spv::DecorationMax;
} }
// If glslang type is nonUniform, return SPIR-V NonUniform decoration. // If glslang type is nonUniform, return SPIR-V NonUniform decoration.
spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glslang::TQualifier& qualifier) spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glslang::TQualifier& qualifier)
{ {
#ifndef GLSLANG_WEB
if (qualifier.isNonUniform()) { if (qualifier.isNonUniform()) {
builder.addExtension("SPV_EXT_descriptor_indexing"); builder.addExtension("SPV_EXT_descriptor_indexing");
builder.addCapability(spv::CapabilityShaderNonUniformEXT); builder.addCapability(spv::CapabilityShaderNonUniformEXT);
return spv::DecorationNonUniformEXT; return spv::DecorationNonUniformEXT;
} else } else
#endif
return spv::DecorationMax; return spv::DecorationMax;
} }
spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess(const spv::Builder::AccessChain::CoherentFlags &coherentFlags) spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess(
const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
{ {
if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage) {
return spv::MemoryAccessMaskNone;
}
spv::MemoryAccessMask mask = spv::MemoryAccessMaskNone; spv::MemoryAccessMask mask = spv::MemoryAccessMaskNone;
#ifndef GLSLANG_WEB
if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage)
return mask;
if (coherentFlags.volatil || if (coherentFlags.volatil ||
coherentFlags.coherent || coherentFlags.coherent ||
coherentFlags.devicecoherent || coherentFlags.devicecoherent ||
@ -520,15 +552,20 @@ spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess(const spv::B
if (mask != spv::MemoryAccessMaskNone) { if (mask != spv::MemoryAccessMaskNone) {
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
} }
#endif
return mask; return mask;
} }
spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands(const spv::Builder::AccessChain::CoherentFlags &coherentFlags) spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands(
const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
{ {
if (!glslangIntermediate->usingVulkanMemoryModel()) {
return spv::ImageOperandsMaskNone;
}
spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
#ifndef GLSLANG_WEB
if (!glslangIntermediate->usingVulkanMemoryModel())
return mask;
if (coherentFlags.volatil || if (coherentFlags.volatil ||
coherentFlags.coherent || coherentFlags.coherent ||
coherentFlags.devicecoherent || coherentFlags.devicecoherent ||
@ -547,12 +584,15 @@ spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands(const spv:
if (mask != spv::ImageOperandsMaskNone) { if (mask != spv::ImageOperandsMaskNone) {
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
} }
#endif
return mask; return mask;
} }
spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCoherent(const glslang::TType& type) spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCoherent(const glslang::TType& type)
{ {
spv::Builder::AccessChain::CoherentFlags flags; spv::Builder::AccessChain::CoherentFlags flags = {};
#ifndef GLSLANG_WEB
flags.coherent = type.getQualifier().coherent; flags.coherent = type.getQualifier().coherent;
flags.devicecoherent = type.getQualifier().devicecoherent; flags.devicecoherent = type.getQualifier().devicecoherent;
flags.queuefamilycoherent = type.getQualifier().queuefamilycoherent; flags.queuefamilycoherent = type.getQualifier().queuefamilycoherent;
@ -570,12 +610,16 @@ spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCohere
flags.coherent || flags.coherent ||
flags.volatil; flags.volatil;
flags.isImage = type.getBasicType() == glslang::EbtSampler; flags.isImage = type.getBasicType() == glslang::EbtSampler;
#endif
return flags; return flags;
} }
spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(const spv::Builder::AccessChain::CoherentFlags &coherentFlags) spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(
const spv::Builder::AccessChain::CoherentFlags &coherentFlags)
{ {
spv::Scope scope; spv::Scope scope = spv::ScopeMax;
#ifndef GLSLANG_WEB
if (coherentFlags.volatil || coherentFlags.coherent) { if (coherentFlags.volatil || coherentFlags.coherent) {
// coherent defaults to Device scope in the old model, QueueFamilyKHR scope in the new model // coherent defaults to Device scope in the old model, QueueFamilyKHR scope in the new model
scope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice; scope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
@ -587,12 +631,12 @@ spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope(const spv::Builder::Acce
scope = spv::ScopeWorkgroup; scope = spv::ScopeWorkgroup;
} else if (coherentFlags.subgroupcoherent) { } else if (coherentFlags.subgroupcoherent) {
scope = spv::ScopeSubgroup; scope = spv::ScopeSubgroup;
} else {
scope = spv::ScopeMax;
} }
if (glslangIntermediate->usingVulkanMemoryModel() && scope == spv::ScopeDevice) { if (glslangIntermediate->usingVulkanMemoryModel() && scope == spv::ScopeDevice) {
builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
} }
#endif
return scope; return scope;
} }
@ -979,6 +1023,10 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy
{ {
assert(type.getBasicType() == glslang::EbtSampler); assert(type.getBasicType() == glslang::EbtSampler);
#ifdef GLSLANG_WEB
return spv::ImageFormatUnknown;
#endif
// Check for capabilities // Check for capabilities
switch (type.getQualifier().getFormat()) { switch (type.getQualifier().getFormat()) {
case glslang::ElfRg32f: case glslang::ElfRg32f:
@ -1186,6 +1234,7 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TType& baseType, void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TType& baseType,
const glslang::TType& indexType) const glslang::TType& indexType)
{ {
#ifndef GLSLANG_WEB
if (indexType.getQualifier().isNonUniform()) { if (indexType.getQualifier().isNonUniform()) {
// deal with an asserted non-uniform index // deal with an asserted non-uniform index
// SPV_EXT_descriptor_indexing already added in TranslateNonUniformDecoration // SPV_EXT_descriptor_indexing already added in TranslateNonUniformDecoration
@ -1221,6 +1270,7 @@ void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TTyp
} }
} }
} }
#endif
} }
// Return whether or not the given type is something that should be tied to a // Return whether or not the given type is something that should be tied to a
@ -1414,6 +1464,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
builder.addExtension(spv::E_SPV_KHR_post_depth_coverage); builder.addExtension(spv::E_SPV_KHR_post_depth_coverage);
} }
if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing())
builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing);
#ifndef GLSLANG_WEB
switch(glslangIntermediate->getDepth()) { switch(glslangIntermediate->getDepth()) {
case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break; case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break;
case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break; case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break;
@ -1421,10 +1475,6 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
} }
if (mode != spv::ExecutionModeMax) if (mode != spv::ExecutionModeMax)
builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
if (glslangIntermediate->getDepth() != glslang::EldUnchanged && glslangIntermediate->isDepthReplacing())
builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing);
switch (glslangIntermediate->getInterlockOrdering()) { switch (glslangIntermediate->getInterlockOrdering()) {
case glslang::EioPixelInterlockOrdered: mode = spv::ExecutionModePixelInterlockOrderedEXT; break; case glslang::EioPixelInterlockOrdered: mode = spv::ExecutionModePixelInterlockOrderedEXT; break;
case glslang::EioPixelInterlockUnordered: mode = spv::ExecutionModePixelInterlockUnorderedEXT; break; case glslang::EioPixelInterlockUnordered: mode = spv::ExecutionModePixelInterlockUnorderedEXT; break;
@ -1447,7 +1497,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const gl
} }
builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock); builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock);
} }
#endif
break; break;
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
@ -1670,7 +1720,7 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
builder.setAccessChainLValue(id); builder.setAccessChainLValue(id);
} }
#ifndef GLSLANG_WEB #ifdef ENABLE_HLSL
// Process linkage-only nodes for any special additional interface work. // Process linkage-only nodes for any special additional interface work.
if (linkageOnly) { if (linkageOnly) {
if (glslangIntermediate->getHlslFunctionality1()) { if (glslangIntermediate->getHlslFunctionality1()) {
@ -2104,7 +2154,7 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
if (result) { if (result) {
if (invertedType) { if (invertedType) {
result = createInvertedSwizzle(decorations.precision, *node->getOperand(), result); result = createInvertedSwizzle(decorations.precision, *node->getOperand(), result);
builder.addDecoration(result, decorations.nonUniform); decorations.addNonUniform(builder, result);
} }
builder.clearAccessChain(); builder.clearAccessChain();
@ -2696,6 +2746,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
else else
glslangOperands[arg]->traverse(this); glslangOperands[arg]->traverse(this);
#ifndef GLSLANG_WEB
if (node->getOp() == glslang::EOpCooperativeMatrixLoad || if (node->getOp() == glslang::EOpCooperativeMatrixLoad ||
node->getOp() == glslang::EOpCooperativeMatrixStore) { node->getOp() == glslang::EOpCooperativeMatrixStore) {
@ -2738,6 +2789,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
continue; continue;
} }
} }
#endif
if (lvalue) { if (lvalue) {
operands.push_back(builder.accessChainGetLValue()); operands.push_back(builder.accessChainGetLValue());
@ -2750,6 +2802,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
} }
builder.setLine(node->getLoc().line, node->getLoc().getFilename()); builder.setLine(node->getLoc().line, node->getLoc().getFilename());
#ifndef GLSLANG_WEB
if (node->getOp() == glslang::EOpCooperativeMatrixLoad) { if (node->getOp() == glslang::EOpCooperativeMatrixLoad) {
std::vector<spv::IdImmediate> idImmOps; std::vector<spv::IdImmediate> idImmOps;
@ -2779,7 +2832,9 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
} else if (atomic) { } else if (atomic) {
// Handle all atomics // Handle all atomics
result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags); result = createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), lvalueCoherentFlags);
} else { } else
#endif
{
// Pass through to generic operations. // Pass through to generic operations.
switch (glslangOperands.size()) { switch (glslangOperands.size()) {
case 0: case 0:
@ -3155,11 +3210,13 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
builder.clearAccessChain(); builder.clearAccessChain();
break; break;
#ifndef GLSLANG_WEB
case glslang::EOpDemote: case glslang::EOpDemote:
builder.createNoResultOp(spv::OpDemoteToHelperInvocationEXT); builder.createNoResultOp(spv::OpDemoteToHelperInvocationEXT);
builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation); builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation);
builder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT); builder.addCapability(spv::CapabilityDemoteToHelperInvocationEXT);
break; break;
#endif
default: default:
assert(0); assert(0);
@ -3185,9 +3242,8 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
spv::Id spvType = forcedType == spv::NoType ? convertGlslangToSpvType(node->getType()) spv::Id spvType = forcedType == spv::NoType ? convertGlslangToSpvType(node->getType())
: forcedType; : forcedType;
const bool contains16BitType = node->getType().containsBasicType(glslang::EbtFloat16) || const bool contains16BitType = node->getType().contains16BitFloat() ||
node->getType().containsBasicType(glslang::EbtInt16) || node->getType().contains16BitInt();
node->getType().containsBasicType(glslang::EbtUint16);
if (contains16BitType) { if (contains16BitType) {
switch (storageClass) { switch (storageClass) {
case spv::StorageClassInput: case spv::StorageClassInput:
@ -3195,10 +3251,6 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
addPre13Extension(spv::E_SPV_KHR_16bit_storage); addPre13Extension(spv::E_SPV_KHR_16bit_storage);
builder.addCapability(spv::CapabilityStorageInputOutput16); builder.addCapability(spv::CapabilityStorageInputOutput16);
break; break;
case spv::StorageClassPushConstant:
addPre13Extension(spv::E_SPV_KHR_16bit_storage);
builder.addCapability(spv::CapabilityStoragePushConstant16);
break;
case spv::StorageClassUniform: case spv::StorageClassUniform:
addPre13Extension(spv::E_SPV_KHR_16bit_storage); addPre13Extension(spv::E_SPV_KHR_16bit_storage);
if (node->getType().getQualifier().storage == glslang::EvqBuffer) if (node->getType().getQualifier().storage == glslang::EvqBuffer)
@ -3206,24 +3258,27 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol*
else else
builder.addCapability(spv::CapabilityStorageUniform16); builder.addCapability(spv::CapabilityStorageUniform16);
break; break;
#ifndef GLSLANG_WEB
case spv::StorageClassPushConstant:
addPre13Extension(spv::E_SPV_KHR_16bit_storage);
builder.addCapability(spv::CapabilityStoragePushConstant16);
break;
case spv::StorageClassStorageBuffer: case spv::StorageClassStorageBuffer:
case spv::StorageClassPhysicalStorageBufferEXT: case spv::StorageClassPhysicalStorageBufferEXT:
addPre13Extension(spv::E_SPV_KHR_16bit_storage); addPre13Extension(spv::E_SPV_KHR_16bit_storage);
builder.addCapability(spv::CapabilityStorageUniformBufferBlock16); builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
break; break;
#endif
default: default:
if (node->getType().containsBasicType(glslang::EbtFloat16)) if (node->getType().contains16BitFloat())
builder.addCapability(spv::CapabilityFloat16); builder.addCapability(spv::CapabilityFloat16);
if (node->getType().containsBasicType(glslang::EbtInt16) || if (node->getType().contains16BitInt())
node->getType().containsBasicType(glslang::EbtUint16))
builder.addCapability(spv::CapabilityInt16); builder.addCapability(spv::CapabilityInt16);
break; break;
} }
} }
const bool contains8BitType = node->getType().containsBasicType(glslang::EbtInt8) || if (node->getType().contains8BitInt()) {
node->getType().containsBasicType(glslang::EbtUint8);
if (contains8BitType) {
if (storageClass == spv::StorageClassPushConstant) { if (storageClass == spv::StorageClassPushConstant) {
builder.addExtension(spv::E_SPV_KHR_8bit_storage); builder.addExtension(spv::E_SPV_KHR_8bit_storage);
builder.addCapability(spv::CapabilityStoragePushConstant8); builder.addCapability(spv::CapabilityStoragePushConstant8);
@ -3482,11 +3537,13 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
if (type.isSizedArray()) if (type.isSizedArray())
spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), 0), stride); spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), 0), stride);
else { else {
#ifndef GLSLANG_WEB
if (!lastBufferBlockMember) { if (!lastBufferBlockMember) {
builder.addExtension("SPV_EXT_descriptor_indexing"); builder.addExtension("SPV_EXT_descriptor_indexing");
builder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT); builder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT);
} }
spvType = builder.makeRuntimeArray(spvType); spvType = builder.makeRuntimeArray(spvType);
#endif
} }
if (stride > 0) if (stride > 0)
builder.addDecoration(spvType, spv::DecorationArrayStride, stride); builder.addDecoration(spvType, spv::DecorationArrayStride, stride);
@ -3642,6 +3699,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
} }
builder.addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier)); builder.addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier));
#ifndef GLSLANG_WEB
if (type.getBasicType() == glslang::EbtBlock && if (type.getBasicType() == glslang::EbtBlock &&
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
@ -3650,6 +3708,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
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]);
} }
#endif
// Location assignment was already completed correctly by the front end, // Location assignment was already completed correctly by the front end,
// just track whether a member needs to be decorated. // just track whether a member needs to be decorated.
@ -3687,6 +3746,7 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
if (builtIn != spv::BuiltInMax) if (builtIn != spv::BuiltInMax)
builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn); builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
#ifndef GLSLANG_WEB
// nonuniform // nonuniform
builder.addMemberDecoration(spvType, member, TranslateNonUniformDecoration(glslangMember.getQualifier())); builder.addMemberDecoration(spvType, member, TranslateNonUniformDecoration(glslangMember.getQualifier()));
@ -3696,7 +3756,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type,
memberQualifier.semanticName); memberQualifier.semanticName);
} }
#ifndef GLSLANG_WEB
if (builtIn == spv::BuiltInLayer) { if (builtIn == spv::BuiltInLayer) {
// SPV_NV_viewport_array2 extension // SPV_NV_viewport_array2 extension
if (glslangMember.getQualifier().layoutViewportRelative){ if (glslangMember.getQualifier().layoutViewportRelative){
@ -4176,13 +4235,11 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
builder.addName(function->getParamId(p), parameters[p]->getAsSymbolNode()->getName().c_str()); builder.addName(function->getParamId(p), parameters[p]->getAsSymbolNode()->getName().c_str());
const glslang::TType& paramType = parameters[p]->getAsTyped()->getType(); const glslang::TType& paramType = parameters[p]->getAsTyped()->getType();
if (paramType.containsBasicType(glslang::EbtInt8) || if (paramType.contains8BitInt())
paramType.containsBasicType(glslang::EbtUint8))
builder.addCapability(spv::CapabilityInt8); builder.addCapability(spv::CapabilityInt8);
if (paramType.containsBasicType(glslang::EbtInt16) || if (paramType.contains16BitInt())
paramType.containsBasicType(glslang::EbtUint16))
builder.addCapability(spv::CapabilityInt16); builder.addCapability(spv::CapabilityInt16);
if (paramType.containsBasicType(glslang::EbtFloat16)) if (paramType.contains16BitFloat())
builder.addCapability(spv::CapabilityFloat16); builder.addCapability(spv::CapabilityFloat16);
} }
} }
@ -4771,13 +4828,9 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO
if (cracked.lod) { if (cracked.lod) {
params.lod = arguments[2 + extraArgs]; params.lod = arguments[2 + extraArgs];
++extraArgs; ++extraArgs;
} else if (glslangIntermediate->getStage() != EShLangFragment } else if (glslangIntermediate->getStage() != EShLangFragment &&
#ifndef GLSLANG_WEB !(glslangIntermediate->getStage() == EShLangCompute &&
// NV_compute_shader_derivatives layout qualifiers allow for implicit LODs glslangIntermediate->hasLayoutDerivativeModeNone())) {
&& !(glslangIntermediate->getStage() == EShLangCompute &&
(glslangIntermediate->getLayoutDerivativeModeNone() != glslang::LayoutDerivativeNone))
#endif
) {
// we need to invent the default lod for an explicit lod instruction for a non-fragment stage // we need to invent the default lod for an explicit lod instruction for a non-fragment stage
noImplicitLod = true; noImplicitLod = true;
} }
@ -5192,8 +5245,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD
builder.promoteScalar(decorations.precision, left, right); builder.promoteScalar(decorations.precision, left, right);
spv::Id result = builder.createBinOp(binOp, typeId, left, right); spv::Id result = builder.createBinOp(binOp, typeId, left, right);
builder.addDecoration(result, decorations.noContraction); decorations.addNoContraction(builder, result);
builder.addDecoration(result, decorations.nonUniform); decorations.addNonUniform(builder, result);
return builder.setPrecision(result, decorations.precision); return builder.setPrecision(result, decorations.precision);
} }
@ -5205,7 +5258,7 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD
if (reduceComparison && (op == glslang::EOpEqual || op == glslang::EOpNotEqual) if (reduceComparison && (op == glslang::EOpEqual || op == glslang::EOpNotEqual)
&& (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left))) { && (builder.isVector(left) || builder.isMatrix(left) || builder.isAggregate(left))) {
spv::Id result = builder.createCompositeCompare(decorations.precision, left, right, op == glslang::EOpEqual); spv::Id result = builder.createCompositeCompare(decorations.precision, left, right, op == glslang::EOpEqual);
builder.addDecoration(result, decorations.nonUniform); decorations.addNonUniform(builder, result);
return result; return result;
} }
@ -5266,8 +5319,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryOperation(glslang::TOperator op, OpD
if (binOp != spv::OpNop) { if (binOp != spv::OpNop) {
spv::Id result = builder.createBinOp(binOp, typeId, left, right); spv::Id result = builder.createBinOp(binOp, typeId, left, right);
builder.addDecoration(result, decorations.noContraction); decorations.addNoContraction(builder, result);
builder.addDecoration(result, decorations.nonUniform); decorations.addNonUniform(builder, result);
return builder.setPrecision(result, decorations.precision); return builder.setPrecision(result, decorations.precision);
} }
@ -5331,8 +5384,8 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora
if (firstClass) { if (firstClass) {
spv::Id result = builder.createBinOp(op, typeId, left, right); spv::Id result = builder.createBinOp(op, typeId, left, right);
builder.addDecoration(result, decorations.noContraction); decorations.addNoContraction(builder, result);
builder.addDecoration(result, decorations.nonUniform); decorations.addNonUniform(builder, result);
return builder.setPrecision(result, decorations.precision); return builder.setPrecision(result, decorations.precision);
} }
@ -5371,14 +5424,14 @@ spv::Id TGlslangToSpvTraverser::createBinaryMatrixOperation(spv::Op op, OpDecora
spv::Id leftVec = leftMat ? builder.createCompositeExtract( left, vecType, indexes) : smearVec; spv::Id leftVec = leftMat ? builder.createCompositeExtract( left, vecType, indexes) : smearVec;
spv::Id rightVec = rightMat ? builder.createCompositeExtract(right, vecType, indexes) : smearVec; spv::Id rightVec = rightMat ? builder.createCompositeExtract(right, vecType, indexes) : smearVec;
spv::Id result = builder.createBinOp(op, vecType, leftVec, rightVec); spv::Id result = builder.createBinOp(op, vecType, leftVec, rightVec);
builder.addDecoration(result, decorations.noContraction); decorations.addNoContraction(builder, result);
builder.addDecoration(result, decorations.nonUniform); decorations.addNonUniform(builder, result);
results.push_back(builder.setPrecision(result, decorations.precision)); results.push_back(builder.setPrecision(result, decorations.precision));
} }
// put the pieces together // put the pieces together
spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision); spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision);
builder.addDecoration(result, decorations.nonUniform); decorations.addNonUniform(builder, result);
return result; return result;
} }
default: default:
@ -5556,6 +5609,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
case glslang::EOpUnpackHalf2x16: case glslang::EOpUnpackHalf2x16:
libCall = spv::GLSLstd450UnpackHalf2x16; libCall = spv::GLSLstd450UnpackHalf2x16;
break; break;
#ifndef GLSLANG_WEB
case glslang::EOpPackSnorm4x8: case glslang::EOpPackSnorm4x8:
libCall = spv::GLSLstd450PackSnorm4x8; libCall = spv::GLSLstd450PackSnorm4x8;
break; break;
@ -5574,6 +5628,7 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
case glslang::EOpUnpackDouble2x32: case glslang::EOpUnpackDouble2x32:
libCall = spv::GLSLstd450UnpackDouble2x32; libCall = spv::GLSLstd450UnpackDouble2x32;
break; break;
#endif
case glslang::EOpPackInt2x32: case glslang::EOpPackInt2x32:
case glslang::EOpUnpackInt2x32: case glslang::EOpUnpackInt2x32:
@ -5784,8 +5839,8 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
id = builder.createUnaryOp(unaryOp, typeId, operand); id = builder.createUnaryOp(unaryOp, typeId, operand);
} }
builder.addDecoration(id, decorations.noContraction); decorations.addNoContraction(builder, id);
builder.addDecoration(id, decorations.nonUniform); decorations.addNonUniform(builder, id);
return builder.setPrecision(id, decorations.precision); return builder.setPrecision(id, decorations.precision);
} }
@ -5813,14 +5868,14 @@ spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, OpDecorat
indexes.push_back(c); indexes.push_back(c);
spv::Id srcVec = builder.createCompositeExtract(operand, srcVecType, indexes); spv::Id srcVec = builder.createCompositeExtract(operand, srcVecType, indexes);
spv::Id destVec = builder.createUnaryOp(op, destVecType, srcVec); spv::Id destVec = builder.createUnaryOp(op, destVecType, srcVec);
builder.addDecoration(destVec, decorations.noContraction); decorations.addNoContraction(builder, destVec);
builder.addDecoration(destVec, decorations.nonUniform); decorations.addNonUniform(builder, destVec);
results.push_back(builder.setPrecision(destVec, decorations.precision)); results.push_back(builder.setPrecision(destVec, decorations.precision));
} }
// put the pieces together // put the pieces together
spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision); spv::Id result = builder.setPrecision(builder.createCompositeConstruct(typeId, results), decorations.precision);
builder.addDecoration(result, decorations.nonUniform); decorations.addNonUniform(builder, result);
return result; return result;
} }
@ -5929,30 +5984,32 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora
case glslang::EOpConvBoolToInt: case glslang::EOpConvBoolToInt:
case glslang::EOpConvBoolToInt64: case glslang::EOpConvBoolToInt64:
if (op == glslang::EOpConvBoolToInt64) #ifndef GLSLANG_WEB
if (op == glslang::EOpConvBoolToInt64) {
zero = builder.makeInt64Constant(0); zero = builder.makeInt64Constant(0);
else
zero = builder.makeIntConstant(0);
if (op == glslang::EOpConvBoolToInt64)
one = builder.makeInt64Constant(1); one = builder.makeInt64Constant(1);
else } else
#endif
{
zero = builder.makeIntConstant(0);
one = builder.makeIntConstant(1); one = builder.makeIntConstant(1);
}
convOp = spv::OpSelect; convOp = spv::OpSelect;
break; break;
case glslang::EOpConvBoolToUint: case glslang::EOpConvBoolToUint:
case glslang::EOpConvBoolToUint64: case glslang::EOpConvBoolToUint64:
if (op == glslang::EOpConvBoolToUint64) #ifndef GLSLANG_WEB
if (op == glslang::EOpConvBoolToUint64) {
zero = builder.makeUint64Constant(0); zero = builder.makeUint64Constant(0);
else
zero = builder.makeUintConstant(0);
if (op == glslang::EOpConvBoolToUint64)
one = builder.makeUint64Constant(1); one = builder.makeUint64Constant(1);
else } else
#endif
{
zero = builder.makeUintConstant(0);
one = builder.makeUintConstant(1); one = builder.makeUintConstant(1);
}
convOp = spv::OpSelect; convOp = spv::OpSelect;
break; break;
@ -6241,7 +6298,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora
result = builder.createUnaryOp(convOp, destType, operand); result = builder.createUnaryOp(convOp, destType, operand);
result = builder.setPrecision(result, decorations.precision); result = builder.setPrecision(result, decorations.precision);
builder.addDecoration(result, decorations.nonUniform); decorations.addNonUniform(builder, result);
return result; return result;
} }
@ -6344,7 +6401,9 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv
scopeId = builder.makeUintConstant(spv::ScopeDevice); scopeId = builder.makeUintConstant(spv::ScopeDevice);
} }
// semantics default to relaxed // semantics default to relaxed
spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.volatil ? spv::MemorySemanticsVolatileMask : spv::MemorySemanticsMaskNone); spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.isVolatile() ?
spv::MemorySemanticsVolatileMask :
spv::MemorySemanticsMaskNone);
spv::Id semanticsId2 = semanticsId; spv::Id semanticsId2 = semanticsId;
pointerId = operands[0]; pointerId = operands[0];
@ -7378,6 +7437,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
} }
} }
#ifndef GLSLANG_WEB
// Decode the return types that were structures // Decode the return types that were structures
switch (op) { switch (op) {
case glslang::EOpAddCarry: case glslang::EOpAddCarry:
@ -7407,6 +7467,7 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
default: default:
break; break;
} }
#endif
return builder.setPrecision(id, precision); return builder.setPrecision(id, precision);
} }
@ -7589,13 +7650,13 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
builder.addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier())); builder.addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier()));
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
addMeshNVDecoration(id, /*member*/ -1, symbol->getType().getQualifier()); addMeshNVDecoration(id, /*member*/ -1, symbol->getType().getQualifier());
if (symbol->getQualifier().hasComponent())
builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent);
if (symbol->getQualifier().hasIndex())
builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex);
#endif #endif
if (symbol->getType().getQualifier().hasSpecConstantId()) if (symbol->getType().getQualifier().hasSpecConstantId())
builder.addDecoration(id, spv::DecorationSpecId, symbol->getType().getQualifier().layoutSpecConstantId); builder.addDecoration(id, spv::DecorationSpecId, symbol->getType().getQualifier().layoutSpecConstantId);
if (symbol->getQualifier().hasIndex())
builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex);
if (symbol->getQualifier().hasComponent())
builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent);
// atomic counters use this: // atomic counters use this:
if (symbol->getQualifier().hasOffset()) if (symbol->getQualifier().hasOffset())
builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutOffset); builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutOffset);
@ -7622,7 +7683,6 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
} }
if (symbol->getQualifier().hasAttachment()) if (symbol->getQualifier().hasAttachment())
builder.addDecoration(id, spv::DecorationInputAttachmentIndex, symbol->getQualifier().layoutAttachment); builder.addDecoration(id, spv::DecorationInputAttachmentIndex, symbol->getQualifier().layoutAttachment);
#ifndef GLSLANG_WEB
if (glslangIntermediate->getXfbMode()) { if (glslangIntermediate->getXfbMode()) {
builder.addCapability(spv::CapabilityTransformFeedback); builder.addCapability(spv::CapabilityTransformFeedback);
if (symbol->getQualifier().hasXfbBuffer()) { if (symbol->getQualifier().hasXfbBuffer()) {
@ -7634,8 +7694,13 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
if (symbol->getQualifier().hasXfbOffset()) if (symbol->getQualifier().hasXfbOffset())
builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutXfbOffset); builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutXfbOffset);
} }
#endif
// add built-in variable decoration
if (builtIn != spv::BuiltInMax) {
builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
}
#ifndef GLSLANG_WEB
if (symbol->getType().isImage()) { if (symbol->getType().isImage()) {
std::vector<spv::Decoration> memory; std::vector<spv::Decoration> memory;
TranslateMemoryDecoration(symbol->getType().getQualifier(), memory, glslangIntermediate->usingVulkanMemoryModel()); TranslateMemoryDecoration(symbol->getType().getQualifier(), memory, glslangIntermediate->usingVulkanMemoryModel());
@ -7643,15 +7708,9 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
builder.addDecoration(id, memory[i]); builder.addDecoration(id, memory[i]);
} }
// add built-in variable decoration
if (builtIn != spv::BuiltInMax) {
builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
}
// nonuniform // nonuniform
builder.addDecoration(id, TranslateNonUniformDecoration(symbol->getType().getQualifier())); builder.addDecoration(id, TranslateNonUniformDecoration(symbol->getType().getQualifier()));
#ifndef GLSLANG_WEB
if (builtIn == spv::BuiltInSampleMask) { if (builtIn == spv::BuiltInSampleMask) {
spv::Decoration decoration; spv::Decoration decoration;
// GL_NV_sample_mask_override_coverage extension // GL_NV_sample_mask_override_coverage extension
@ -7690,7 +7749,6 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
builder.addCapability(spv::CapabilityFragmentBarycentricNV); builder.addCapability(spv::CapabilityFragmentBarycentricNV);
builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric); builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric);
} }
#endif
if (glslangIntermediate->getHlslFunctionality1() && symbol->getType().getQualifier().semanticName != nullptr) { if (glslangIntermediate->getHlslFunctionality1() && symbol->getType().getQualifier().semanticName != nullptr) {
builder.addExtension("SPV_GOOGLE_hlsl_functionality1"); builder.addExtension("SPV_GOOGLE_hlsl_functionality1");
@ -7701,6 +7759,7 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
if (symbol->isReference()) { if (symbol->isReference()) {
builder.addDecoration(id, symbol->getType().getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT); builder.addDecoration(id, symbol->getType().getQualifier().restrict ? spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT);
} }
#endif
return id; return id;
} }

View File

@ -528,6 +528,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type)); constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
module.mapInstruction(type); module.mapInstruction(type);
#ifndef GLSLANG_WEB
// deal with capabilities // deal with capabilities
switch (dim) { switch (dim) {
case DimBuffer: case DimBuffer:
@ -573,6 +574,7 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
addCapability(CapabilityImageMSArray); addCapability(CapabilityImageMSArray);
} }
} }
#endif
return type->getResultId(); return type->getResultId();
} }
@ -1018,9 +1020,16 @@ Id Builder::makeFloat16Constant(float f16, bool specConstant)
Id Builder::makeFpConstant(Id type, double d, bool specConstant) Id Builder::makeFpConstant(Id type, double d, bool specConstant)
{ {
#ifdef GLSLANG_WEB
const int width = 32;
assert(width == getScalarTypeWidth(type));
#else
const int width = getScalarTypeWidth(type);
#endif
assert(isFloatType(type)); assert(isFloatType(type));
switch (getScalarTypeWidth(type)) { switch (width) {
case 16: case 16:
return makeFloat16Constant((float)d, specConstant); return makeFloat16Constant((float)d, specConstant);
case 32: case 32:
@ -1895,6 +1904,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask); mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);
texArgs[numArgs++] = parameters.offsets; texArgs[numArgs++] = parameters.offsets;
} }
#ifndef GLSLANG_WEB
if (parameters.sample) { if (parameters.sample) {
mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask); mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
texArgs[numArgs++] = parameters.sample; texArgs[numArgs++] = parameters.sample;
@ -1912,6 +1922,7 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
if (parameters.volatil) { if (parameters.volatil) {
mask = mask | ImageOperandsVolatileTexelKHRMask; mask = mask | ImageOperandsVolatileTexelKHRMask;
} }
#endif
mask = mask | signExtensionMask; mask = mask | signExtensionMask;
if (mask == ImageOperandsMaskNone) if (mask == ImageOperandsMaskNone)
--numArgs; // undo speculative reservation for the mask argument --numArgs; // undo speculative reservation for the mask argument
@ -2302,7 +2313,12 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
int numRows = getTypeNumRows(resultTypeId); int numRows = getTypeNumRows(resultTypeId);
Instruction* instr = module.getInstruction(componentTypeId); Instruction* instr = module.getInstruction(componentTypeId);
unsigned bitCount = instr->getImmediateOperand(0); #ifdef GLSLANG_WEB
const unsigned bitCount = 32;
assert(bitcount == instr->getImmediateOperand(0));
#else
const unsigned bitCount = instr->getImmediateOperand(0);
#endif
// Optimize matrix constructed from a bigger matrix // Optimize matrix constructed from a bigger matrix
if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) { if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) {

View File

@ -201,7 +201,11 @@ public:
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; } bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; } bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
bool isArrayType(Id typeId) const { return getTypeClass(typeId) == OpTypeArray; } bool isArrayType(Id typeId) const { return getTypeClass(typeId) == OpTypeArray; }
#ifdef GLSLANG_WEB
bool isCooperativeMatrixType(Id typeId)const { return false; }
#else
bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; } bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; }
#endif
bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); } bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; } bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; } bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
@ -557,6 +561,14 @@ public:
// Accumulate whether anything in the chain of structures has coherent decorations. // Accumulate whether anything in the chain of structures has coherent decorations.
struct CoherentFlags { struct CoherentFlags {
CoherentFlags() { clear(); }
#ifdef GLSLANG_WEB
void clear() { }
bool isVolatile() const { return false; }
CoherentFlags operator |=(const CoherentFlags &other) { return *this; }
#else
bool isVolatile() const { return volatil; }
unsigned coherent : 1; unsigned coherent : 1;
unsigned devicecoherent : 1; unsigned devicecoherent : 1;
unsigned queuefamilycoherent : 1; unsigned queuefamilycoherent : 1;
@ -577,7 +589,6 @@ public:
isImage = 0; isImage = 0;
} }
CoherentFlags() { clear(); }
CoherentFlags operator |=(const CoherentFlags &other) { CoherentFlags operator |=(const CoherentFlags &other) {
coherent |= other.coherent; coherent |= other.coherent;
devicecoherent |= other.devicecoherent; devicecoherent |= other.devicecoherent;
@ -589,6 +600,7 @@ public:
isImage |= other.isImage; isImage |= other.isImage;
return *this; return *this;
} }
#endif
}; };
CoherentFlags coherentFlags; CoherentFlags coherentFlags;
}; };

View File

@ -58,8 +58,8 @@ using depth_greater
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "PixelShaderFunction" 18 EntryPoint Fragment 4 "PixelShaderFunction" 18
ExecutionMode 4 OriginUpperLeft ExecutionMode 4 OriginUpperLeft
ExecutionMode 4 DepthGreater
ExecutionMode 4 DepthReplacing ExecutionMode 4 DepthReplacing
ExecutionMode 4 DepthGreater
Source HLSL 500 Source HLSL 500
Name 4 "PixelShaderFunction" Name 4 "PixelShaderFunction"
Name 10 "@PixelShaderFunction(f1;" Name 10 "@PixelShaderFunction(f1;"

View File

@ -50,8 +50,8 @@ using depth_less
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "PixelShaderFunction" 14 EntryPoint Fragment 4 "PixelShaderFunction" 14
ExecutionMode 4 OriginUpperLeft ExecutionMode 4 OriginUpperLeft
ExecutionMode 4 DepthLess
ExecutionMode 4 DepthReplacing ExecutionMode 4 DepthReplacing
ExecutionMode 4 DepthLess
Source HLSL 500 Source HLSL 500
Name 4 "PixelShaderFunction" Name 4 "PixelShaderFunction"
Name 8 "@PixelShaderFunction(" Name 8 "@PixelShaderFunction("

View File

@ -170,8 +170,8 @@ using depth_greater
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 22 27 31 36 45 48 51 55 EntryPoint Fragment 4 "main" 22 27 31 36 45 48 51 55
ExecutionMode 4 OriginUpperLeft ExecutionMode 4 OriginUpperLeft
ExecutionMode 4 DepthGreater
ExecutionMode 4 DepthReplacing ExecutionMode 4 DepthReplacing
ExecutionMode 4 DepthGreater
Source HLSL 500 Source HLSL 500
Name 4 "main" Name 4 "main"
Name 8 "T" Name 8 "T"

View File

@ -1 +1 @@
598528 ../build/install/bin/glslangValidator.exe 409600 ../build/install/bin/glslangValidator.exe

View File

@ -8,8 +8,8 @@ spv.depthOut.frag
MemoryModel Logical GLSL450 MemoryModel Logical GLSL450
EntryPoint Fragment 4 "main" 8 10 14 EntryPoint Fragment 4 "main" 8 10 14
ExecutionMode 4 OriginUpperLeft ExecutionMode 4 OriginUpperLeft
ExecutionMode 4 DepthGreater
ExecutionMode 4 DepthReplacing ExecutionMode 4 DepthReplacing
ExecutionMode 4 DepthGreater
Source GLSL 450 Source GLSL 450
Name 4 "main" Name 4 "main"
Name 8 "gl_FragDepth" Name 8 "gl_FragDepth"

View File

@ -527,7 +527,8 @@ __inline bool isTypeFloat(TBasicType type)
} }
} }
__inline int getTypeRank(TBasicType type) { __inline int getTypeRank(TBasicType type)
{
int res = -1; int res = -1;
switch(type) { switch(type) {
case EbtInt8: case EbtInt8:

View File

@ -79,18 +79,27 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
bool ms : 1; bool ms : 1;
bool image : 1; // image, combined should be false bool image : 1; // image, combined should be false
bool combined : 1; // true means texture is combined with a sampler, false means texture with no sampler bool combined : 1; // true means texture is combined with a sampler, false means texture with no sampler
bool sampler : 1; // true means a pure sampler, other fields should be clear() #ifdef ENABLE_HLSL
bool external : 1; // GL_OES_EGL_image_external
bool yuv : 1; // GL_EXT_YUV_target
unsigned int vectorSize : 3; // vector return type size. unsigned int vectorSize : 3; // vector return type size.
// Encapsulate getting members' vector sizes packed into the vectorSize bitfield.
unsigned int getVectorSize() const { return vectorSize; } unsigned int getVectorSize() const { return vectorSize; }
void clearReturnStruct() { structReturnIndex = noReturnStruct; }
bool hasReturnStruct() const { return structReturnIndex != noReturnStruct; }
unsigned getStructReturnIndex() const { return structReturnIndex; }
#ifdef GLSLANG_WEB static const unsigned structReturnIndexBits = 4; // number of index bits to use.
static const unsigned structReturnSlots = (1<<structReturnIndexBits)-1; // number of valid values
static const unsigned noReturnStruct = structReturnSlots; // value if no return struct type.
// Index into a language specific table of texture return structures.
unsigned int structReturnIndex : structReturnIndexBits;
#else
unsigned int getVectorSize() const { return 4; }
void clearReturnStruct() const { } void clearReturnStruct() const { }
bool hasReturnStruct() const { return false; } bool hasReturnStruct() const { return false; }
unsigned getStructReturnIndex() const { return 0; } unsigned getStructReturnIndex() const { return 0; }
#endif
#ifdef GLSLANG_WEB
bool is1D() const { return false; } bool is1D() const { return false; }
bool isBuffer() const { return false; } bool isBuffer() const { return false; }
bool isRect() const { return false; } bool isRect() const { return false; }
@ -105,18 +114,12 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
void setExternal(bool e) { } void setExternal(bool e) { }
bool isYuv() const { return false; } bool isYuv() const { return false; }
#else #else
bool sampler : 1; // true means a pure sampler, other fields should be clear()
bool external : 1; // GL_OES_EGL_image_external
bool yuv : 1; // GL_EXT_YUV_target
// Some languages support structures as sample results. Storing the whole structure in the // Some languages support structures as sample results. Storing the whole structure in the
// TSampler is too large, so there is an index to a separate table. // TSampler is too large, so there is an index to a separate table.
static const unsigned structReturnIndexBits = 4; // number of index bits to use.
static const unsigned structReturnSlots = (1<<structReturnIndexBits)-1; // number of valid values
static const unsigned noReturnStruct = structReturnSlots; // value if no return struct type.
// Index into a language specific table of texture return structures.
unsigned int structReturnIndex : structReturnIndexBits;
void clearReturnStruct() { structReturnIndex = noReturnStruct; }
bool hasReturnStruct() const { return structReturnIndex != noReturnStruct; }
unsigned getStructReturnIndex() const { return structReturnIndex; }
bool is1D() const { return dim == Esd1D; } bool is1D() const { return dim == Esd1D; }
bool isBuffer() const { return dim == EsdBuffer; } bool isBuffer() const { return dim == EsdBuffer; }
bool isRect() const { return dim == EsdRect; } bool isRect() const { return dim == EsdRect; }
@ -144,13 +147,17 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
ms = false; ms = false;
image = false; image = false;
combined = false; combined = false;
#ifndef GLSLANG_WEB
sampler = false; sampler = false;
external = false; external = false;
yuv = false; yuv = false;
clearReturnStruct(); #endif
#ifdef ENABLE_HLSL
clearReturnStruct();
// by default, returns a single vec4; // by default, returns a single vec4;
vectorSize = 4; vectorSize = 4;
#endif
} }
// make a combined sampler and texture // make a combined sampler and texture
@ -188,6 +195,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
ms = m; ms = m;
} }
#ifndef GLSLANG_WEB
// make a subpass input attachment // make a subpass input attachment
void setSubpass(TBasicType t, bool m = false) void setSubpass(TBasicType t, bool m = false)
{ {
@ -205,6 +213,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
sampler = true; sampler = true;
shadow = s; shadow = s;
} }
#endif
bool operator==(const TSampler& right) const bool operator==(const TSampler& right) const
{ {
@ -218,7 +227,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
isPureSampler() == right.isPureSampler() && isPureSampler() == right.isPureSampler() &&
isExternal() == right.isExternal() && isExternal() == right.isExternal() &&
isYuv() == right.isYuv() && isYuv() == right.isYuv() &&
vectorSize == right.vectorSize && getVectorSize() == right.getVectorSize() &&
getStructReturnIndex() == right.getStructReturnIndex(); getStructReturnIndex() == right.getStructReturnIndex();
} }
@ -495,8 +504,10 @@ public:
void clearInterstage() void clearInterstage()
{ {
clearInterpolation(); clearInterpolation();
#ifndef GLSLANG_WEB
patch = false; patch = false;
sample = false; sample = false;
#endif
} }
void clearInterpolation() void clearInterpolation()
@ -552,17 +563,6 @@ public:
bool centroid : 1; bool centroid : 1;
bool smooth : 1; bool smooth : 1;
bool flat : 1; bool flat : 1;
#ifndef GLSLANG_WEB
bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
bool nopersp : 1;
bool explicitInterp : 1;
bool pervertexNV : 1;
bool perPrimitiveNV : 1;
bool perViewNV : 1;
bool perTaskNV : 1;
#endif
bool patch : 1;
bool sample : 1;
bool coherent : 1; bool coherent : 1;
bool devicecoherent : 1; bool devicecoherent : 1;
bool queuefamilycoherent : 1; bool queuefamilycoherent : 1;
@ -573,10 +573,12 @@ public:
bool restrict : 1; bool restrict : 1;
bool readonly : 1; bool readonly : 1;
bool writeonly : 1; bool writeonly : 1;
bool specConstant : 1; // having a constant_id is not sufficient: expressions have no id, but are still specConstant // having a constant_id is not sufficient: expressions have no id, but are still specConstant
bool specConstant : 1;
bool nonUniform : 1; bool nonUniform : 1;
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
bool isSample() const { return false; }
bool isMemory() const { return false; } bool isMemory() const { return false; }
bool isMemoryQualifierImageAndSSBOOnly() const { return false; } bool isMemoryQualifierImageAndSSBOOnly() const { return false; }
bool bufferReferenceNeedsVulkanMemoryModel() const { return false; } bool bufferReferenceNeedsVulkanMemoryModel() const { return false; }
@ -588,6 +590,16 @@ public:
void setNoContraction() { } void setNoContraction() { }
bool isPervertexNV() const { return false; } bool isPervertexNV() const { return false; }
#else #else
bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
bool nopersp : 1;
bool explicitInterp : 1;
bool pervertexNV : 1;
bool perPrimitiveNV : 1;
bool perViewNV : 1;
bool perTaskNV : 1;
bool patch : 1;
bool sample : 1;
bool isSample() const { return sample; }
bool isMemory() const bool isMemory() const
{ {
return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly || nonprivate; return subgroupcoherent || workgroupcoherent || queuefamilycoherent || devicecoherent || coherent || volatil || restrict || readonly || writeonly || nonprivate;
@ -1592,9 +1604,9 @@ public:
virtual TIntermTyped* getOuterArrayNode() const { return arraySizes->getOuterNode(); } virtual TIntermTyped* getOuterArrayNode() const { return arraySizes->getOuterNode(); }
virtual int getCumulativeArraySize() const { return arraySizes->getCumulativeSize(); } virtual int getCumulativeArraySize() const { return arraySizes->getCumulativeSize(); }
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
virtual bool isArrayOfArrays() const { return false; } bool isArrayOfArrays() const { return false; }
#else #else
virtual bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; } bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; }
#endif #endif
virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); } virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); }
virtual const TArraySizes* getArraySizes() const { return arraySizes; } virtual const TArraySizes* getArraySizes() const { return arraySizes; }
@ -1646,11 +1658,11 @@ public:
virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); } virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); }
virtual bool isParameterized() const { return typeParameters != nullptr; } virtual bool isParameterized() const { return typeParameters != nullptr; }
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
virtual bool isCoopMat() const { return false; } bool isCoopMat() const { return false; }
virtual bool isReference() const { return false; } bool isReference() const { return false; }
#else #else
virtual bool isCoopMat() const { return coopmat; } bool isCoopMat() const { return coopmat; }
virtual bool isReference() const { return getBasicType() == EbtReference; } bool isReference() const { return getBasicType() == EbtReference; }
#endif #endif
// return true if this type contains any subtype which satisfies the given predicate. // return true if this type contains any subtype which satisfies the given predicate.
@ -1733,39 +1745,39 @@ public:
} }
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
virtual bool containsDouble() const { return false; } bool containsDouble() const { return false; }
virtual bool contains16BitFloat() const { return false; } bool contains16BitFloat() const { return false; }
virtual bool contains64BitInt() const { return false; } bool contains64BitInt() const { return false; }
virtual bool contains16BitInt() const { return false; } bool contains16BitInt() const { return false; }
virtual bool contains8BitInt() const { return false; } bool contains8BitInt() const { return false; }
virtual bool containsCoopMat() const { return false; } bool containsCoopMat() const { return false; }
virtual bool containsReference() const { return false; } bool containsReference() const { return false; }
#else #else
virtual bool containsDouble() const bool containsDouble() const
{ {
return containsBasicType(EbtDouble); return containsBasicType(EbtDouble);
} }
virtual bool contains16BitFloat() const bool contains16BitFloat() const
{ {
return containsBasicType(EbtFloat16); return containsBasicType(EbtFloat16);
} }
virtual bool contains64BitInt() const bool contains64BitInt() const
{ {
return containsBasicType(EbtInt64) || containsBasicType(EbtUint64); return containsBasicType(EbtInt64) || containsBasicType(EbtUint64);
} }
virtual bool contains16BitInt() const bool contains16BitInt() const
{ {
return containsBasicType(EbtInt16) || containsBasicType(EbtUint16); return containsBasicType(EbtInt16) || containsBasicType(EbtUint16);
} }
virtual bool contains8BitInt() const bool contains8BitInt() const
{ {
return containsBasicType(EbtInt8) || containsBasicType(EbtUint8); return containsBasicType(EbtInt8) || containsBasicType(EbtUint8);
} }
virtual bool containsCoopMat() const bool containsCoopMat() const
{ {
return contains([](const TType* t) { return t->coopmat; } ); return contains([](const TType* t) { return t->coopmat; } );
} }
virtual bool containsReference() const bool containsReference() const
{ {
return containsBasicType(EbtReference); return containsBasicType(EbtReference);
} }

View File

@ -1354,10 +1354,6 @@ public:
case EOpTexture: case EOpTexture:
case EOpSparseTexture: case EOpSparseTexture:
break; break;
case EOpTextureClamp:
case EOpSparseTextureClamp:
cracked.lodClamp = true;
break;
case EOpTextureProj: case EOpTextureProj:
cracked.proj = true; cracked.proj = true;
break; break;
@ -1369,11 +1365,6 @@ public:
case EOpSparseTextureOffset: case EOpSparseTextureOffset:
cracked.offset = true; cracked.offset = true;
break; break;
case EOpTextureOffsetClamp:
case EOpSparseTextureOffsetClamp:
cracked.offset = true;
cracked.lodClamp = true;
break;
case EOpTextureFetch: case EOpTextureFetch:
case EOpSparseTextureFetch: case EOpSparseTextureFetch:
cracked.fetch = true; cracked.fetch = true;
@ -1409,11 +1400,6 @@ public:
case EOpSparseTextureGrad: case EOpSparseTextureGrad:
cracked.grad = true; cracked.grad = true;
break; break;
case EOpTextureGradClamp:
case EOpSparseTextureGradClamp:
cracked.grad = true;
cracked.lodClamp = true;
break;
case EOpTextureGradOffset: case EOpTextureGradOffset:
case EOpSparseTextureGradOffset: case EOpSparseTextureGradOffset:
cracked.grad = true; cracked.grad = true;
@ -1428,6 +1414,21 @@ public:
cracked.offset = true; cracked.offset = true;
cracked.proj = true; cracked.proj = true;
break; break;
#ifndef GLSLANG_WEB
case EOpTextureClamp:
case EOpSparseTextureClamp:
cracked.lodClamp = true;
break;
case EOpTextureOffsetClamp:
case EOpSparseTextureOffsetClamp:
cracked.offset = true;
cracked.lodClamp = true;
break;
case EOpTextureGradClamp:
case EOpSparseTextureGradClamp:
cracked.grad = true;
cracked.lodClamp = true;
break;
case EOpTextureGradOffsetClamp: case EOpTextureGradOffsetClamp:
case EOpSparseTextureGradOffsetClamp: case EOpSparseTextureGradOffsetClamp:
cracked.grad = true; cracked.grad = true;
@ -1497,6 +1498,7 @@ public:
case EOpSubpassLoadMS: case EOpSubpassLoadMS:
cracked.subpass = true; cracked.subpass = true;
break; break;
#endif
default: default:
break; break;
} }

View File

@ -153,13 +153,13 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
case EvqConst: message = "can't modify a const"; break; case EvqConst: message = "can't modify a const"; break;
case EvqConstReadOnly: message = "can't modify a const"; break; case EvqConstReadOnly: message = "can't modify a const"; break;
case EvqUniform: message = "can't modify a uniform"; break; case EvqUniform: message = "can't modify a uniform"; break;
#ifndef GLSLANG_WEB
case EvqBuffer: case EvqBuffer:
if (node->getQualifier().readonly) if (node->getQualifier().readonly)
message = "can't modify a readonly buffer"; message = "can't modify a readonly buffer";
if (node->getQualifier().isShaderRecordNV()) if (node->getQualifier().isShaderRecordNV())
message = "can't modify a shaderrecordnv qualified buffer"; message = "can't modify a shaderrecordnv qualified buffer";
break; break;
#ifndef GLSLANG_WEB
case EvqHitAttrNV: case EvqHitAttrNV:
if (language != EShLangIntersectNV) if (language != EShLangIntersectNV)
message = "cannot modify hitAttributeNV in this stage"; message = "cannot modify hitAttributeNV in this stage";

View File

@ -1147,6 +1147,7 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", ""); error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", "");
} }
TQualifier& argQualifier = arg->getAsTyped()->getQualifier(); TQualifier& argQualifier = arg->getAsTyped()->getQualifier();
#ifndef GLSLANG_WEB
if (argQualifier.isMemory()) { if (argQualifier.isMemory()) {
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)
@ -1176,7 +1177,7 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
argQualifier.getFormat() != ElfNone)) argQualifier.getFormat() != ElfNone))
error(arguments->getLoc(), "image formats must match", "format", ""); error(arguments->getLoc(), "image formats must match", "format", "");
} }
#endif
if (builtIn && arg->getAsTyped()->getType().contains16BitFloat()) if (builtIn && arg->getAsTyped()->getType().contains16BitFloat())
requireFloat16Arithmetic(arguments->getLoc(), "built-in function", "float16 types can only be in uniform block or buffer storage"); requireFloat16Arithmetic(arguments->getLoc(), "built-in function", "float16 types can only be in uniform block or buffer storage");
if (builtIn && arg->getAsTyped()->getType().contains16BitInt()) if (builtIn && arg->getAsTyped()->getType().contains16BitInt())
@ -7507,7 +7508,7 @@ void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier&
error(loc, "cannot use interpolation qualifiers on an interface block", "flat/smooth/noperspective", ""); error(loc, "cannot use interpolation qualifiers on an interface block", "flat/smooth/noperspective", "");
if (qualifier.centroid) if (qualifier.centroid)
error(loc, "cannot use centroid qualifier on an interface block", "centroid", ""); error(loc, "cannot use centroid qualifier on an interface block", "centroid", "");
if (qualifier.sample) if (qualifier.isSample())
error(loc, "cannot use sample qualifier on an interface block", "sample", ""); error(loc, "cannot use sample qualifier on an interface block", "sample", "");
if (qualifier.invariant) if (qualifier.invariant)
error(loc, "cannot use invariant qualifier on an interface block", "invariant", ""); error(loc, "cannot use invariant qualifier on an interface block", "invariant", "");

View File

@ -538,13 +538,14 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
if (symbol.getQualifier().centroid != unitSymbol.getQualifier().centroid || if (symbol.getQualifier().centroid != unitSymbol.getQualifier().centroid ||
symbol.getQualifier().smooth != unitSymbol.getQualifier().smooth || symbol.getQualifier().smooth != unitSymbol.getQualifier().smooth ||
symbol.getQualifier().flat != unitSymbol.getQualifier().flat || symbol.getQualifier().flat != unitSymbol.getQualifier().flat ||
symbol.getQualifier().sample != unitSymbol.getQualifier().sample || symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() ||
symbol.getQualifier().patch != unitSymbol.getQualifier().patch || symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() ||
symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective()) { symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective()) {
error(infoSink, "Interpolation and auxiliary storage qualifiers must match:"); error(infoSink, "Interpolation and auxiliary storage qualifiers must match:");
writeTypeComparison = true; writeTypeComparison = true;
} }
#ifndef GLSLANG_WEB
// Memory... // Memory...
if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent || if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent ||
symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent || symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent ||
@ -559,6 +560,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
error(infoSink, "Memory qualifiers must match:"); error(infoSink, "Memory qualifiers must match:");
writeTypeComparison = true; writeTypeComparison = true;
} }
#endif
// Layouts... // Layouts...
// TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec // TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec
@ -608,9 +610,6 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
warn(infoSink, "Entry point not found"); warn(infoSink, "Entry point not found");
} }
if (getNumPushConstants() > 1)
error(infoSink, "Only one push_constant block is allowed per stage");
// recursion and missing body checking // recursion and missing body checking
checkCallGraphCycles(infoSink); checkCallGraphCycles(infoSink);
checkCallGraphBodies(infoSink, keepUncalled); checkCallGraphBodies(infoSink, keepUncalled);
@ -619,6 +618,9 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
inOutLocationCheck(infoSink); inOutLocationCheck(infoSink);
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
if (getNumPushConstants() > 1)
error(infoSink, "Only one push_constant block is allowed per stage");
// invocations // invocations
if (invocations == TQualifier::layoutNotSet) if (invocations == TQualifier::layoutNotSet)
invocations = 1; invocations = 1;

View File

@ -481,6 +481,8 @@ public:
bool usingVulkanMemoryModel() const { return false; } bool usingVulkanMemoryModel() const { return false; }
bool usingPhysicalStorageBuffer() const { return false; } bool usingPhysicalStorageBuffer() const { return false; }
bool usingVariablePointers() const { return false; } bool usingVariablePointers() const { return false; }
unsigned getXfbStride(int buffer) const { return 0; }
bool hasLayoutDerivativeModeNone() const { return false; }
#else #else
void output(TInfoSink&, bool tree); void output(TInfoSink&, bool tree);
@ -544,6 +546,7 @@ public:
} }
bool getAutoMapLocations() const { return autoMapLocations; } bool getAutoMapLocations() const { return autoMapLocations; }
#ifdef ENABLE_HLSL
void setFlattenUniformArrays(bool flatten) void setFlattenUniformArrays(bool flatten)
{ {
flattenUniformArrays = flatten; flattenUniformArrays = flatten;
@ -551,6 +554,7 @@ public:
processes.addProcess("flatten-uniform-arrays"); processes.addProcess("flatten-uniform-arrays");
} }
bool getFlattenUniformArrays() const { return flattenUniformArrays; } bool getFlattenUniformArrays() const { return flattenUniformArrays; }
#endif
void setNoStorageFormat(bool b) void setNoStorageFormat(bool b)
{ {
useUnknownFormat = b; useUnknownFormat = b;
@ -576,12 +580,14 @@ public:
} }
bool usingVariablePointers() const { return useVariablePointers; } bool usingVariablePointers() const { return useVariablePointers; }
#ifdef ENABLE_HLSL
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 {
size_t len = strlen(implicitCounterName); size_t len = strlen(implicitCounterName);
return name.size() > len && return name.size() > len &&
name.compare(name.size() - len, len, implicitCounterName) == 0; name.compare(name.size() - len, len, implicitCounterName) == 0;
} }
#endif
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; } void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
int getNumPushConstants() const { return numPushConstants; } int getNumPushConstants() const { return numPushConstants; }
@ -703,6 +709,7 @@ public:
void setGeoPassthroughEXT() { geoPassthroughEXT = true; } void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
bool getGeoPassthroughEXT() const { return geoPassthroughEXT; } bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; } void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
bool hasLayoutDerivativeModeNone() const { return computeDerivativeMode != LayoutDerivativeNone; }
ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; } ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
bool setPrimitives(int m) bool setPrimitives(int m)
{ {

View File

@ -68,30 +68,30 @@ public:
virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc); virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
bool isEsProfile() const { return true; } bool isEsProfile() const { return true; }
virtual void initializeExtensionBehavior() { } void initializeExtensionBehavior() { }
virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc) { } void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc) { }
virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc) { } void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc) { }
virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
const char* featureDesc) { } const char* featureDesc) { }
virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
const char* featureDesc) { } const char* featureDesc) { }
virtual TExtensionBehavior getExtensionBehavior(const char*) { return EBhMissing; } TExtensionBehavior getExtensionBehavior(const char*) { return EBhMissing; }
virtual bool extensionTurnedOn(const char* const extension) { return false; } bool extensionTurnedOn(const char* const extension) { return false; }
virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]) { return false; } bool extensionsTurnedOn(int numExtensions, const char* const extensions[]) { return false; }
virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior) { } void updateExtensionBehavior(int line, const char* const extension, const char* behavior) { }
virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior) { } void updateExtensionBehavior(const char* const extension, TExtensionBehavior) { }
virtual void checkExtensionStage(const TSourceLoc&, const char* const extension) { } void checkExtensionStage(const TSourceLoc&, const char* const extension) { }
virtual void fullIntegerCheck(const TSourceLoc&, const char* op) { } void fullIntegerCheck(const TSourceLoc&, const char* op) { }
virtual void doubleCheck(const TSourceLoc&, const char* op) { } void doubleCheck(const TSourceLoc&, const char* op) { }
virtual bool float16Arithmetic() { return false; } bool float16Arithmetic() { return false; }
virtual void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { } void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
virtual bool int16Arithmetic() { return false; } bool int16Arithmetic() { return false; }
virtual void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { } void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
virtual bool int8Arithmetic() { return false; } bool int8Arithmetic() { return false; }
virtual void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { } void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false) { } void int64Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
virtual void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false) { } void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
virtual void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false) { } void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
#else #else
bool isEsProfile() const { return profile == EEsProfile; } bool isEsProfile() const { return profile == EEsProfile; }
virtual void initializeExtensionBehavior(); virtual void initializeExtensionBehavior();

View File

@ -1085,6 +1085,7 @@ void TReflection::buildAttributeReflection(EShLanguage stage, const TIntermediat
// build counter block index associations for buffers // build counter block index associations for buffers
void TReflection::buildCounterIndices(const TIntermediate& intermediate) void TReflection::buildCounterIndices(const TIntermediate& intermediate)
{ {
#ifdef ENABLE_HLSL
// search for ones that have counters // search for ones that have counters
for (int i = 0; i < int(indexToUniformBlock.size()); ++i) { for (int i = 0; i < int(indexToUniformBlock.size()); ++i) {
const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name).c_str()); const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name).c_str());
@ -1093,6 +1094,7 @@ void TReflection::buildCounterIndices(const TIntermediate& intermediate)
if (index >= 0) if (index >= 0)
indexToUniformBlock[i].counterIndex = index; indexToUniformBlock[i].counterIndex = index;
} }
#endif
} }
// build Shader Stages mask for all uniforms // build Shader Stages mask for all uniforms

View File

@ -434,8 +434,8 @@ public:
void setInvertY(bool invert); void setInvertY(bool invert);
#ifdef ENABLE_HLSL #ifdef ENABLE_HLSL
void setHlslIoMapping(bool hlslIoMap); void setHlslIoMapping(bool hlslIoMap);
#endif
void setFlattenUniformArrays(bool flatten); void setFlattenUniformArrays(bool flatten);
#endif
void setNoStorageFormat(bool useUnknownFormat); void setNoStorageFormat(bool useUnknownFormat);
void setNanMinMaxClamp(bool nanMinMaxClamp); void setNanMinMaxClamp(bool nanMinMaxClamp);
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode); void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);

View File

@ -227,7 +227,9 @@ public:
shader.setAutoMapBindings(true); shader.setAutoMapBindings(true);
} }
shader.setTextureSamplerTransformMode(texSampTransMode); shader.setTextureSamplerTransformMode(texSampTransMode);
#ifdef ENABLE_HLSL
shader.setFlattenUniformArrays(flattenUniformArrays); shader.setFlattenUniformArrays(flattenUniformArrays);
#endif
if (controls & EShMsgSpvRules) { if (controls & EShMsgSpvRules) {
if (controls & EShMsgVulkanRules) { if (controls & EShMsgVulkanRules) {
@ -300,7 +302,9 @@ public:
shader.setShiftSsboBinding(baseSsboBinding); shader.setShiftSsboBinding(baseSsboBinding);
shader.setAutoMapBindings(autoMapBindings); shader.setAutoMapBindings(autoMapBindings);
shader.setAutoMapLocations(true); shader.setAutoMapLocations(true);
#ifdef ENABLE_HLSL
shader.setFlattenUniformArrays(flattenUniformArrays); shader.setFlattenUniformArrays(flattenUniformArrays);
#endif
bool success = compile(&shader, code, entryPointName, controls); bool success = compile(&shader, code, entryPointName, controls);