option(ENABLE_GLSLANG_JS
"If using Emscripten, build glslang.js. Otherwise, builds a sample executable for binary-size testing." OFF)
-CMAKE_DEPENDENT_OPTION(ENABLE_GLSLANG_WEBMIN
- "Reduces glslang to minimum needed for web use"
- OFF "ENABLE_GLSLANG_JS"
- OFF)
-CMAKE_DEPENDENT_OPTION(ENABLE_GLSLANG_WEBMIN_DEVEL
- "For ENABLE_GLSLANG_WEBMIN builds, enables compilation error messages"
- OFF "ENABLE_GLSLANG_WEBMIN"
- OFF)
CMAKE_DEPENDENT_OPTION(ENABLE_EMSCRIPTEN_SINGLE_FILE
"If using Emscripten, enables SINGLE_FILE build"
OFF "ENABLE_GLSLANG_JS AND EMSCRIPTEN"
OFF "ENABLE_GLSLANG_JS AND EMSCRIPTEN"
OFF)
-CMAKE_DEPENDENT_OPTION(ENABLE_HLSL
- "Enables HLSL input support"
- ON "NOT ENABLE_GLSLANG_WEBMIN"
- OFF)
-
+option(ENABLE_HLSL "Enables HLSL input support" ON)
option(ENABLE_RTTI "Enables RTTI" OFF)
option(ENABLE_EXCEPTIONS "Enables Exceptions" OFF)
option(ENABLE_OPT "Enables spirv-opt capability if present" ON)
add_definitions(-DENABLE_HLSL)
endif()
-if(ENABLE_GLSLANG_WEBMIN)
- add_definitions(-DGLSLANG_WEB)
- if(ENABLE_GLSLANG_WEBMIN_DEVEL)
- add_definitions(-DGLSLANG_WEB_DEVEL)
- endif()
-endif()
-
if(WIN32)
set(CMAKE_DEBUG_POSTFIX "d")
option(OVERRIDE_MSVCCRT "Overrides runtime of MSVC " ON)
PATH_EXPORT_TARGETS
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}
)
-
+
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/glslang-config-version.cmake"
VERSION ${GLSLANG_VERSION}
COMPATIBILITY SameMajorVersion
)
-
+
install(
EXPORT glslang-targets
NAMESPACE "glslang::"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
-
+
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/glslang-config.cmake"
* Set `-DBUILD_TESTING=OFF -DENABLE_OPT=OFF -DINSTALL_GTEST=OFF`.
* Set `-DENABLE_HLSL=OFF` if HLSL is not needed.
* For a standalone JS/WASM library, turn on `-DENABLE_GLSLANG_JS=ON`.
-* For building a minimum-size web subset of core glslang:
- + turn on `-DENABLE_GLSLANG_WEBMIN=ON` (disables HLSL)
- + execute `updateGrammar web` from the glslang subdirectory
- (or if using your own scripts, `m4` needs a `-DGLSLANG_WEB` argument)
- + optionally, for GLSL compilation error messages, turn on
- `-DENABLE_GLSLANG_WEBMIN_DEVEL=ON`
* To get a fully minimized build, make sure to use `brotli` to compress the .js
and .wasm files
public:
OpDecorations(spv::Decoration precision, spv::Decoration noContraction, spv::Decoration nonUniform) :
precision(precision)
-#ifndef GLSLANG_WEB
,
noContraction(noContraction),
nonUniform(nonUniform)
-#endif
{ }
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 nonUniform;
-#endif
-
};
} // namespace
// Translate glslang profile to SPIR-V source language.
spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile profile)
{
-#ifdef GLSLANG_WEB
- return spv::SourceLanguageESSL;
-#endif
-
switch (source) {
case glslang::EShSourceGlsl:
switch (profile) {
case EShLangVertex: return spv::ExecutionModelVertex;
case EShLangFragment: return spv::ExecutionModelFragment;
case EShLangCompute: return spv::ExecutionModelGLCompute;
-#ifndef GLSLANG_WEB
case EShLangTessControl: return spv::ExecutionModelTessellationControl;
case EShLangTessEvaluation: return spv::ExecutionModelTessellationEvaluation;
case EShLangGeometry: return spv::ExecutionModelGeometry;
case EShLangCallable: return spv::ExecutionModelCallableKHR;
case EShLangTask: return (isMeshShaderEXT)? spv::ExecutionModelTaskEXT : spv::ExecutionModelTaskNV;
case EShLangMesh: return (isMeshShaderEXT)? spv::ExecutionModelMeshEXT: spv::ExecutionModelMeshNV;
-#endif
default:
assert(0);
return spv::ExecutionModelFragment;
case glslang::EvqVaryingIn: return spv::DecorationBlock;
case glslang::EvqVaryingOut: return spv::DecorationBlock;
case glslang::EvqShared: return spv::DecorationBlock;
-#ifndef GLSLANG_WEB
case glslang::EvqPayload: return spv::DecorationBlock;
case glslang::EvqPayloadIn: return spv::DecorationBlock;
case glslang::EvqHitAttr: return spv::DecorationBlock;
case glslang::EvqCallableData: return spv::DecorationBlock;
case glslang::EvqCallableDataIn: return spv::DecorationBlock;
case glslang::EvqHitObjectAttrNV: return spv::DecorationBlock;
-#endif
default:
assert(0);
break;
assert(type.getQualifier().layoutPacking == glslang::ElpNone);
}
return spv::DecorationMax;
-#ifndef GLSLANG_WEB
case glslang::EvqPayload:
case glslang::EvqPayloadIn:
case glslang::EvqHitAttr:
case glslang::EvqCallableDataIn:
case glslang::EvqHitObjectAttrNV:
return spv::DecorationMax;
-#endif
default:
assert(0);
return spv::DecorationMax;
{
if (qualifier.centroid)
return spv::DecorationCentroid;
-#ifndef GLSLANG_WEB
else if (qualifier.patch)
return spv::DecorationPatch;
else if (qualifier.sample) {
builder.addCapability(spv::CapabilitySampleRateShading);
return spv::DecorationSample;
}
-#endif
return spv::DecorationMax;
}
// If glslang type is noContraction, return SPIR-V NoContraction decoration.
spv::Decoration TranslateNoContractionDecoration(const glslang::TQualifier& qualifier)
{
-#ifndef GLSLANG_WEB
if (qualifier.isNoContraction())
return spv::DecorationNoContraction;
else
-#endif
return spv::DecorationMax;
}
// If glslang type is nonUniform, return SPIR-V NonUniform decoration.
spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glslang::TQualifier& qualifier)
{
-#ifndef GLSLANG_WEB
if (qualifier.isNonUniform()) {
builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
builder.addCapability(spv::CapabilityShaderNonUniformEXT);
return spv::DecorationNonUniformEXT;
} else
-#endif
return spv::DecorationMax;
}
spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(
const spv::Builder::AccessChain::CoherentFlags& coherentFlags)
{
-#ifndef GLSLANG_WEB
if (coherentFlags.isNonUniform()) {
builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
builder.addCapability(spv::CapabilityShaderNonUniformEXT);
return spv::DecorationNonUniformEXT;
} else
-#endif
return spv::DecorationMax;
}
{
spv::MemoryAccessMask mask = spv::MemoryAccessMaskNone;
-#ifndef GLSLANG_WEB
if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage)
return mask;
if (mask != spv::MemoryAccessMaskNone) {
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
}
-#endif
return mask;
}
{
spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone;
-#ifndef GLSLANG_WEB
if (!glslangIntermediate->usingVulkanMemoryModel())
return mask;
if (mask != spv::ImageOperandsMaskNone) {
builder.addCapability(spv::CapabilityVulkanMemoryModelKHR);
}
-#endif
return mask;
}
spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCoherent(const glslang::TType& type)
{
spv::Builder::AccessChain::CoherentFlags flags = {};
-#ifndef GLSLANG_WEB
flags.coherent = type.getQualifier().coherent;
flags.devicecoherent = type.getQualifier().devicecoherent;
flags.queuefamilycoherent = type.getQualifier().queuefamilycoherent;
flags.anyCoherent() ||
flags.volatil;
flags.isImage = type.getBasicType() == glslang::EbtSampler;
-#endif
flags.nonUniform = type.getQualifier().nonUniform;
return flags;
}
{
spv::Scope scope = spv::ScopeMax;
-#ifndef GLSLANG_WEB
if (coherentFlags.volatil || coherentFlags.coherent) {
// coherent defaults to Device scope in the old model, QueueFamilyKHR scope in the new model
scope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
if (glslangIntermediate->usingVulkanMemoryModel() && scope == spv::ScopeDevice) {
builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR);
}
-#endif
return scope;
}
{
switch (builtIn) {
case glslang::EbvPointSize:
-#ifndef GLSLANG_WEB
// Defer adding the capability until the built-in is actually used.
if (! memberDeclaration) {
switch (glslangIntermediate->getStage()) {
break;
}
}
-#endif
return spv::BuiltInPointSize;
case glslang::EbvPosition: return spv::BuiltInPosition;
case glslang::EbvLocalInvocationIndex: return spv::BuiltInLocalInvocationIndex;
case glslang::EbvGlobalInvocationId: return spv::BuiltInGlobalInvocationId;
-#ifndef GLSLANG_WEB
// These *Distance capabilities logically belong here, but if the member is declared and
// then never used, consumers of SPIR-V prefer the capability not be declared.
// They are now generated when used, rather than here when declared.
builder.addExtension(spv::E_SPV_ARM_core_builtins);
builder.addCapability(spv::CapabilityCoreBuiltinsARM);
return spv::BuiltInWarpMaxIDARM;
-#endif
default:
return spv::BuiltInMax;
{
assert(type.getBasicType() == glslang::EbtSampler);
-#ifdef GLSLANG_WEB
- return spv::ImageFormatUnknown;
-#endif
-
// Check for capabilities
switch (type.getQualifier().getFormat()) {
case glslang::ElfRg32f:
{
if (type.getBasicType() == glslang::EbtRayQuery || type.getBasicType() == glslang::EbtHitObjectNV)
return spv::StorageClassPrivate;
-#ifndef GLSLANG_WEB
if (type.getQualifier().isSpirvByReference()) {
if (type.getQualifier().isParamInput() || type.getQualifier().isParamOutput())
return spv::StorageClassFunction;
}
-#endif
if (type.getQualifier().isPipeInput())
return spv::StorageClassInput;
if (type.getQualifier().isPipeOutput())
case glslang::EvqConstReadOnly: return spv::StorageClassFunction;
case glslang::EvqTemporary: return spv::StorageClassFunction;
case glslang::EvqShared: return spv::StorageClassWorkgroup;
-#ifndef GLSLANG_WEB
case glslang::EvqPayload: return spv::StorageClassRayPayloadKHR;
case glslang::EvqPayloadIn: return spv::StorageClassIncomingRayPayloadKHR;
case glslang::EvqHitAttr: return spv::StorageClassHitAttributeKHR;
case glslang::EvqtaskPayloadSharedEXT : return spv::StorageClassTaskPayloadWorkgroupEXT;
case glslang::EvqHitObjectAttrNV: return spv::StorageClassHitObjectAttributeNV;
case glslang::EvqSpirvStorageClass: return static_cast<spv::StorageClass>(type.getQualifier().spirvStorageClass);
-#endif
default:
assert(0);
break;
void TGlslangToSpvTraverser::addIndirectionIndexCapabilities(const glslang::TType& baseType,
const glslang::TType& indexType)
{
-#ifndef GLSLANG_WEB
if (indexType.getQualifier().isNonUniform()) {
// deal with an asserted non-uniform index
// SPV_EXT_descriptor_indexing already added in TranslateNonUniformDecoration
}
}
}
-#endif
}
// Return whether or not the given type is something that should be tied to a
child.flat = true;
if (parent.centroid)
child.centroid = true;
-#ifndef GLSLANG_WEB
if (parent.nopersp)
child.nopersp = true;
if (parent.explicitInterp)
child.readonly = true;
if (parent.writeonly)
child.writeonly = true;
-#endif
if (parent.nonUniform)
child.nonUniform = true;
}
builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR);
}
-#ifndef GLSLANG_WEB
if (glslangIntermediate->getSubgroupUniformControlFlow()) {
builder.addExtension(spv::E_SPV_KHR_subgroup_uniform_control_flow);
builder.addExecutionMode(shaderEntry, spv::ExecutionModeSubgroupUniformControlFlowKHR);
}
-#endif
unsigned int mode;
switch (glslangIntermediate->getStage()) {
if (glslangIntermediate->isStencilReplacing())
builder.addExecutionMode(shaderEntry, spv::ExecutionModeStencilRefReplacingEXT);
-#ifndef GLSLANG_WEB
-
switch(glslangIntermediate->getDepth()) {
case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break;
case glslang::EldLess: mode = spv::ExecutionModeDepthLess; break;
}
builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock);
}
-#endif
break;
case EShLangCompute:
builder.addExtension(spv::E_SPV_NV_compute_shader_derivatives);
}
break;
-#ifndef GLSLANG_WEB
case EShLangTessEvaluation:
case EShLangTessControl:
builder.addCapability(spv::CapabilityTessellation);
builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode);
}
break;
-#endif
default:
break;
}
-#ifndef GLSLANG_WEB
//
// Add SPIR-V requirements (GL_EXT_spirv_intrinsics)
//
builder.addExecutionModeId(shaderEntry, static_cast<spv::ExecutionMode>(modeId.first), operandIds);
}
}
-#endif
}
// Finish creating SPV, after the traversal is complete.
}
};
-#ifndef GLSLANG_WEB
if (node->getOp() == glslang::EOpAtomicCounterIncrement ||
node->getOp() == glslang::EOpAtomicCounterDecrement ||
node->getOp() == glslang::EOpAtomicCounter ||
} else if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) {
// Will be translated to a literal value, make a placeholder here
operand = spv::NoResult;
- } else
-#endif
- {
+ } else {
operand = accessChainLoad(node->getOperand()->getType());
}
result = createUnaryOperation(node->getOp(), decorations, resultType(), operand,
node->getOperand()->getBasicType(), lvalueCoherentFlags);
-#ifndef GLSLANG_WEB
// it could be attached to a SPIR-V intruction
if (!result) {
if (node->getOp() == glslang::EOpSpirvInst) {
return false; // done with this node
}
}
-#endif
if (result) {
if (invertedType) {
spv::Id one = 0;
if (node->getBasicType() == glslang::EbtFloat)
one = builder.makeFloatConstant(1.0F);
-#ifndef GLSLANG_WEB
else if (node->getBasicType() == glslang::EbtDouble)
one = builder.makeDoubleConstant(1.0);
else if (node->getBasicType() == glslang::EbtFloat16)
one = builder.makeInt16Constant(1);
else if (node->getBasicType() == glslang::EbtInt64 || node->getBasicType() == glslang::EbtUint64)
one = builder.makeInt64Constant(1);
-#endif
else
one = builder.makeIntConstant(1);
glslang::TOperator op;
return false;
-#ifndef GLSLANG_WEB
case glslang::EOpEmitStreamVertex:
builder.createNoResultOp(spv::OpEmitStreamVertex, operand);
return false;
case glslang::EOpHitObjectRecordEmptyNV:
builder.createNoResultOp(spv::OpHitObjectRecordEmptyNV, operand);
return false;
-#endif
default:
logger->missingFunctionality("unknown glslang unary");
builder.setAccessChainRValue(result);
return false;
- }
-#ifndef GLSLANG_WEB
- else if (node->getOp() == glslang::EOpImageStore ||
+ } else if (node->getOp() == glslang::EOpImageStore ||
node->getOp() == glslang::EOpImageStoreLod ||
node->getOp() == glslang::EOpImageAtomicStore) {
// "imageStore" is a special case, which has no result
return false;
}
-#endif
glslang::TOperator binOp = glslang::EOpNull;
bool reduceComparison = true;
atomic = true;
break;
-#ifndef GLSLANG_WEB
case glslang::EOpAtomicStore:
noReturnValue = true;
// fallthrough
builder.addCapability(spv::CapabilityRayQueryPositionFetchKHR);
noReturnValue = true;
break;
-#endif
case glslang::EOpDebugPrintf:
noReturnValue = true;
lvalue = true;
break;
-#ifndef GLSLANG_WEB
case glslang::EOpFrexp:
if (arg == 1)
lvalue = true;
if (arg == 0 || arg == 2)
lvalue = true;
break;
-#endif
default:
break;
}
else
glslangOperands[arg]->traverse(this);
-#ifndef GLSLANG_WEB
if (node->getOp() == glslang::EOpCooperativeMatrixLoad ||
node->getOp() == glslang::EOpCooperativeMatrixStore ||
node->getOp() == glslang::EOpCooperativeMatrixLoadNV ||
continue;
}
}
-#endif
// for l-values, pass the address, for r-values, pass the value
if (lvalue) {
visitSymbol(itNode->second);
spv::Id symId = getSymbolId(itNode->second);
operands.push_back(symId);
-#ifndef GLSLANG_WEB
} else if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvLiteral()) {
// Will be translated to a literal value, make a placeholder here
operands.push_back(spv::NoResult);
-#endif
} else {
operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType()));
}
}
builder.setLine(node->getLoc().line, node->getLoc().getFilename());
-#ifndef GLSLANG_WEB
if (node->getOp() == glslang::EOpCooperativeMatrixLoad ||
node->getOp() == glslang::EOpCooperativeMatrixLoadNV) {
std::vector<spv::IdImmediate> idImmOps;
idImmOps.push_back(spv::IdImmediate(false, matrixOperands));
result = builder.createOp(spv::OpCooperativeMatrixMulAddKHR, resultType(), idImmOps);
- } else
-#endif
- if (atomic) {
+ } else if (atomic) {
// Handle all atomics
glslang::TBasicType typeProxy = (node->getOp() == glslang::EOpAtomicStore)
? node->getSequence()[0]->getAsTyped()->getBasicType() : node->getBasicType();
result = createAtomicOperation(node->getOp(), precision, resultType(), operands, typeProxy,
lvalueCoherentFlags);
-#ifndef GLSLANG_WEB
} else if (node->getOp() == glslang::EOpSpirvInst) {
const auto& spirvInst = node->getSpirvInstruction();
if (spirvInst.set == "") {
spirvInst.id, operands);
}
noReturnValue = node->getBasicType() == glslang::EbtVoid;
-#endif
} else if (node->getOp() == glslang::EOpDebugPrintf) {
if (!nonSemanticDebugPrintf) {
nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf");
void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* node)
{
-#ifndef GLSLANG_WEB
if (node->getQualifier().isSpirvLiteral())
return; // Translated to a literal value, skip further processing
-#endif
int nextConst = 0;
spv::Id constant = createSpvConstantFromConstUnionArray(node->getType(), node->getConstArray(), nextConst, false);
builder.clearAccessChain();
break;
-#ifndef GLSLANG_WEB
case glslang::EOpDemote:
builder.createNoResultOp(spv::OpDemoteToHelperInvocationEXT);
builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation);
case glslang::EOpIgnoreIntersectionKHR:
builder.makeStatementTerminator(spv::OpIgnoreIntersectionKHR, "post-ignoreIntersectionKHR");
break;
-#endif
default:
assert(0);
else
builder.addCapability(spv::CapabilityStorageUniform16);
break;
-#ifndef GLSLANG_WEB
case spv::StorageClassPushConstant:
builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3);
builder.addCapability(spv::CapabilityStoragePushConstant16);
builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3);
builder.addCapability(spv::CapabilityStorageUniformBufferBlock16);
break;
-#endif
default:
if (storageClass == spv::StorageClassWorkgroup &&
node->getType().getBasicType() == glslang::EbtBlock) {
case glslang::EbtInt: return builder.makeIntType(32);
case glslang::EbtUint: return builder.makeUintType(32);
case glslang::EbtFloat: return builder.makeFloatType(32);
-#ifndef GLSLANG_WEB
case glslang::EbtFloat16:
builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch);
builder.addCapability(spv::CapabilityFloat16ImageAMD);
builder.addExtension(spv::E_SPV_EXT_shader_image_int64);
builder.addCapability(spv::CapabilityInt64ImageEXT);
return builder.makeUintType(64);
-#endif
default:
assert(0);
return builder.makeFloatType(32);
case glslang::EbtFloat:
spvType = builder.makeFloatType(32);
break;
-#ifndef GLSLANG_WEB
case glslang::EbtDouble:
spvType = builder.makeFloatType(64);
break;
}
}
break;
-#endif
case glslang::EbtSampler:
{
const glslang::TSampler& sampler = type.getSampler();
spvType = builder.makeHitObjectNVType();
}
break;
-#ifndef GLSLANG_WEB
case glslang::EbtSpirvType: {
// GL_EXT_spirv_intrinsics
const auto& spirvType = type.getSpirvType();
break;
}
-#endif
default:
assert(0);
break;
if (type.isSizedArray())
spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), 0), stride);
else {
-#ifndef GLSLANG_WEB
if (!lastBufferBlockMember) {
builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5);
builder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT);
}
-#endif
spvType = builder.makeRuntimeArray(spvType);
}
if (stride > 0)
//
bool TGlslangToSpvTraverser::filterMember(const glslang::TType& member)
{
-#ifndef GLSLANG_WEB
auto& extensions = glslangIntermediate->getRequestedExtensions();
if (member.getFieldName() == "gl_SecondaryViewportMaskNV" &&
extensions.find("GL_NVX_multiview_per_view_attributes") == extensions.end())
return true;
}
-#endif
return false;
};
glslangIntermediate->getSource() == glslang::EShSourceHlsl) {
builder.addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier));
builder.addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier));
-#ifndef GLSLANG_WEB
addMeshNVDecoration(spvType, member, memberQualifier);
-#endif
}
}
builder.addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier));
-#ifndef GLSLANG_WEB
if (type.getBasicType() == glslang::EbtBlock &&
qualifier.storage == glslang::EvqBuffer) {
// Add memory decorations only to top-level members of shader storage block
builder.addMemberDecoration(spvType, member, memory[i]);
}
-#endif
-
// Location assignment was already completed correctly by the front end,
// just track whether a member needs to be decorated.
// Ignore member locations if the container is an array, as that's
if (builtIn != spv::BuiltInMax)
builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn);
-#ifndef GLSLANG_WEB
// nonuniform
builder.addMemberDecoration(spvType, member, TranslateNonUniformDecoration(glslangMember.getQualifier()));
builder.addDecoration(spvType, static_cast<spv::Decoration>(decorateString.first), strings);
}
}
-#endif
}
// Decorate the structure
switch (glslangBuiltIn)
{
case glslang::EbvPointSize:
-#ifndef GLSLANG_WEB
case glslang::EbvClipDistance:
case glslang::EbvCullDistance:
case glslang::EbvViewportMaskNV:
case glslang::EbvLayerPerViewNV:
case glslang::EbvMeshViewCountNV:
case glslang::EbvMeshViewIndicesNV:
-#endif
// Generate the associated capability. Delegate to TranslateBuiltInDecoration.
// Alternately, we could just call this for any glslang built-in, since the
// capability already guards against duplicates.
if (glslangIntermediate->getSource() == glslang::EShSourceHlsl)
return paramType.getBasicType() == glslang::EbtBlock;
return (paramType.containsOpaque() && !glslangIntermediate->getBindlessMode()) || // sampler, etc.
-#ifndef GLSLANG_WEB
paramType.getQualifier().isSpirvByReference() || // spirv_by_reference
-#endif
(paramType.getBasicType() == glslang::EbtBlock && qualifier == glslang::EvqBuffer); // SSBO
}
glslang::TSampler sampler = {};
bool cubeCompare = false;
-#ifndef GLSLANG_WEB
bool f16ShadowCompare = false;
-#endif
if (node.isTexture() || node.isImage()) {
sampler = glslangArguments[0]->getAsTyped()->getType().getSampler();
cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow;
-#ifndef GLSLANG_WEB
f16ShadowCompare = sampler.shadow &&
glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16;
-#endif
}
for (int i = 0; i < (int)glslangArguments.size(); ++i) {
builder.clearAccessChain();
glslangArguments[i]->traverse(this);
-#ifndef GLSLANG_WEB
// Special case l-value operands
bool lvalue = false;
switch (node.getOp()) {
builder.addDecoration(lvalue_id, TranslateNonUniformDecoration(lvalueCoherentFlags));
lvalueCoherentFlags |= TranslateCoherent(glslangArguments[i]->getAsTyped()->getType());
} else
-#endif
arguments.push_back(accessChainLoad(glslangArguments[i]->getAsTyped()->getType()));
}
}
? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType()
: node->getAsUnaryNode()->getOperand()->getAsTyped()->getType();
const glslang::TSampler sampler = imageType.getSampler();
-#ifdef GLSLANG_WEB
- const bool f16ShadowCompare = false;
-#else
bool f16ShadowCompare = (sampler.shadow && node->getAsAggregate())
? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16
: false;
-#endif
const auto signExtensionMask = [&]() {
if (builder.getSpvVersion() >= spv::Spv_1_4) {
return builder.createTextureQueryCall(spv::OpImageQuerySizeLod, params, isUnsignedResult);
} else
return builder.createTextureQueryCall(spv::OpImageQuerySize, params, isUnsignedResult);
-#ifndef GLSLANG_WEB
case glslang::EOpImageQuerySamples:
case glslang::EOpTextureQuerySamples:
return builder.createTextureQueryCall(spv::OpImageQuerySamples, params, isUnsignedResult);
return builder.createTextureQueryCall(spv::OpImageQueryLevels, params, isUnsignedResult);
case glslang::EOpSparseTexelsResident:
return builder.createUnaryOp(spv::OpImageSparseTexelsResident, builder.makeBoolType(), arguments[0]);
-#endif
default:
assert(0);
break;
}
}
-#ifndef GLSLANG_WEB
// Check for fragment mask functions other than queries
if (cracked.fragMask) {
assert(sampler.ms);
builder.addCapability(spv::CapabilityFragmentMaskAMD);
return builder.createOp(fragMaskOp, resultType(), operands);
}
-#endif
// Check for texture functions other than queries
bool sparse = node->isSparseTexture();
bias = true;
}
-#ifndef GLSLANG_WEB
if (cracked.gather) {
const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions();
if (bias || cracked.lod ||
builder.addCapability(spv::CapabilityImageGatherBiasLodAMD);
}
}
-#endif
// set the rest of the arguments
++extraArgs;
}
-#ifndef GLSLANG_WEB
// lod clamp
if (cracked.lodClamp) {
params.lodClamp = arguments[2 + extraArgs];
resultStruct = arguments[4 + extraArgs];
extraArgs += 3;
}
-#endif
+
// bias
if (bias) {
params.bias = arguments[2 + extraArgs];
++extraArgs;
}
-#ifndef GLSLANG_WEB
if (imageFootprint) {
builder.addExtension(spv::E_SPV_NV_shader_image_footprint);
builder.addCapability(spv::CapabilityImageFootprintNV);
}
return builder.createCompositeExtract(res, resultType(), 0);
}
-#endif
// projective component (might not to move)
// GLSL: "The texture coordinates consumed from P, not including the last component of P,
}
}
-#ifndef GLSLANG_WEB
// nonprivate
if (imageType.getQualifier().nonprivate) {
params.nonprivate = true;
if (imageType.getQualifier().volatil) {
params.volatil = true;
}
-#endif
std::vector<spv::Id> result( 1,
builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather,
case glslang::EOpUnpackHalf2x16:
libCall = spv::GLSLstd450UnpackHalf2x16;
break;
-#ifndef GLSLANG_WEB
case glslang::EOpPackSnorm4x8:
libCall = spv::GLSLstd450PackSnorm4x8;
break;
case glslang::EOpUnpackDouble2x32:
libCall = spv::GLSLstd450UnpackDouble2x32;
break;
-#endif
case glslang::EOpPackInt2x32:
case glslang::EOpUnpackInt2x32:
libCall = spv::GLSLstd450SSign;
break;
-#ifndef GLSLANG_WEB
case glslang::EOpDPdxFine:
unaryOp = spv::OpDPdxFine;
break;
unaryOp = spv::OpHitObjectGetShaderRecordBufferHandleNV;
break;
-#endif
-
case glslang::EOpCopyObject:
unaryOp = spv::OpCopyObject;
break;
case glslang::EOpConvBoolToInt:
case glslang::EOpConvBoolToInt64:
-#ifndef GLSLANG_WEB
if (op == glslang::EOpConvBoolToInt64) {
zero = builder.makeInt64Constant(0);
one = builder.makeInt64Constant(1);
- } else
-#endif
- {
+ } else {
zero = builder.makeIntConstant(0);
one = builder.makeIntConstant(1);
}
case glslang::EOpConvBoolToUint:
case glslang::EOpConvBoolToUint64:
-#ifndef GLSLANG_WEB
if (op == glslang::EOpConvBoolToUint64) {
zero = builder.makeUint64Constant(0);
one = builder.makeUint64Constant(1);
- } else
-#endif
- {
+ } else {
zero = builder.makeUintConstant(0);
one = builder.makeUintConstant(1);
}
case glslang::EOpConvInt64ToUint64:
if (builder.isInSpecConstCodeGenMode()) {
// Build zero scalar or vector for OpIAdd.
-#ifndef GLSLANG_WEB
if(op == glslang::EOpConvUint8ToInt8 || op == glslang::EOpConvInt8ToUint8) {
zero = builder.makeUint8Constant(0);
} else if (op == glslang::EOpConvUint16ToInt16 || op == glslang::EOpConvInt16ToUint16) {
zero = builder.makeUint16Constant(0);
} else if (op == glslang::EOpConvUint64ToInt64 || op == glslang::EOpConvInt64ToUint64) {
zero = builder.makeUint64Constant(0);
- } else
-#endif
- {
+ } else {
zero = builder.makeUintConstant(0);
}
zero = makeSmearedConstant(zero, vectorSize);
convOp = spv::OpConvertFToU;
break;
-#ifndef GLSLANG_WEB
case glslang::EOpConvInt8ToBool:
case glslang::EOpConvUint8ToBool:
zero = builder.makeUint8Constant(0);
case glslang::EOpConvUvec2ToPtr:
convOp = spv::OpBitcast;
break;
-#endif
default:
break;
}
break;
-#ifndef GLSLANG_WEB
case glslang::EOpInterpolateAtSample:
if (typeProxy == glslang::EbtFloat16)
builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
}
break;
-#endif // GLSLANG_WEB
default:
return 0;
}
}
}
-#ifndef GLSLANG_WEB
// Decode the return types that were structures
switch (op) {
case glslang::EOpAddCarry:
default:
break;
}
-#endif
return builder.setPrecision(id, precision);
}
builder.createMemoryBarrier(spv::ScopeWorkgroup, spv::MemorySemanticsAllMemory |
spv::MemorySemanticsAcquireReleaseMask);
return 0;
-#ifndef GLSLANG_WEB
case glslang::EOpMemoryBarrierAtomicCounter:
builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAtomicCounterMemoryMask |
spv::MemorySemanticsAcquireReleaseMask);
builder.addCapability(spv::CapabilityShaderClockKHR);
return builder.createOp(spv::OpReadClockKHR, typeId, args);
}
-#endif
case glslang::EOpStencilAttachmentReadEXT:
case glslang::EOpDepthAttachmentReadEXT:
{
builder.addDecoration(id, TranslatePrecisionDecoration(symbol->getType()));
builder.addDecoration(id, TranslateInterpolationDecoration(symbol->getType().getQualifier()));
builder.addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier()));
-#ifndef GLSLANG_WEB
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
if (symbol->getType().getQualifier().hasSpecConstantId())
builder.addDecoration(id, spv::DecorationSpecId, symbol->getType().getQualifier().layoutSpecConstantId);
// atomic counters use this:
builder.addDecoration(id, spv::DecorationVolatile);
}
-#ifndef GLSLANG_WEB
// Subgroup builtins which have input storage class are volatile for ray tracing stages.
if (symbol->getType().isImage() || symbol->getQualifier().isPipeInput()) {
std::vector<spv::Decoration> memory;
builder.addDecoration(id, static_cast<spv::Decoration>(decorateString.first), strings);
}
}
-#endif
return id;
}
-#ifndef GLSLANG_WEB
// add per-primitive, per-view. per-task decorations to a struct member (member >= 0) or an object
void TGlslangToSpvTraverser::addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier& qualifier)
{
builder.addDecoration(id, spv::DecorationPerTaskNV);
}
}
-#endif
// Make a full tree of instructions to build a SPIR-V specialization constant,
// or regular constant if possible.
case glslang::EbtBool:
spvConsts.push_back(builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst()));
break;
-#ifndef GLSLANG_WEB
case glslang::EbtInt8:
builder.addCapability(spv::CapabilityInt8);
spvConsts.push_back(builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const()));
builder.addCapability(spv::CapabilityFloat16);
spvConsts.push_back(builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst()));
break;
-#endif
default:
assert(0);
break;
case glslang::EbtBool:
scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst(), specConstant);
break;
-#ifndef GLSLANG_WEB
case glslang::EbtInt8:
builder.addCapability(spv::CapabilityInt8);
scalar = builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const(), specConstant);
scalar = builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const(), specConstant);
scalar = builder.createUnaryOp(spv::OpBitcast, typeId, scalar);
break;
-#endif
case glslang::EbtString:
scalar = builder.getStringId(consts[nextConst].getSConst()->c_str());
break;
return builder.createOp(spv::OpPhi, boolTypeId, phiOperands);
}
-#ifndef GLSLANG_WEB
// Return type Id of the imported set of extended instructions corresponds to the name.
// Import this set if it has not been imported yet.
spv::Id TGlslangToSpvTraverser::getExtBuiltins(const char* name)
return extBuiltins;
}
}
-#endif
}; // end anonymous namespace
// Write SPIR-V out to a text file with 32-bit hexadecimal words
bool OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName)
{
-#if !defined(GLSLANG_WEB)
std::ofstream out;
out.open(baseName, std::ios::binary | std::ios::out);
if (out.fail()) {
out << std::endl;
}
out.close();
-#endif
return true;
}
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
-#ifndef GLSLANG_WEB
-
#include "Logger.h"
#include <algorithm>
}
} // end spv namespace
-
-#endif
public:
SpvBuildLogger() {}
-#ifdef GLSLANG_WEB
- void tbdFunctionality(const std::string& f) { }
- void missingFunctionality(const std::string& f) { }
- void warning(const std::string& w) { }
- void error(const std::string& e) { errors.push_back(e); }
- std::string getAllMessages() { return ""; }
-#else
-
// Registers a TBD functionality.
void tbdFunctionality(const std::string& f);
// Registers a missing functionality.
// Returns all messages accumulated in the order of:
// TBD functionalities, missing functionalities, warnings, errors.
std::string getAllMessages() const;
-#endif
private:
SpvBuildLogger(const SpvBuildLogger&);
#include <algorithm>
#include "SpvBuilder.h"
-
-#ifndef GLSLANG_WEB
#include "hex_float.h"
-#endif
#ifndef _WIN32
#include <cstdio>
Id Builder::makeIntegerType(int width, bool hasSign)
{
-#ifdef GLSLANG_WEB
- assert(width == 32);
- width = 32;
-#endif
-
// try to find it
Instruction* type;
for (int t = 0; t < (int)groupedTypes[OpTypeInt].size(); ++t) {
Id Builder::makeFloatType(int width)
{
-#ifdef GLSLANG_WEB
- assert(width == 32);
- width = 32;
-#endif
-
// try to find it
Instruction* type;
for (int t = 0; t < (int)groupedTypes[OpTypeFloat].size(); ++t) {
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
module.mapInstruction(type);
-#ifndef GLSLANG_WEB
// deal with capabilities
switch (dim) {
case DimBuffer:
addCapability(CapabilityImageMSArray);
}
}
-#endif
if (emitNonSemanticShaderDebugInfo)
{
return inst->getResultId();
}
-#ifndef GLSLANG_WEB
Id Builder::makeAccelerationStructureType()
{
Instruction *type;
return type->getResultId();
}
-#endif
Id Builder::getDerefTypeId(Id resultId) const
{
Id Builder::makeDoubleConstant(double d, bool specConstant)
{
-#ifdef GLSLANG_WEB
- assert(0);
- return NoResult;
-#else
Op opcode = specConstant ? OpSpecConstant : OpConstant;
Id typeId = makeFloatType(64);
union { double db; unsigned long long ull; } u;
module.mapInstruction(c);
return c->getResultId();
-#endif
}
Id Builder::makeFloat16Constant(float f16, bool specConstant)
{
-#ifdef GLSLANG_WEB
- assert(0);
- return NoResult;
-#else
Op opcode = specConstant ? OpSpecConstant : OpConstant;
Id typeId = makeFloatType(16);
module.mapInstruction(c);
return c->getResultId();
-#endif
}
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));
if (parameters.component != NoResult)
texArgs.push_back(parameters.component);
-#ifndef GLSLANG_WEB
if (parameters.granularity != NoResult)
texArgs.push_back(parameters.granularity);
if (parameters.coarse != NoResult)
texArgs.push_back(parameters.coarse);
-#endif
//
// Set up the optional arguments
mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);
texArgs.push_back(parameters.offsets);
}
-#ifndef GLSLANG_WEB
if (parameters.sample) {
mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
texArgs.push_back(parameters.sample);
if (parameters.volatil) {
mask = mask | ImageOperandsVolatileTexelKHRMask;
}
-#endif
mask = mask | signExtensionMask;
// insert the operand for the mask, if any bits were set.
if (mask != ImageOperandsMaskNone)
opCode = OpImageSparseFetch;
else
opCode = OpImageFetch;
-#ifndef GLSLANG_WEB
} else if (parameters.granularity && parameters.coarse) {
opCode = OpImageSampleFootprintNV;
} else if (gather) {
opCode = OpImageSparseGather;
else
opCode = OpImageGather;
-#endif
} else if (explicitLod) {
if (parameters.Dref) {
if (proj)
int numRows = getTypeNumRows(resultTypeId);
Instruction* instr = module.getInstruction(componentTypeId);
-#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
if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) {
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
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) == OpTypeCooperativeMatrixKHR || getTypeClass(typeId) == OpTypeCooperativeMatrixNV;
}
-#endif
bool isAggregateType(Id typeId) const
{ return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
// Accumulate whether anything in the chain of structures has coherent decorations.
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; }
bool isNonUniform() const { return nonUniform; }
bool anyCoherent() const {
nonUniform |= other.nonUniform;
return *this;
}
-#endif
};
CoherentFlags coherentFlags;
};
// Prune unreachable blocks in the CFG and remove unneeded decorations.
void postProcessCFG();
-#ifndef GLSLANG_WEB
// Add capabilities, extensions based on instructions in the module.
void postProcessFeatures();
// Hook to visit each instruction in a block in a function
void postProcess(Instruction&);
// Hook to visit each non-32-bit sized float/int operation in a block.
void postProcessType(const Instruction&, spv::Id typeId);
-#endif
void dump(std::vector<unsigned int>&) const;
namespace spv {
-#ifndef GLSLANG_WEB
// Hook to visit each operand type and result type of an instruction.
// Will be called multiple times for one instruction, once for each typed
// operand and the result.
}
}
}
-#endif
// comment in header
void Builder::postProcessCFG()
decorations.end());
}
-#ifndef GLSLANG_WEB
// comment in header
void Builder::postProcessFeatures() {
// Add per-instruction capabilities, extensions, etc.,
}
}
}
-#endif
// comment in header
void Builder::postProcess() {
postProcessCFG();
-#ifndef GLSLANG_WEB
postProcessFeatures();
-#endif
}
}; // end spv namespace
{
if (ConfigFile.size() == 0)
*GetResources() = *GetDefaultResources();
-#ifndef GLSLANG_WEB
else {
char* configString = ReadFileData(ConfigFile.c_str());
DecodeResourceLimits(GetResources(), configString);
FreeFileData(configString);
}
-#endif
}
int ReflectOptions = EShReflectionDefault;
shader->setPreamble(PreambleString.c_str());
shader->addProcesses(Processes);
-#ifndef GLSLANG_WEB
// Set IO mapper binding shift values
for (int r = 0; r < glslang::EResCount; ++r) {
const glslang::TResourceType res = glslang::TResourceType(r);
}
shader->setUniformLocationBase(uniformBase);
-#endif
if (VulkanRulesRelaxed) {
for (auto& storageOverride : blockStorageOverrides) {
const int defaultVersion = Options & EOptionDefaultDesktop ? 110 : 100;
-#ifndef GLSLANG_WEB
if (Options & EOptionOutputPreprocessed) {
std::string str;
if (shader->preprocess(GetResources(), defaultVersion, ENoProfile, false, false, messages, &str, includer)) {
StderrIfNonEmpty(shader->getInfoDebugLog());
continue;
}
-#endif
if (! shader->parse(GetResources(), defaultVersion, false, messages, includer))
CompileFailed = true;
if (! (Options & EOptionOutputPreprocessed) && ! program.link(messages))
LinkFailed = true;
-#ifndef GLSLANG_WEB
// Map IO
if (Options & EOptionSpv) {
if (!program.mapIO())
LinkFailed = true;
}
-#endif
// Report
if (! (Options & EOptionSuppressInfolog) &&
PutsIfNonEmpty(program.getInfoDebugLog());
}
-#ifndef GLSLANG_WEB
// Reflect
if (Options & EOptionDumpReflection) {
program.buildReflection(ReflectOptions);
program.dumpReflection();
}
-#endif
std::vector<std::string> outputFiles;
}
outputFiles.push_back(GetBinaryName((EShLanguage)stage));
-#ifndef GLSLANG_WEB
if (!SpvToolsDisassembler && (Options & EOptionHumanReadableSpv))
spv::Disassemble(std::cout, spirv);
-#endif
}
}
}
workList.add(item.get());
});
-#ifndef GLSLANG_WEB
if (Options & EOptionDumpConfig) {
printf("%s", GetDefaultTBuiltInResourceString().c_str());
if (workList.empty())
return ESuccess;
}
-#endif
if (Options & EOptionDumpBareVersion) {
printf("%d:%d.%d.%d%s\n", glslang::GetSpirvGeneratorVersion(), GLSLANG_VERSION_MAJOR, GLSLANG_VERSION_MINOR,
EbtRayQuery,
EbtHitObjectNV,
EbtCoopmat,
-#ifndef GLSLANG_WEB
// SPIR-V type defined by spirv_type
EbtSpirvType,
-#endif
// HLSL types that live only temporarily.
EbtString,
EvqUniform, // read only, shared with app
EvqBuffer, // read/write, shared with app
EvqShared, // compute shader's read/write 'shared' qualifier
-#ifndef GLSLANG_WEB
EvqSpirvStorageClass, // spirv_storage_class
-#endif
EvqPayload,
EvqPayloadIn,
EpqHigh
};
-#ifdef GLSLANG_WEB
-__inline const char* GetStorageQualifierString(TStorageQualifier q) { return ""; }
-__inline const char* GetPrecisionQualifierString(TPrecisionQualifier p) { return ""; }
-#else
// These will show up in error messages
__inline const char* GetStorageQualifierString(TStorageQualifier q)
{
case EvqGlobal: return "global"; break;
case EvqConst: return "const"; break;
case EvqConstReadOnly: return "const (read only)"; break;
-#ifndef GLSLANG_WEB
case EvqSpirvStorageClass: return "spirv_storage_class"; break;
-#endif
case EvqVaryingIn: return "in"; break;
case EvqVaryingOut: return "out"; break;
case EvqUniform: return "uniform"; break;
default: return "unknown precision qualifier";
}
}
-#endif
__inline bool isTypeSignedInt(TBasicType type)
{
break;
-#ifndef GLSLANG_WEB
case EbtInt16:
if (constant.i16Const == i16Const)
return true;
return true;
break;
-#endif
default:
assert(false && "Default missing");
}
return true;
return false;
-#ifndef GLSLANG_WEB
case EbtInt8:
if (i8Const > constant.i8Const)
return true;
return true;
return false;
-#endif
default:
assert(false && "Default missing");
return false;
{
assert(type == constant.type);
switch (type) {
-#ifndef GLSLANG_WEB
case EbtInt8:
if (i8Const < constant.i8Const)
return true;
return true;
return false;
-#endif
case EbtDouble:
if (dConst < constant.dConst)
return true;
case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
case EbtUint: returnValue.setUConst(uConst + constant.uConst); break;
case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break;
-#ifndef GLSLANG_WEB
case EbtInt8: returnValue.setI8Const(i8Const + constant.i8Const); break;
case EbtInt16: returnValue.setI16Const(i16Const + constant.i16Const); break;
case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break;
case EbtUint8: returnValue.setU8Const(u8Const + constant.u8Const); break;
case EbtUint16: returnValue.setU16Const(u16Const + constant.u16Const); break;
case EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break;
-#endif
default: assert(false && "Default missing");
}
case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
case EbtUint: returnValue.setUConst(uConst - constant.uConst); break;
case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break;
-#ifndef GLSLANG_WEB
case EbtInt8: returnValue.setI8Const(i8Const - constant.i8Const); break;
case EbtInt16: returnValue.setI16Const(i16Const - constant.i16Const); break;
case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break;
case EbtUint8: returnValue.setU8Const(u8Const - constant.u8Const); break;
case EbtUint16: returnValue.setU16Const(u16Const - constant.u16Const); break;
case EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break;
-#endif
default: assert(false && "Default missing");
}
case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
case EbtUint: returnValue.setUConst(uConst * constant.uConst); break;
case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break;
-#ifndef GLSLANG_WEB
case EbtInt8: returnValue.setI8Const(i8Const * constant.i8Const); break;
case EbtInt16: returnValue.setI16Const(i16Const * constant.i16Const); break;
case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break;
case EbtUint8: returnValue.setU8Const(u8Const * constant.u8Const); break;
case EbtUint16: returnValue.setU16Const(u16Const * constant.u16Const); break;
case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break;
-#endif
default: assert(false && "Default missing");
}
switch (type) {
case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
case EbtUint: returnValue.setUConst(uConst % constant.uConst); break;
-#ifndef GLSLANG_WEB
case EbtInt8: returnValue.setI8Const(i8Const % constant.i8Const); break;
case EbtInt16: returnValue.setI8Const(i8Const % constant.i16Const); break;
case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break;
case EbtUint8: returnValue.setU8Const(u8Const % constant.u8Const); break;
case EbtUint16: returnValue.setU16Const(u16Const % constant.u16Const); break;
case EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break;
-#endif
default: assert(false && "Default missing");
}
{
TConstUnion returnValue;
switch (type) {
-#ifndef GLSLANG_WEB
case EbtInt8:
switch (constant.type) {
case EbtInt8: returnValue.setI8Const(i8Const >> constant.i8Const); break;
default: assert(false && "Default missing");
}
break;
-#endif
case EbtInt:
switch (constant.type) {
case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break;
-#ifndef GLSLANG_WEB
case EbtInt8: returnValue.setIConst(iConst >> constant.i8Const); break;
case EbtUint8: returnValue.setIConst(iConst >> constant.u8Const); break;
case EbtInt16: returnValue.setIConst(iConst >> constant.i16Const); break;
case EbtUint16: returnValue.setIConst(iConst >> constant.u16Const); break;
case EbtInt64: returnValue.setIConst(iConst >> constant.i64Const); break;
case EbtUint64: returnValue.setIConst(iConst >> constant.u64Const); break;
-#endif
default: assert(false && "Default missing");
}
break;
switch (constant.type) {
case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break;
case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break;
-#ifndef GLSLANG_WEB
case EbtInt8: returnValue.setUConst(uConst >> constant.i8Const); break;
case EbtUint8: returnValue.setUConst(uConst >> constant.u8Const); break;
case EbtInt16: returnValue.setUConst(uConst >> constant.i16Const); break;
case EbtUint16: returnValue.setUConst(uConst >> constant.u16Const); break;
case EbtInt64: returnValue.setUConst(uConst >> constant.i64Const); break;
case EbtUint64: returnValue.setUConst(uConst >> constant.u64Const); break;
-#endif
default: assert(false && "Default missing");
}
break;
-#ifndef GLSLANG_WEB
case EbtInt64:
switch (constant.type) {
case EbtInt8: returnValue.setI64Const(i64Const >> constant.i8Const); break;
default: assert(false && "Default missing");
}
break;
-#endif
default: assert(false && "Default missing");
}
{
TConstUnion returnValue;
switch (type) {
-#ifndef GLSLANG_WEB
case EbtInt8:
switch (constant.type) {
case EbtInt8: returnValue.setI8Const(i8Const << constant.i8Const); break;
default: assert(false && "Default missing");
}
break;
-#endif
case EbtInt:
switch (constant.type) {
case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
case EbtUint: returnValue.setIConst(iConst << constant.uConst); break;
-#ifndef GLSLANG_WEB
case EbtInt8: returnValue.setIConst(iConst << constant.i8Const); break;
case EbtUint8: returnValue.setIConst(iConst << constant.u8Const); break;
case EbtInt16: returnValue.setIConst(iConst << constant.i16Const); break;
case EbtUint16: returnValue.setIConst(iConst << constant.u16Const); break;
case EbtInt64: returnValue.setIConst(iConst << constant.i64Const); break;
case EbtUint64: returnValue.setIConst(iConst << constant.u64Const); break;
-#endif
default: assert(false && "Default missing");
}
break;
switch (constant.type) {
case EbtInt: returnValue.setUConst(uConst << constant.iConst); break;
case EbtUint: returnValue.setUConst(uConst << constant.uConst); break;
-#ifndef GLSLANG_WEB
case EbtInt8: returnValue.setUConst(uConst << constant.i8Const); break;
case EbtUint8: returnValue.setUConst(uConst << constant.u8Const); break;
case EbtInt16: returnValue.setUConst(uConst << constant.i16Const); break;
case EbtUint16: returnValue.setUConst(uConst << constant.u16Const); break;
case EbtInt64: returnValue.setUConst(uConst << constant.i64Const); break;
case EbtUint64: returnValue.setUConst(uConst << constant.u64Const); break;
-#endif
default: assert(false && "Default missing");
}
break;
switch (type) {
case EbtInt: returnValue.setIConst(iConst & constant.iConst); break;
case EbtUint: returnValue.setUConst(uConst & constant.uConst); break;
-#ifndef GLSLANG_WEB
case EbtInt8: returnValue.setI8Const(i8Const & constant.i8Const); break;
case EbtUint8: returnValue.setU8Const(u8Const & constant.u8Const); break;
case EbtInt16: returnValue.setI16Const(i16Const & constant.i16Const); break;
case EbtUint16: returnValue.setU16Const(u16Const & constant.u16Const); break;
case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break;
case EbtUint64: returnValue.setU64Const(u64Const & constant.u64Const); break;
-#endif
default: assert(false && "Default missing");
}
switch (type) {
case EbtInt: returnValue.setIConst(iConst | constant.iConst); break;
case EbtUint: returnValue.setUConst(uConst | constant.uConst); break;
-#ifndef GLSLANG_WEB
case EbtInt8: returnValue.setI8Const(i8Const | constant.i8Const); break;
case EbtUint8: returnValue.setU8Const(u8Const | constant.u8Const); break;
case EbtInt16: returnValue.setI16Const(i16Const | constant.i16Const); break;
case EbtUint16: returnValue.setU16Const(u16Const | constant.u16Const); break;
case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break;
case EbtUint64: returnValue.setU64Const(u64Const | constant.u64Const); break;
-#endif
default: assert(false && "Default missing");
}
switch (type) {
case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break;
case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break;
-#ifndef GLSLANG_WEB
case EbtInt8: returnValue.setI8Const(i8Const ^ constant.i8Const); break;
case EbtUint8: returnValue.setU8Const(u8Const ^ constant.u8Const); break;
case EbtInt16: returnValue.setI16Const(i16Const ^ constant.i16Const); break;
case EbtUint16: returnValue.setU16Const(u16Const ^ constant.u16Const); break;
case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break;
case EbtUint64: returnValue.setU64Const(u64Const ^ constant.u64Const); break;
-#endif
default: assert(false && "Default missing");
}
switch (type) {
case EbtInt: returnValue.setIConst(~iConst); break;
case EbtUint: returnValue.setUConst(~uConst); break;
-#ifndef GLSLANG_WEB
case EbtInt8: returnValue.setI8Const(~i8Const); break;
case EbtUint8: returnValue.setU8Const(~u8Const); break;
case EbtInt16: returnValue.setI16Const(~i16Const); break;
case EbtUint16: returnValue.setU16Const(~u16Const); break;
case EbtInt64: returnValue.setI64Const(~i64Const); break;
case EbtUint64: returnValue.setU64Const(~u64Const); break;
-#endif
default: assert(false && "Default missing");
}
#pragma once
-#ifndef GLSLANG_WEB
-
//
// GL_EXT_spirv_intrinsics
//
};
} // end namespace glslang
-
-#endif // GLSLANG_WEB
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 GLSLANG_WEB
- bool is1D() const { return false; }
- bool isBuffer() const { return false; }
- bool isRect() const { return false; }
- bool isSubpass() const { return false; }
- bool isAttachmentEXT() const { return false; }
- bool isCombined() const { return true; }
- bool isImage() const { return false; }
- bool isImageClass() const { return false; }
- bool isMultiSample() const { return false; }
- bool isExternal() const { return false; }
- void setExternal(bool e) { }
- bool isYuv() const { return false; }
-#else
unsigned int vectorSize : 3; // vector return type size.
// 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.
bool isExternal() const { return external; }
void setExternal(bool e) { external = e; }
bool isYuv() const { return yuv; }
-#endif
bool isTexture() const { return !sampler && !image; }
bool isPureSampler() const { return sampler; }
image = false;
combined = false;
sampler = false;
-#ifndef GLSLANG_WEB
external = false;
yuv = false;
-#endif
#ifdef ENABLE_HLSL
clearReturnStruct();
shadow = s;
}
-#ifndef GLSLANG_WEB
// make a subpass input attachment
void setSubpass(TBasicType t, bool m = false)
{
image = true;
dim = EsdAttachmentEXT;
}
-#endif
bool operator==(const TSampler& right) const
{
switch (type) {
case EbtInt: s.append("i"); break;
case EbtUint: s.append("u"); break;
-#ifndef GLSLANG_WEB
case EbtFloat16: s.append("f16"); break;
case EbtInt8: s.append("i8"); break;
case EbtUint16: s.append("u8"); break;
case EbtUint8: s.append("u16"); break;
case EbtInt64: s.append("i64"); break;
case EbtUint64: s.append("u64"); break;
-#endif
default: break;
}
if (isImageClass()) {
case Esd2D: s.append("2D"); break;
case Esd3D: s.append("3D"); break;
case EsdCube: s.append("Cube"); break;
-#ifndef GLSLANG_WEB
case Esd1D: s.append("1D"); break;
case EsdRect: s.append("2DRect"); break;
case EsdBuffer: s.append("Buffer"); break;
case EsdSubpass: s.append("Input"); break;
case EsdAttachmentEXT: s.append(""); break;
-#endif
default: break; // some compilers want this
}
if (isMultiSample())
invariant = false;
makeTemporary();
declaredBuiltIn = EbvNone;
-#ifndef GLSLANG_WEB
noContraction = false;
nullInit = false;
spirvByReference = false;
spirvLiteral = false;
-#endif
defaultBlock = false;
}
nullInit = false;
defaultBlock = false;
clearLayout();
-#ifndef GLSLANG_WEB
spirvStorageClass = -1;
spirvDecorate = nullptr;
spirvByReference = false;
spirvLiteral = false;
-#endif
}
void clearInterstage()
{
clearInterpolation();
-#ifndef GLSLANG_WEB
patch = false;
sample = false;
-#endif
}
void clearInterpolation()
centroid = false;
smooth = false;
flat = false;
-#ifndef GLSLANG_WEB
nopersp = false;
explicitInterp = false;
pervertexNV = false;
perPrimitiveNV = false;
perViewNV = false;
perTaskNV = false;
-#endif
pervertexEXT = false;
}
void clearMemory()
{
-#ifndef GLSLANG_WEB
coherent = false;
devicecoherent = false;
queuefamilycoherent = false;
restrict = false;
readonly = false;
writeonly = false;
-#endif
}
const char* semanticName;
bool explicitOffset : 1;
bool defaultBlock : 1; // default blocks with matching names have structures merged when linking
-#ifdef GLSLANG_WEB
- bool isWriteOnly() const { return false; }
- bool isReadOnly() const { return false; }
- bool isRestrict() const { return false; }
- bool isCoherent() const { return false; }
- bool isVolatile() const { return false; }
- bool isSample() const { return false; }
- bool isMemory() const { return false; }
- bool isMemoryQualifierImageAndSSBOOnly() const { return false; }
- bool bufferReferenceNeedsVulkanMemoryModel() const { return false; }
- bool isInterpolation() const { return flat || smooth; }
- bool isExplicitInterpolation() const { return false; }
- bool isAuxiliary() const { return centroid; }
- bool isPatch() const { return false; }
- bool isNoContraction() const { return false; }
- void setNoContraction() { }
- bool isPervertexNV() const { return false; }
- bool isPervertexEXT() const { return pervertexEXT; }
- void setNullInit() {}
- bool isNullInit() const { return false; }
- void setSpirvByReference() { }
- bool isSpirvByReference() { return false; }
- void setSpirvLiteral() { }
- bool isSpirvLiteral() { return false; }
-#else
bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
bool nopersp : 1;
bool explicitInterp : 1;
bool isSpirvByReference() const { return spirvByReference; }
void setSpirvLiteral() { spirvLiteral = true; }
bool isSpirvLiteral() const { return spirvLiteral; }
-#endif
bool isPipeInput() const
{
}
void setBlockStorage(TBlockStorageClass newBacking) {
-#ifndef GLSLANG_WEB
layoutPushConstant = (newBacking == EbsPushConstant);
-#endif
switch (newBacking) {
case EbsUniform :
if (layoutPacking == ElpStd430) {
case EbsStorageBuffer :
storage = EvqBuffer;
break;
-#ifndef GLSLANG_WEB
case EbsPushConstant :
storage = EvqUniform;
layoutSet = TQualifier::layoutSetEnd;
layoutBinding = TQualifier::layoutBindingEnd;
break;
-#endif
default:
break;
}
}
-#ifdef GLSLANG_WEB
- bool isPerView() const { return false; }
- bool isTaskMemory() const { return false; }
- bool isArrayedIo(EShLanguage language) const { return false; }
-#else
bool isPerPrimitive() const { return perPrimitiveNV; }
bool isPerView() const { return perViewNV; }
bool isTaskMemory() const { return perTaskNV; }
return false;
}
}
-#endif
// Implementing an embedded layout-qualifier class here, since C++ can't have a real class bitfield
void clearLayout() // all layout
{
clearUniformLayout();
-#ifndef GLSLANG_WEB
layoutPushConstant = false;
layoutBufferReference = false;
layoutPassthrough = false;
layoutBindlessImage = false;
layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd;
layoutFormat = ElfNone;
-#endif
clearInterstageLayout();
{
layoutLocation = layoutLocationEnd;
layoutComponent = layoutComponentEnd;
-#ifndef GLSLANG_WEB
layoutIndex = layoutIndexEnd;
clearStreamLayout();
clearXfbLayout();
-#endif
}
-#ifndef GLSLANG_WEB
void clearStreamLayout()
{
layoutStream = layoutStreamEnd;
layoutXfbStride = layoutXfbStrideEnd;
layoutXfbOffset = layoutXfbOffsetEnd;
}
-#endif
bool hasNonXfbLayout() const
{
unsigned int layoutSpecConstantId : 11;
static const unsigned int layoutSpecConstantIdEnd = 0x7FF;
-#ifndef GLSLANG_WEB
// stored as log2 of the actual alignment value
unsigned int layoutBufferReferenceAlign : 6;
static const unsigned int layoutBufferReferenceAlignEnd = 0x3F;
bool layoutBindlessSampler;
bool layoutBindlessImage;
-#endif
bool hasUniformLayout() const
{
layoutSet = layoutSetEnd;
layoutBinding = layoutBindingEnd;
-#ifndef GLSLANG_WEB
layoutAttachment = layoutAttachmentEnd;
-#endif
}
bool hasMatrix() const
{
return layoutBinding != layoutBindingEnd;
}
-#ifdef GLSLANG_WEB
- bool hasOffset() const { return false; }
- bool isNonPerspective() const { return false; }
- bool hasIndex() const { return false; }
- unsigned getIndex() const { return 0; }
- bool hasComponent() const { return false; }
- bool hasStream() const { return false; }
- bool hasFormat() const { return false; }
- bool hasXfb() const { return false; }
- bool hasXfbBuffer() const { return false; }
- bool hasXfbStride() const { return false; }
- bool hasXfbOffset() const { return false; }
- bool hasAttachment() const { return false; }
- TLayoutFormat getFormat() const { return ElfNone; }
- bool isPushConstant() const { return false; }
- bool isShaderRecord() const { return false; }
- bool hasBufferReference() const { return false; }
- bool hasBufferReferenceAlign() const { return false; }
- bool isNonUniform() const { return false; }
-#else
bool hasOffset() const
{
return layoutOffset != layoutNotSet;
const TSpirvDecorate& getSpirvDecorate() const { assert(spirvDecorate); return *spirvDecorate; }
TSpirvDecorate& getSpirvDecorate() { assert(spirvDecorate); return *spirvDecorate; }
TString getSpirvDecorateQualifierString() const;
-#endif
+
bool hasSpecConstantId() const
{
// Not the same thing as being a specialization constant, this
{
switch (packing) {
case ElpStd140: return "std140";
-#ifndef GLSLANG_WEB
case ElpPacked: return "packed";
case ElpShared: return "shared";
case ElpStd430: return "std430";
case ElpScalar: return "scalar";
-#endif
default: return "none";
}
}
default: return "none";
}
}
-#ifdef GLSLANG_WEB
- static const char* getLayoutFormatString(TLayoutFormat f) { return "none"; }
-#else
static const char* getLayoutFormatString(TLayoutFormat f)
{
switch (f) {
default: return "none";
}
}
-#endif
};
// Qualifiers that don't need to be keep per object. They have shader scope, not object scope.
int localSize[3]; // compute shader
bool localSizeNotDefault[3]; // compute shader
int localSizeSpecId[3]; // compute shader specialization id for gl_WorkGroupSize
-#ifndef GLSLANG_WEB
bool earlyFragmentTests; // fragment input
bool postDepthCoverage; // fragment input
bool earlyAndLateFragmentTestsAMD; //fragment input
bool layoutPrimitiveCulling; // true if layout primitive_culling set
TLayoutDepth getDepth() const { return layoutDepth; }
TLayoutStencil getStencil() const { return layoutStencil; }
-#else
- TLayoutDepth getDepth() const { return EldNone; }
-#endif
void init()
{
localSizeSpecId[0] = TQualifier::layoutNotSet;
localSizeSpecId[1] = TQualifier::layoutNotSet;
localSizeSpecId[2] = TQualifier::layoutNotSet;
-#ifndef GLSLANG_WEB
earlyFragmentTests = false;
earlyAndLateFragmentTestsAMD = false;
postDepthCoverage = false;
layoutPrimitiveCulling = false;
primitives = TQualifier::layoutNotSet;
interlockOrdering = EioNone;
-#endif
}
-#ifdef GLSLANG_WEB
- bool hasBlendEquation() const { return false; }
-#else
bool hasBlendEquation() const { return blendEquation; }
-#endif
// Merge in characteristics from the 'src' qualifier. They can override when
// set, but never erase when not set.
if (src.localSizeSpecId[i] != TQualifier::layoutNotSet)
localSizeSpecId[i] = src.localSizeSpecId[i];
}
-#ifndef GLSLANG_WEB
if (src.earlyFragmentTests)
earlyFragmentTests = true;
if (src.earlyAndLateFragmentTestsAMD)
interlockOrdering = src.interlockOrdering;
if (src.layoutPrimitiveCulling)
layoutPrimitiveCulling = src.layoutPrimitiveCulling;
-#endif
}
};
const TType* userDef;
TSourceLoc loc;
TTypeParameters* typeParameters;
-#ifndef GLSLANG_WEB
// SPIR-V type defined by spirv_type directive
TSpirvType* spirvType;
-#endif
-#ifdef GLSLANG_WEB
- bool isCoopmat() const { return false; }
- bool isCoopmatNV() const { return false; }
- bool isCoopmatKHR() const { return false; }
-#else
bool isCoopmat() const { return coopmatNV || coopmatKHR; }
bool isCoopmatNV() const { return coopmatNV; }
bool isCoopmatKHR() const { return coopmatKHR; }
-#endif
void initType(const TSourceLoc& l)
{
typeParameters = nullptr;
coopmatNV = false;
coopmatKHR = false;
-#ifndef GLSLANG_WEB
spirvType = nullptr;
-#endif
}
void initQualifiers(bool global = false)
return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr;
}
-#ifndef GLSLANG_WEB
// GL_EXT_spirv_intrinsics
void setSpirvType(const TSpirvInstruction& spirvInst, const TSpirvTypeParameters* typeParams = nullptr);
-#endif
// "Image" is a superset of "Subpass"
bool isImage() const { return basicType == EbtSampler && sampler.isImage(); }
explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0,
bool isVector = false) :
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
- arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr)
-#ifndef GLSLANG_WEB
- , spirvType(nullptr)
-#endif
+ arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
+ spirvType(nullptr)
{
sampler.clear();
qualifier.clear();
TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0,
bool isVector = false) :
basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
- arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr)
-#ifndef GLSLANG_WEB
- , spirvType(nullptr)
-#endif
+ arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
+ spirvType(nullptr)
{
sampler.clear();
qualifier.clear();
explicit TType(const TPublicType& p) :
basicType(p.basicType),
vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmatNV(p.coopmatNV), coopmatKHR(p.coopmatKHR), coopmatKHRuse(-1),
- arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters)
-#ifndef GLSLANG_WEB
- , spirvType(p.spirvType)
-#endif
+ arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters),
+ spirvType(p.spirvType)
{
if (basicType == EbtSampler)
sampler = p.sampler;
TType(const TSampler& sampler, TStorageQualifier q = EvqUniform, TArraySizes* as = nullptr) :
basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
- sampler(sampler), typeParameters(nullptr)
-#ifndef GLSLANG_WEB
- , spirvType(nullptr)
-#endif
+ sampler(sampler), typeParameters(nullptr), spirvType(nullptr)
{
qualifier.clear();
qualifier.storage = q;
// for making structures, ...
TType(TTypeList* userDef, const TString& n) :
basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
- arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr)
-#ifndef GLSLANG_WEB
- , spirvType(nullptr)
-#endif
+ arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
+ spirvType(nullptr)
{
sampler.clear();
qualifier.clear();
// For interface blocks
TType(TTypeList* userDef, const TString& n, const TQualifier& q) :
basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
- qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr)
-#ifndef GLSLANG_WEB
- , spirvType(nullptr)
-#endif
+ qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr),
+ spirvType(nullptr)
{
sampler.clear();
typeName = NewPoolTString(n.c_str());
// for block reference (first parameter must be EbtReference)
explicit TType(TBasicType t, const TType &p, const TString& n) :
basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(-1),
- arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr)
-#ifndef GLSLANG_WEB
- , spirvType(nullptr)
-#endif
+ arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr),
+ spirvType(nullptr)
{
assert(t == EbtReference);
typeName = NewPoolTString(n.c_str());
referentType = copyOf.referentType;
}
typeParameters = copyOf.typeParameters;
-#ifndef GLSLANG_WEB
spirvType = copyOf.spirvType;
-#endif
coopmatNV = copyOf.isCoopMatNV();
coopmatKHR = copyOf.isCoopMatKHR();
coopmatKHRuse = copyOf.coopmatKHRuse;
virtual int getOuterArraySize() const { return arraySizes->getOuterSize(); }
virtual TIntermTyped* getOuterArrayNode() const { return arraySizes->getOuterNode(); }
virtual int getCumulativeArraySize() const { return arraySizes->getCumulativeSize(); }
-#ifdef GLSLANG_WEB
- bool isArrayOfArrays() const { return false; }
-#else
bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; }
-#endif
virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); }
virtual const TArraySizes* getArraySizes() const { return arraySizes; }
virtual TArraySizes* getArraySizes() { return arraySizes; }
return false;
}
virtual bool isOpaque() const { return basicType == EbtSampler
-#ifndef GLSLANG_WEB
- || basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery
- || basicType == EbtHitObjectNV
-#endif
- ; }
+ || basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery
+ || basicType == EbtHitObjectNV; }
virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; }
virtual bool isAttachmentEXT() const { return basicType == EbtSampler && getSampler().isAttachmentEXT(); }
// Check the block-name convention of creating a block without populating it's members:
virtual bool isUnusableName() const { return isStruct() && structure == nullptr; }
virtual bool isParameterized() const { return typeParameters != nullptr; }
-#ifdef GLSLANG_WEB
- bool isAtomic() const { return false; }
- bool isCoopMat() const { return false; }
- bool isCoopMatNV() const { return false; }
- bool isCoopMatKHR() const { return false; }
- bool isReference() const { return false; }
- bool isSpirvType() const { return false; }
-#else
bool isAtomic() const { return basicType == EbtAtomicUint; }
bool isCoopMat() const { return coopmatNV || coopmatKHR; }
bool isCoopMatNV() const { return coopmatNV; }
bool isCoopMatKHR() const { return coopmatKHR; }
bool isReference() const { return getBasicType() == EbtReference; }
bool isSpirvType() const { return getBasicType() == EbtSpirvType; }
-#endif
int getCoopMatKHRuse() const { return coopmatKHRuse; }
// return true if this type contains any subtype which satisfies the given predicate.
return contains([](const TType* t) { return t->isArray() && t->arraySizes->isOuterSpecialization(); } );
}
-#ifdef GLSLANG_WEB
- bool containsDouble() const { return false; }
- bool contains16BitFloat() const { return false; }
- bool contains64BitInt() const { return false; }
- bool contains16BitInt() const { return false; }
- bool contains8BitInt() const { return false; }
- bool containsCoopMat() const { return false; }
- bool containsReference() const { return false; }
-#else
bool containsDouble() const
{
return containsBasicType(EbtDouble);
{
return containsBasicType(EbtReference);
}
-#endif
// Array editing methods. Array descriptors can be shared across
// type instances. This allows all uses of the same array
case EbtInt: return "int";
case EbtUint: return "uint";
case EbtSampler: return "sampler/image";
-#ifndef GLSLANG_WEB
case EbtVoid: return "void";
case EbtDouble: return "double";
case EbtFloat16: return "float16_t";
case EbtString: return "string";
case EbtSpirvType: return "spirv_type";
case EbtCoopmat: return "coopmat";
-#endif
default: return "unknown type";
}
}
-#ifdef GLSLANG_WEB
- TString getCompleteString() const { return ""; }
- const char* getStorageQualifierString() const { return ""; }
- const char* getBuiltInVariableString() const { return ""; }
- const char* getPrecisionQualifierString() const { return ""; }
- TString getBasicTypeString() const { return ""; }
-#else
TString getCompleteString(bool syntactic = false, bool getQualifiers = true, bool getPrecision = true,
bool getType = true, TString name = "", TString structName = "") const
{
const char* getStorageQualifierString() const { return GetStorageQualifierString(qualifier.storage); }
const char* getBuiltInVariableString() const { return GetBuiltInVariableString(qualifier.builtIn); }
const char* getPrecisionQualifierString() const { return GetPrecisionQualifierString(qualifier.precision); }
-#endif
const TTypeList* getStruct() const { assert(isStruct()); return structure; }
void setStruct(TTypeList* s) { assert(isStruct()); structure = s; }
(typeParameters != nullptr && right.typeParameters != nullptr && *typeParameters == *right.typeParameters));
}
-#ifndef GLSLANG_WEB
// See if two type's SPIR-V type contents match
bool sameSpirvType(const TType& right) const
{
return ((spirvType == nullptr && right.spirvType == nullptr) ||
(spirvType != nullptr && right.spirvType != nullptr && *spirvType == *right.spirvType));
}
-#endif
// See if two type's elements match in all ways except basic type
// If mismatch in structure members, return member indices in lpidx and rpidx.
// See if two types match in all ways (just the actual type, not qualification)
bool operator==(const TType& right) const
{
-#ifndef GLSLANG_WEB
return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right) && sameCoopMatUse(right) && sameSpirvType(right);
-#else
- return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right);
-#endif
}
bool operator!=(const TType& right) const
unsigned int getBufferReferenceAlignment() const
{
-#ifndef GLSLANG_WEB
if (getBasicType() == glslang::EbtReference) {
return getReferentType()->getQualifier().hasBufferReferenceAlign() ?
(1u << getReferentType()->getQualifier().layoutBufferReferenceAlign) : 16u;
}
-#endif
return 0;
}
-#ifndef GLSLANG_WEB
const TSpirvType& getSpirvType() const { assert(spirvType); return *spirvType; }
-#endif
protected:
// Require consumer to pick between deep copy and shallow copy.
{
shallowCopy(copyOf);
-#ifndef GLSLANG_WEB
// GL_EXT_spirv_intrinsics
if (copyOf.qualifier.spirvDecorate) {
qualifier.spirvDecorate = new TSpirvDecorate;
spirvType = new TSpirvType;
*spirvType = *copyOf.spirvType;
}
-#endif
if (copyOf.arraySizes) {
arraySizes = new TArraySizes;
TString *typeName; // for structure type name
TSampler sampler;
TTypeParameters *typeParameters;// nullptr unless a parameterized type; can be shared across types
-#ifndef GLSLANG_WEB
TSpirvType* spirvType; // SPIR-V type defined by spirv_type directive
-#endif
};
} // end namespace glslang
EOpFunctionCall,
EOpFunction, // For function definition
EOpParameters, // an aggregate listing the parameters to a function
-#ifndef GLSLANG_WEB
EOpSpirvInst,
-#endif
//
// Unary operators
// per process threadPoolAllocator, then it causes increased memory usage per compile
// it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(long long i, const TString& n, const TType& t)
- : TIntermTyped(t), id(i),
-#ifndef GLSLANG_WEB
- flattenSubset(-1),
-#endif
- constSubtree(nullptr)
- { name = n; }
+ : TIntermTyped(t), id(i), flattenSubset(-1), constSubtree(nullptr) { name = n; }
virtual long long getId() const { return id; }
virtual void changeId(long long i) { id = i; }
virtual const TString& getName() const { return name; }
const TConstUnionArray& getConstArray() const { return constArray; }
void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
TIntermTyped* getConstSubtree() const { return constSubtree; }
-#ifndef GLSLANG_WEB
void setFlattenSubset(int subset) { flattenSubset = subset; }
virtual const TString& getAccessName() const;
int getFlattenSubset() const { return flattenSubset; } // -1 means full object
-#endif
// This is meant for cases where a node has already been constructed, and
// later on, it becomes necessary to switch to a different symbol.
protected:
long long id; // the unique id of the symbol this node represents
-#ifndef GLSLANG_WEB
int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced
-#endif
TString name; // the name of the symbol this node represents
TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value
TIntermTyped* constSubtree;
bool isConstructor() const;
bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; }
bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; }
-#ifdef GLSLANG_WEB
- bool isImage() const { return false; }
- bool isSparseTexture() const { return false; }
- bool isImageFootprint() const { return false; }
- bool isSparseImage() const { return false; }
- bool isSubgroup() const { return false; }
-#else
bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; }
bool isSparseImage() const { return op == EOpSparseImageLoad; }
bool isSubgroup() const { return op > EOpSubgroupGuardStart && op < EOpSubgroupGuardStop; }
-#endif
void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; }
TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ?
cracked.offset = true;
cracked.proj = true;
break;
-#ifndef GLSLANG_WEB
case EOpTextureClamp:
case EOpSparseTextureClamp:
cracked.lodClamp = true;
case EOpColorAttachmentReadEXT:
cracked.attachmentEXT = true;
break;
-#endif
default:
break;
}
virtual TIntermUnary* getAsUnaryNode() { return this; }
virtual const TIntermUnary* getAsUnaryNode() const { return this; }
virtual void updatePrecision();
-#ifndef GLSLANG_WEB
void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
-#endif
protected:
TIntermTyped* operand;
-#ifndef GLSLANG_WEB
TSpirvInstruction spirvInst;
-#endif
};
typedef TVector<TIntermNode*> TIntermSequence;
bool getDebug() const { return debug; }
void setPragmaTable(const TPragmaTable& pTable);
const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
-#ifndef GLSLANG_WEB
void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
-#endif
protected:
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
bool optimize;
bool debug;
TPragmaTable* pragmaTable;
-#ifndef GLSLANG_WEB
TSpirvInstruction spirvInst;
-#endif
};
//
newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
break;
-#ifndef GLSLANG_WEB
case EbtInt8:
if (rightUnionArray[i] == (signed char)0)
newConstArray[i].setI8Const((signed char)0x7F);
break;
default:
return nullptr;
-#endif
}
}
break;
newConstArray[i].setIConst(0);
break;
} else goto modulo_default;
-#ifndef GLSLANG_WEB
case EbtInt64:
if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == LLONG_MIN) {
newConstArray[i].setI64Const(0);
newConstArray[i].setIConst(0);
break;
} else goto modulo_default;
-#endif
default:
modulo_default:
newConstArray[i] = leftUnionArray[i] % rightUnionArray[i];
: -unionArray[i].getIConst());
break;
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
-#ifndef GLSLANG_WEB
case EbtInt8: newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break;
case EbtUint8: newConstArray[i].setU8Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU8Const()))); break;
case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break;
case EbtUint16:newConstArray[i].setU16Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU16Const()))); break;
case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned long long>(-static_cast<long long>(unionArray[i].getU64Const()))); break;
-#endif
default:
return nullptr;
}
case EOpConvDoubleToInt:
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
-#ifndef GLSLANG_WEB
case EOpConvInt8ToBool:
newConstArray[i].setBConst(unionArray[i].getI8Const() != 0); break;
case EOpConvUint8ToBool:
case EOpConvUint64ToPtr:
case EOpConstructReference:
newConstArray[i].setU64Const(unionArray[i].getU64Const()); break;
-#endif
// TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out
case EbtUint:
newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
break;
-#ifndef GLSLANG_WEB
case EbtInt8:
newConstArray[comp].setI8Const(std::min(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
break;
case EbtUint64:
newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
break;
-#endif
default: assert(false && "Default missing");
}
break;
case EbtUint:
newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
break;
-#ifndef GLSLANG_WEB
case EbtInt8:
newConstArray[comp].setI8Const(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
break;
case EbtUint64:
newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
break;
-#endif
default: assert(false && "Default missing");
}
break;
newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()),
childConstUnions[2][arg2comp].getUConst()));
break;
-#ifndef GLSLANG_WEB
case EbtInt8:
newConstArray[comp].setI8Const(std::min(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()),
childConstUnions[2][arg2comp].getI8Const()));
newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()),
childConstUnions[2][arg2comp].getU64Const()));
break;
-#endif
default: assert(false && "Default missing");
}
break;
EProfile EDesktopProfile = static_cast<EProfile>(ENoProfile | ECoreProfile | ECompatibilityProfile);
// Declare pointers to put into the table for versioning.
-#ifdef GLSLANG_WEB
- const Versioning* Es300Desktop130 = nullptr;
- const Versioning* Es310Desktop420 = nullptr;
-#else
const Versioning Es300Desktop130Version[] = { { EEsProfile, 0, 300, 0, nullptr },
{ EDesktopProfile, 0, 130, 0, nullptr },
{ EBadProfile } };
{ EDesktopProfile, 0, 450, 0, nullptr },
{ EBadProfile } };
const Versioning* Es310Desktop450 = &Es310Desktop450Version[0];
-#endif
// The main descriptor of what a set of function prototypes can look like, and
// a pointer to extra versioning information, when needed.
{ EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
{ EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 },
{ EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, Es310Desktop420 },
-#ifndef GLSLANG_WEB
{ EOpMix, "mix", 3, TypeB, ClassRegular, Es310Desktop450 },
{ EOpMix, "mix", 3, TypeIU, ClassLB, Es310Desktop450 },
-#endif
{ EOpNull }
};
if (arg == function.numArguments - 1 && (function.classes & ClassLO))
decls.append("out ");
if (arg == 0) {
-#ifndef GLSLANG_WEB
if (function.classes & ClassCV)
decls.append("coherent volatile ");
-#endif
if (function.classes & ClassFIO)
decls.append("inout ");
if (function.classes & ClassFO)
// See if the tabled versioning information allows the current version.
bool ValidVersion(const BuiltInFunction& function, int version, EProfile profile, const SpvVersion& /* spVersion */)
{
-#if defined(GLSLANG_WEB)
- // all entries in table are valid
- return true;
-#endif
-
// nullptr means always valid
if (function.versioning == nullptr)
return true;
prefixes[EbtFloat] = "";
prefixes[EbtInt] = "i";
prefixes[EbtUint] = "u";
-#if !defined(GLSLANG_WEB)
prefixes[EbtFloat16] = "f16";
prefixes[EbtInt8] = "i8";
prefixes[EbtUint8] = "u8";
prefixes[EbtUint16] = "u16";
prefixes[EbtInt64] = "i64";
prefixes[EbtUint64] = "u64";
-#endif
postfixes[2] = "2";
postfixes[3] = "3";
dimMap[Esd2D] = 2;
dimMap[Esd3D] = 3;
dimMap[EsdCube] = 3;
-#ifndef GLSLANG_WEB
dimMap[Esd1D] = 1;
dimMap[EsdRect] = 2;
dimMap[EsdBuffer] = 1;
dimMap[EsdSubpass] = 2; // potentially unused for now
dimMap[EsdAttachmentEXT] = 2; // potentially unused for now
-#endif
}
TBuiltIns::~TBuiltIns()
//
void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvVersion)
{
-#ifdef GLSLANG_WEB
- version = 310;
- profile = EEsProfile;
-#endif
addTabledBuiltins(version, profile, spvVersion);
//============================================================================
//
//============================================================================
-#ifndef GLSLANG_WEB
//
// Derivatives Functions.
//
"void atomicStore(coherent volatile out double, double, int, int, int);"
"\n");
}
-#endif // !GLSLANG_WEB
if ((profile == EEsProfile && version >= 300) ||
(profile != EEsProfile && version >= 150)) { // GL_ARB_shader_bit_encoding
"\n");
}
-#ifndef GLSLANG_WEB
if ((profile != EEsProfile && version >= 400) ||
(profile == EEsProfile && version >= 310)) { // GL_OES_gpu_shader5
"\n");
}
-#endif
if ((profile == EEsProfile && version >= 300) ||
(profile != EEsProfile && version >= 150)) {
"\n");
}
-#ifndef GLSLANG_WEB
if ((profile == EEsProfile && version >= 310) ||
(profile != EEsProfile && version >= 150)) {
commonBuiltins.append(
"vec4 unpackUnorm4x8(highp uint);"
"\n");
}
-#endif
//
// Matrix Functions.
}
}
-#ifndef GLSLANG_WEB
//
// Original-style texture functions existing in all stages.
// (Per-stage functions below.)
"void EndPrimitive();"
"\n");
}
-#endif // !GLSLANG_WEB
//============================================================================
//
"void groupMemoryBarrier();"
);
}
-#ifndef GLSLANG_WEB
if ((profile != EEsProfile && version >= 420) || esBarrier) {
if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed) {
commonBuiltins.append("void memoryBarrierAtomicCounter();");
"void SetMeshOutputsEXT(uint, uint);"
"\n");
}
-#endif // !GLSLANG_WEB
//============================================================================
//
"highp float diff;" // f - n
);
} else {
-#ifndef GLSLANG_WEB
commonBuiltins.append(
"float near;" // n
"float far;" // f
"float diff;" // f - n
);
-#endif
}
commonBuiltins.append(
"\n");
}
-#if !defined(GLSLANG_WEB)
if (spvVersion.spv == 0 && IncludeLegacy(version, profile, spvVersion)) {
//
// Matrix state. p. 31, 32, 37, 39, 40.
"\n");
}
-#endif // !GLSLANG_WEB
//============================================================================
//
"\n");
}
-#ifndef GLSLANG_WEB
//============================================================================
//
// Define the interface to the mesh/task shader.
"in highp int gl_InstanceID;" // needs qualifier fixed later
);
if (spvVersion.vulkan > 0)
-#endif
stageBuiltins[EShLangVertex].append(
"in highp int gl_VertexIndex;"
"in highp int gl_InstanceIndex;"
);
-#ifndef GLSLANG_WEB
if (version < 310)
-#endif
stageBuiltins[EShLangVertex].append(
"highp vec4 gl_Position;" // needs qualifier fixed later
"highp float gl_PointSize;" // needs qualifier fixed later
);
-#ifndef GLSLANG_WEB
else
stageBuiltins[EShLangVertex].append(
"out gl_PerVertex {"
"mediump vec2 gl_PointCoord;" // needs qualifier fixed later
);
}
-#endif
if (version >= 300) {
stageBuiltins[EShLangFragment].append(
"highp vec4 gl_FragCoord;" // needs qualifier fixed later
"highp float gl_FragDepth;" // needs qualifier fixed later
);
}
-#ifndef GLSLANG_WEB
if (version >= 310) {
stageBuiltins[EShLangFragment].append(
"bool gl_HelperInvocation;" // needs qualifier fixed later
"flat in highp int gl_ShadingRateEXT;" // GL_EXT_fragment_shading_rate
);
}
-#endif
stageBuiltins[EShLangFragment].append("\n");
if (version >= 130)
add2ndGenerationSamplingImaging(version, profile, spvVersion);
-#ifndef GLSLANG_WEB
-
if ((profile != EEsProfile && version >= 140) ||
(profile == EEsProfile && version >= 310)) {
stageBuiltins[EShLangFragment].append(
}
}
}
-#endif // !GLSLANG_WEB
// printf("%s\n", commonBuiltins.c_str());
// printf("%s\n", stageBuiltins[EShLangFragment].c_str());
// enumerate all the types
const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint,
-#if !defined(GLSLANG_WEB)
- EbtFloat16
-#endif
+ EbtFloat16
};
-#ifdef GLSLANG_WEB
- bool skipBuffer = true;
- bool skipCubeArrayed = true;
- const int image = 0;
-#else
bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140);
bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130);
for (int image = 0; image <= 1; ++image) // loop over "bool" image vs sampler
-#endif
{
for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not
-#ifdef GLSLANG_WEB
- const int ms = 0;
-#else
for (int ms = 0; ms <= 1; ++ms) // loop over "bool" multisample or not
-#endif
{
if ((ms || image) && shadow)
continue;
continue;
for (int arrayed = 0; arrayed <= 1; ++arrayed) { // loop over "bool" arrayed or not
-#ifdef GLSLANG_WEB
- for (int dim = Esd2D; dim <= EsdCube; ++dim) { // 2D, 3D, and Cube
-#else
for (int dim = Esd1D; dim < EsdNumDims; ++dim) { // 1D, ..., buffer, subpass
if (dim == EsdAttachmentEXT)
continue;
continue;
if (ms && arrayed && profile == EEsProfile && version < 310)
continue;
-#endif
if (dim == Esd3D && shadow)
continue;
if (dim == EsdCube && arrayed && skipCubeArrayed)
// Loop over the bTypes
for (size_t bType = 0; bType < sizeof(bTypes)/sizeof(TBasicType); ++bType) {
-#ifndef GLSLANG_WEB
if (bTypes[bType] == EbtFloat16 && (profile == EEsProfile || version < 450))
continue;
if (dim == EsdRect && version < 140 && bType > 0)
continue;
-#endif
if (shadow && (bTypes[bType] == EbtInt || bTypes[bType] == EbtUint))
continue;
//
// Now, make all the function prototypes for the type we just built...
//
TSampler sampler;
-#ifndef GLSLANG_WEB
if (dim == EsdSubpass) {
sampler.setSubpass(bTypes[bType], ms ? true : false);
} else if (dim == EsdAttachmentEXT) {
sampler.setAttachmentEXT(bTypes[bType]);
} else
-#endif
if (image) {
sampler.setImage(bTypes[bType], (TSamplerDim)dim, arrayed ? true : false,
shadow ? true : false,
TString typeName = sampler.getString();
-#ifndef GLSLANG_WEB
if (dim == EsdSubpass) {
addSubpassSampling(sampler, typeName, version, profile);
continue;
}
-#endif
addQueryFunctions(sampler, typeName, version, profile);
addImageFunctions(sampler, typeName, version, profile);
else {
addSamplingFunctions(sampler, typeName, version, profile);
-#ifndef GLSLANG_WEB
addGatherFunctions(sampler, typeName, version, profile);
if (spvVersion.vulkan > 0 && sampler.isCombined() && !sampler.shadow) {
// Base Vulkan allows texelFetch() for
addSamplingFunctions(sampler, textureTypeName, version, profile);
addQueryFunctions(sampler, textureTypeName, version, profile);
}
-#endif
}
}
}
int sizeDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0) - (sampler.dim == EsdCube ? 1 : 0);
-#ifdef GLSLANG_WEB
- commonBuiltins.append("highp ");
- commonBuiltins.append("ivec");
- commonBuiltins.append(postfixes[sizeDims]);
- commonBuiltins.append(" textureSize(");
- commonBuiltins.append(typeName);
- commonBuiltins.append(",int);\n");
- return;
-#endif
-
if (sampler.isImage() && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 420)))
return;
//
void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile)
{
-#ifdef GLSLANG_WEB
- profile = EEsProfile;
- version = 310;
-#endif
-
//
// texturing
//
continue;
// loop over 16-bit floating-point texel addressing
-#if defined(GLSLANG_WEB)
- const int f16TexAddr = 0;
-#else
for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr)
-#endif
{
if (f16TexAddr && sampler.type != EbtFloat16)
continue;
totalDims--;
}
// loop over "bool" lod clamp
-#if defined(GLSLANG_WEB)
- const int lodClamp = 0;
-#else
for (int lodClamp = 0; lodClamp <= 1 ;++lodClamp)
-#endif
{
if (lodClamp && (profile == EEsProfile || version < 450))
continue;
continue;
// loop over "bool" sparse or not
-#if defined(GLSLANG_WEB)
- const int sparse = 0;
-#else
for (int sparse = 0; sparse <= 1; ++sparse)
-#endif
{
if (sparse && (profile == EEsProfile || version < 450))
continue;
//
void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile)
{
-#ifdef GLSLANG_WEB
- profile = EEsProfile;
- version = 310;
-#endif
-
switch (sampler.dim) {
case Esd2D:
case EsdRect:
//
void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language)
{
-#ifdef GLSLANG_WEB
- version = 310;
- profile = EEsProfile;
-#endif
-
//
// Initialize the context-dependent (resource-dependent) built-in strings for parsing.
//
s.append(builtInConstant);
}
-#ifndef GLSLANG_WEB
if (version >= 310) {
// geometry
snprintf(builtInConstant, maxSize, "const int gl_MaxTransformFeedbackInterleavedComponents = %d;", resources.maxTransformFeedbackInterleavedComponents);
s.append(builtInConstant);
}
-#endif
}
// compute
s.append("\n");
}
-#ifndef GLSLANG_WEB
// images (some in compute below)
if ((profile == EEsProfile && version >= 310) ||
(profile != EEsProfile && version >= 130)) {
s.append("\n");
}
-#endif
s.append("\n");
}
//
void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable)
{
-#ifdef GLSLANG_WEB
- version = 310;
- profile = EEsProfile;
-#endif
-
//
// Tag built-in variables and functions with additional qualifier and extension information
// that cannot be declared with the text strings.
BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable);
}
-#ifndef GLSLANG_WEB
if (spvVersion.vulkan == 0) {
SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable);
SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable);
case EShLangTessEvaluation:
case EShLangGeometry:
-#endif // !GLSLANG_WEB
SpecialQualifier("gl_Position", EvqPosition, EbvPosition, symbolTable);
SpecialQualifier("gl_PointSize", EvqPointSize, EbvPointSize, symbolTable);
BuiltInVariable("gl_out", "gl_Position", EbvPosition, symbolTable);
BuiltInVariable("gl_out", "gl_PointSize", EbvPointSize, symbolTable);
-#ifndef GLSLANG_WEB
SpecialQualifier("gl_ClipVertex", EvqClipVertex, EbvClipVertex, symbolTable);
BuiltInVariable("gl_in", "gl_ClipDistance", EbvClipDistance, symbolTable);
symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate);
}
}
-
-#endif // !GLSLANG_WEB
break;
case EShLangFragment:
}
}
SpecialQualifier("gl_FragDepth", EvqFragDepth, EbvFragDepth, symbolTable);
-#ifndef GLSLANG_WEB
SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, EbvFragDepth, symbolTable);
SpecialQualifier("gl_FragStencilRefARB", EvqFragStencil, EbvFragStencilRef, symbolTable);
SpecialQualifier("gl_HelperInvocation", EvqVaryingIn, EbvHelperInvocation, symbolTable);
symbolTable.setFunctionExtensions("stencilAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image);
symbolTable.setFunctionExtensions("depthAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image);
symbolTable.setFunctionExtensions("colorAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image);
-#endif // !GLSLANG_WEB
break;
case EShLangCompute:
BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable);
-#ifndef GLSLANG_WEB
if ((profile != EEsProfile && version >= 140) ||
(profile == EEsProfile && version >= 310)) {
symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
symbolTable.setVariableExtensions("gl_ShadingRateFlag2HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate);
symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate);
}
-#endif // !GLSLANG_WEB
break;
-#if !defined(GLSLANG_WEB)
case EShLangRayGen:
case EShLangIntersect:
case EShLangAnyHit:
symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate);
}
break;
-#endif
default:
assert(false && "Language not supported");
relateTabledBuiltins(version, profile, spvVersion, language, symbolTable);
-#ifndef GLSLANG_WEB
symbolTable.relateToOperator("doubleBitsToInt64", EOpDoubleBitsToInt64);
symbolTable.relateToOperator("doubleBitsToUint64", EOpDoubleBitsToUint64);
symbolTable.relateToOperator("int64BitsToDouble", EOpInt64BitsToDouble);
default:
assert(false && "Language not supported");
}
-#endif // !GLSLANG_WEB
}
//
//
void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources)
{
-#ifndef GLSLANG_WEB
if (profile != EEsProfile && version >= 430 && version < 440) {
symbolTable.setVariableExtensions("gl_MaxTransformFeedbackBuffers", 1, &E_GL_ARB_enhanced_layouts);
symbolTable.setVariableExtensions("gl_MaxTransformFeedbackInterleavedComponents", 1, &E_GL_ARB_enhanced_layouts);
default:
break;
}
-#endif
}
} // end namespace glslang
case EOpConstructFloat: newType = EbtFloat; break;
case EOpConstructInt: newType = EbtInt; break;
case EOpConstructUint: newType = EbtUint; break;
-#ifndef GLSLANG_WEB
case EOpConstructInt8: newType = EbtInt8; break;
case EOpConstructUint8: newType = EbtUint8; break;
case EOpConstructInt16: newType = EbtInt16; break;
case EOpConstructUint64: newType = EbtUint64; break;
case EOpConstructDouble: newType = EbtDouble; break;
case EOpConstructFloat16: newType = EbtFloat16; break;
-#endif
default: break; // some compilers want this
}
bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& newOp) const
{
switch (dst) {
-#ifndef GLSLANG_WEB
case EbtDouble:
switch (src) {
case EbtUint: newOp = EOpConvUintToDouble; break;
return false;
}
break;
-#endif
case EbtFloat:
switch (src) {
case EbtInt: newOp = EOpConvIntToFloat; break;
case EbtUint: newOp = EOpConvUintToFloat; break;
case EbtBool: newOp = EOpConvBoolToFloat; break;
-#ifndef GLSLANG_WEB
case EbtDouble: newOp = EOpConvDoubleToFloat; break;
case EbtInt8: newOp = EOpConvInt8ToFloat; break;
case EbtUint8: newOp = EOpConvUint8ToFloat; break;
case EbtFloat16: newOp = EOpConvFloat16ToFloat; break;
case EbtInt64: newOp = EOpConvInt64ToFloat; break;
case EbtUint64: newOp = EOpConvUint64ToFloat; break;
-#endif
default:
return false;
}
break;
-#ifndef GLSLANG_WEB
case EbtFloat16:
switch (src) {
case EbtInt8: newOp = EOpConvInt8ToFloat16; break;
return false;
}
break;
-#endif
case EbtBool:
switch (src) {
case EbtInt: newOp = EOpConvIntToBool; break;
case EbtUint: newOp = EOpConvUintToBool; break;
case EbtFloat: newOp = EOpConvFloatToBool; break;
-#ifndef GLSLANG_WEB
case EbtDouble: newOp = EOpConvDoubleToBool; break;
case EbtInt8: newOp = EOpConvInt8ToBool; break;
case EbtUint8: newOp = EOpConvUint8ToBool; break;
case EbtFloat16: newOp = EOpConvFloat16ToBool; break;
case EbtInt64: newOp = EOpConvInt64ToBool; break;
case EbtUint64: newOp = EOpConvUint64ToBool; break;
-#endif
default:
return false;
}
break;
-#ifndef GLSLANG_WEB
case EbtInt8:
switch (src) {
case EbtUint8: newOp = EOpConvUint8ToInt8; break;
return false;
}
break;
-#endif
case EbtInt:
switch (src) {
case EbtUint: newOp = EOpConvUintToInt; break;
case EbtBool: newOp = EOpConvBoolToInt; break;
case EbtFloat: newOp = EOpConvFloatToInt; break;
-#ifndef GLSLANG_WEB
case EbtInt8: newOp = EOpConvInt8ToInt; break;
case EbtUint8: newOp = EOpConvUint8ToInt; break;
case EbtInt16: newOp = EOpConvInt16ToInt; break;
case EbtFloat16: newOp = EOpConvFloat16ToInt; break;
case EbtInt64: newOp = EOpConvInt64ToInt; break;
case EbtUint64: newOp = EOpConvUint64ToInt; break;
-#endif
default:
return false;
}
case EbtInt: newOp = EOpConvIntToUint; break;
case EbtBool: newOp = EOpConvBoolToUint; break;
case EbtFloat: newOp = EOpConvFloatToUint; break;
-#ifndef GLSLANG_WEB
case EbtInt8: newOp = EOpConvInt8ToUint; break;
case EbtUint8: newOp = EOpConvUint8ToUint; break;
case EbtInt16: newOp = EOpConvInt16ToUint; break;
case EbtFloat16: newOp = EOpConvFloat16ToUint; break;
case EbtInt64: newOp = EOpConvInt64ToUint; break;
case EbtUint64: newOp = EOpConvUint64ToUint; break;
-#endif
// For bindless texture type conversion, add a dummy convert op, just
// to generate a new TIntermTyped
// uvec2(any sampler type)
return false;
}
break;
-#ifndef GLSLANG_WEB
case EbtInt64:
switch (src) {
case EbtInt8: newOp = EOpConvInt8ToInt64; break;
return false;
}
break;
-#endif
default:
return false;
}
// Add a new newNode for the conversion.
//
-#ifndef GLSLANG_WEB
bool convertToIntTypes = (convertTo == EbtInt8 || convertTo == EbtUint8 ||
convertTo == EbtInt16 || convertTo == EbtUint16 ||
convertTo == EbtInt || convertTo == EbtUint ||
return nullptr;
}
}
-#endif
TIntermUnary* newNode = nullptr;
TOperator newOp = EOpNull;
newNode = addUnaryNode(newOp, node, node->getLoc(), newType);
if (node->getAsConstantUnion()) {
-#ifndef GLSLANG_WEB
// 8/16-bit storage extensions don't support 8/16-bit constants, so don't fold conversions
// to those types
if ((getArithemeticInt8Enabled() || !(convertTo == EbtInt8 || convertTo == EbtUint8)) &&
(getArithemeticInt16Enabled() || !(convertTo == EbtInt16 || convertTo == EbtUint16)) &&
(getArithemeticFloat16Enabled() || !(convertTo == EbtFloat16)))
-#endif
{
TIntermTyped* folded = node->getAsConstantUnion()->fold(newOp, newType);
if (folded)
case EOpConstructFloat:
case EOpConstructInt:
case EOpConstructUint:
-#ifndef GLSLANG_WEB
case EOpConstructDouble:
case EOpConstructFloat16:
case EOpConstructInt8:
case EOpConstructUint64:
break;
-#endif
-
//
// Implicit conversions
//
}
bool canPromoteConstant = true;
-#ifndef GLSLANG_WEB
// GL_EXT_shader_16bit_storage can't do OpConstantComposite with
// 16-bit types, so disable promotion for those types.
// Many issues with this, from JohnK:
default:
break;
}
-#endif
if (canPromoteConstant && node->getAsConstantUnion())
return promoteConstantUnion(type.getBasicType(), node->getAsConstantUnion());
bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const
{
-#ifdef GLSLANG_WEB
- return false;
-#endif
-
switch (from) {
case EbtInt:
switch(to) {
bool TIntermediate::isFPConversion(TBasicType from, TBasicType to) const
{
-#ifdef GLSLANG_WEB
- return false;
-#endif
-
if (to == EbtFloat && from == EbtFloat16) {
return true;
} else {
break;
}
break;
-#ifndef GLSLANG_WEB
case EbtInt8:
case EbtUint8:
case EbtInt16:
return true;
}
break;
-#endif
default:
break;
}
static bool canSignedIntTypeRepresentAllUnsignedValues(TBasicType sintType, TBasicType uintType)
{
-#ifdef GLSLANG_WEB
- return false;
-#endif
-
switch(sintType) {
case EbtInt8:
switch(uintType) {
static TBasicType getCorrespondingUnsignedType(TBasicType type)
{
-#ifdef GLSLANG_WEB
- assert(type == EbtInt);
- return EbtUint;
-#endif
-
switch(type) {
case EbtInt8:
return EbtUint8;
}
}
break;
-#ifndef GLSLANG_WEB
case EbtDouble:
if (type.getMatrixCols()) {
switch (type.getMatrixCols()) {
case EbtAccStruct:
op = EOpConstructAccStruct;
break;
-#endif
default:
break;
}
if (aggRoot && aggRoot->getOp() == EOpNull)
aggRoot->setOperator(EOpSequence);
-#ifndef GLSLANG_WEB
// Propagate 'noContraction' label in backward from 'precise' variables.
glslang::PropagateNoContraction(*this);
assert(0);
break;
}
-#endif
return true;
}
#define PROMOTE(Set, CType, Get) leftUnionArray[i].Set(static_cast<CType>(rightUnionArray[i].Get()))
#define PROMOTE_TO_BOOL(Get) leftUnionArray[i].setBConst(rightUnionArray[i].Get() != 0)
-#ifdef GLSLANG_WEB
-#define TO_ALL(Get) \
- switch (promoteTo) { \
- case EbtFloat: PROMOTE(setDConst, double, Get); break; \
- case EbtInt: PROMOTE(setIConst, int, Get); break; \
- case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \
- case EbtBool: PROMOTE_TO_BOOL(Get); break; \
- default: return node; \
- }
-#else
#define TO_ALL(Get) \
switch (promoteTo) { \
case EbtFloat16: PROMOTE(setDConst, double, Get); break; \
case EbtBool: PROMOTE_TO_BOOL(Get); break; \
default: return node; \
}
-#endif
switch (node->getType().getBasicType()) {
case EbtFloat: TO_ALL(getDConst); break;
case EbtInt: TO_ALL(getIConst); break;
case EbtUint: TO_ALL(getUConst); break;
case EbtBool: TO_ALL(getBConst); break;
-#ifndef GLSLANG_WEB
case EbtFloat16: TO_ALL(getDConst); break;
case EbtDouble: TO_ALL(getDConst); break;
case EbtInt8: TO_ALL(getI8Const); break;
case EbtUint8: TO_ALL(getU8Const); break;
case EbtUint16: TO_ALL(getU16Const); break;
case EbtUint64: TO_ALL(getU64Const); break;
-#endif
default: return node;
}
}
}
}
-#if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL)
-
void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...)
{
va_end(args);
}
-#endif
-
//
// Both test and if necessary, spit out an error, to see if the node is really
// an l-value that can be operated on this way.
case EvqConst: 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;
-#ifndef GLSLANG_WEB
case EvqBuffer:
if (node->getQualifier().isReadOnly())
message = "can't modify a readonly buffer";
if (language != EShLangIntersect)
message = "cannot modify hitAttributeNV in this stage";
break;
-#endif
default:
//
case EbtVoid:
message = "can't modify void";
break;
-#ifndef GLSLANG_WEB
case EbtAtomicUint:
message = "can't modify an atomic_uint";
break;
case EbtHitObjectNV:
message = "can't modify hitObjectNV";
break;
-#endif
default:
break;
}
infoSink, forwardCompatible, messages, entryPoint),
inMain(false),
blockName(nullptr),
- limits(resources.limits)
-#ifndef GLSLANG_WEB
- ,
+ limits(resources.limits),
atomicUintOffsets(nullptr), anyIndexLimits(false)
-#endif
{
// decide whether precision qualifiers should be ignored or respected
if (isEsProfile() || spvVersion.vulkan > 0) {
globalSharedDefaults.layoutMatrix = ElmColumnMajor;
globalSharedDefaults.layoutPacking = ElpStd430;
-#ifndef GLSLANG_WEB
// "Shaders in the transform
// feedback capturing mode have an initial global default of
// layout(xfb_buffer = 0) out;"
if (language == EShLangGeometry)
globalOutputDefaults.layoutStream = 0;
-#endif
if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "main")
infoSink.info.message(EPrefixError, "Source entry point must be \"main\"");
TParseContext::~TParseContext()
{
-#ifndef GLSLANG_WEB
delete [] atomicUintOffsets;
-#endif
}
// Set up all default precisions as needed by the current environment.
resources = r;
intermediate.setLimits(r);
-#ifndef GLSLANG_WEB
anyIndexLimits = ! limits.generalAttributeMatrixVectorIndexing ||
! limits.generalConstantMatrixVectorIndexing ||
! limits.generalSamplerIndexing ||
atomicUintOffsets = new int[resources.maxAtomicCounterBindings];
for (int b = 0; b < resources.maxAtomicCounterBindings; ++b)
atomicUintOffsets[b] = 0;
-#endif
}
//
void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens)
{
-#ifndef GLSLANG_WEB
if (pragmaCallback)
pragmaCallback(loc.line, tokens);
setInvariant(loc, "gl_FragColor");
setInvariant(loc, "gl_FragData");
}
-#endif
}
//
if (symbol && symbol->getNumExtensions())
requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str());
-#ifndef GLSLANG_WEB
if (symbol && symbol->isReadOnly()) {
// All shared things containing an unsized array must be copied up
// on first use, so that all future references will share its array structure,
makeEditable(symbol);
}
}
-#endif
const TVariable* variable;
const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : nullptr;
// at least one of base and index is not a front-end constant variable...
TIntermTyped* result = nullptr;
-#ifndef GLSLANG_WEB
if (base->isReference() && ! base->isArray()) {
requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "buffer reference indexing");
if (base->getType().getReferentType()->containsUnsizedArray()) {
}
if (base->getAsSymbolNode() && isIoResizeArray(base->getType()))
handleIoResizeArrayAccess(loc, base);
-#endif
if (index->getQualifier().isFrontEndConstant())
checkIndex(loc, base->getType(), indexValue);
if (index->getQualifier().isFrontEndConstant()) {
-#ifndef GLSLANG_WEB
if (base->getType().isUnsizedArray()) {
base->getWritableType().updateImplicitArraySize(indexValue + 1);
base->getWritableType().setImplicitlySized(true);
}
}
} else
-#endif
checkIndex(loc, base->getType(), indexValue);
result = intermediate.addIndex(EOpIndexDirect, base, index, loc);
} else {
-#ifndef GLSLANG_WEB
if (base->getType().isUnsizedArray()) {
// we have a variable index into an unsized array, which is okay,
// depending on the situation
}
base->getWritableType().setArrayVariablyIndexed();
}
-#endif
if (base->getBasicType() == EbtBlock) {
if (base->getQualifier().storage == EvqBuffer)
requireProfile(base->getLoc(), ~EEsProfile, "variable indexing buffer block array");
}
result->setType(newType);
-#ifndef GLSLANG_WEB
inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier());
// Propagate nonuniform
if (anyIndexLimits)
handleIndexLimits(loc, base, index);
-#endif
return result;
}
-#ifndef GLSLANG_WEB
-
// for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms
void TParseContext::handleIndexLimits(const TSourceLoc& /*loc*/, TIntermTyped* base, TIntermTyped* index)
{
}
}
-#endif // GLSLANG_WEB
-
// Handle seeing a binary node with a math operation.
// Returns nullptr if not semantically allowed.
TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right)
TSymbol* symbol = symbolTable.find(function.getMangledName(), &builtIn);
if (symbol && symbol->getAsFunction() && builtIn)
requireProfile(loc, ~EEsProfile, "redefinition of built-in function");
-#ifndef GLSLANG_WEB
// Check the validity of using spirv_literal qualifier
for (int i = 0; i < function.getParamCount(); ++i) {
if (function[i].type->getQualifier().isSpirvLiteral() && function.getBuiltInOp() != EOpSpirvInst)
// respect this redeclared one.
if (symbol && builtIn && function.getBuiltInOp() == EOpSpirvInst)
symbol = nullptr;
-#endif
const TFunction* prevDec = symbol ? symbol->getAsFunction() : nullptr;
if (prevDec) {
if (prevDec->isPrototyped() && prototype)
profileRequires(loc, EEsProfile, 300, nullptr, "multiple prototypes for same function");
if (prevDec->getType() != function.getType())
error(loc, "overloaded functions must have the same return type", function.getName().c_str(), "");
-#ifndef GLSLANG_WEB
if (prevDec->getSpirvInstruction() != function.getSpirvInstruction()) {
error(loc, "overloaded functions must have the same qualifiers", function.getName().c_str(),
"spirv_instruction");
}
-#endif
for (int i = 0; i < prevDec->getParamCount(); ++i) {
if ((*prevDec)[i].type->getQualifier().storage != function[i].type->getQualifier().storage)
error(loc, "overloaded functions must have the same parameter storage qualifiers for argument", function[i].type->getStorageQualifierString(), "%d", i+1);
if (lValueErrorCheck(arguments->getLoc(), "assign", arg->getAsTyped()))
error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", "");
}
-#ifndef GLSLANG_WEB
if (formalQualifier.isSpirvLiteral()) {
if (!arg->getAsTyped()->getQualifier().isFrontEndConstant()) {
error(arguments->getLoc(),
"spirv_literal", "");
}
}
-#endif
const TType& argType = arg->getAsTyped()->getType();
const TQualifier& argQualifier = argType.getQualifier();
bool containsBindlessSampler = intermediate.getBindlessMode() && argType.containsSampler();
if (argQualifier.isMemory() && !containsBindlessSampler && (argType.containsOpaque() || argType.isReference())) {
const char* message = "argument cannot drop memory qualifier when passed to formal parameter";
-#ifndef GLSLANG_WEB
if (argQualifier.volatil && ! formalQualifier.volatil)
error(arguments->getLoc(), message, "volatile", "");
if (argQualifier.coherent && ! (formalQualifier.devicecoherent || formalQualifier.coherent))
// Don't check 'restrict', it is different than the rest:
// "...but only restrict can be taken away from a calling argument, by a formal parameter that
// lacks the restrict qualifier..."
-#endif
}
if (!builtIn && argQualifier.getFormat() != formalQualifier.getFormat()) {
// we have mismatched formats, which should only be allowed if writeonly
if (builtIn && fnCandidate->getBuiltInOp() != EOpNull) {
// A function call mapped to a built-in operation.
result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate);
-#ifndef GLSLANG_WEB
} else if (fnCandidate->getBuiltInOp() == EOpSpirvInst) {
// When SPIR-V instruction qualifier is specified, the function call is still mapped to a built-in operation.
result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate);
-#endif
} else {
// This is a function call not mapped to built-in operator.
// It could still be a built-in function, but only if PureOperatorBuiltins == false.
intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName());
}
-#ifndef GLSLANG_WEB
if (builtIn)
nonOpBuiltInCheck(loc, *fnCandidate, *call);
else
-#endif
userFunctionCallCheck(loc, *call);
}
} else if (result->getAsOperator())
builtInOpCheck(loc, function, *result->getAsOperator());
-#ifndef GLSLANG_WEB
// Special handling for function call with SPIR-V instruction qualifier specified
if (function.getBuiltInOp() == EOpSpirvInst) {
if (auto agg = result->getAsAggregate()) {
} else
assert(0);
}
-#endif
return result;
}
TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value)
{
-#ifndef GLSLANG_WEB
storage16BitAssignmentCheck(loc, value->getType(), "return");
-#endif
functionReturnsValue = true;
TIntermBranch* branch = nullptr;
// See if the operation is being done in an illegal location.
void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
{
-#ifndef GLSLANG_WEB
switch (op) {
case EOpBarrier:
if (language == EShLangTessControl) {
default:
break;
}
-#endif
}
// Finish processing object.length(). This started earlier in handleDotDereference(), where
const TType& type = intermNode->getAsTyped()->getType();
if (type.isArray()) {
if (type.isUnsizedArray()) {
-#ifndef GLSLANG_WEB
if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) {
// We could be between a layout declaration that gives a built-in io array implicit size and
// a user redeclaration of that array, meaning we have to substitute its implicit size here
length = getIoArrayImplicitSize(type.getQualifier());
}
}
-#endif
if (length == 0) {
-#ifndef GLSLANG_WEB
if (intermNode->getAsSymbolNode() && isIoResizeArray(type))
error(loc, "", function->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier");
else if (isRuntimeLength(*intermNode->getAsTyped())) {
// Create a unary op and let the back end handle it
return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt));
} else
-#endif
error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method");
}
} else if (type.getOuterArrayNode()) {
//
void TParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments) const
{
-#ifndef GLSLANG_WEB
TIntermAggregate* aggregate = arguments->getAsAggregate();
// Process each argument's conversion
}
}
}
-#endif
}
//
//
TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const
{
-#ifdef GLSLANG_WEB
- return &intermNode;
-#else
TIntermSequence& arguments = intermNode.getSequence();
// Will there be any output conversions?
conversionTree = intermediate.setAggregateOperator(conversionTree, EOpComma, intermNode.getType(), intermNode.getLoc());
return conversionTree;
-#endif
}
TIntermTyped* TParseContext::addAssign(const TSourceLoc& loc, TOperator op, TIntermTyped* left, TIntermTyped* right)
TString featureString;
const char* feature = nullptr;
switch (callNode.getOp()) {
-#ifndef GLSLANG_WEB
case EOpTextureGather:
case EOpTextureGatherOffset:
case EOpTextureGatherOffsets:
break;
}
-#endif
case EOpTextureOffset:
case EOpTextureFetchOffset:
if (arg > 0) {
-#ifndef GLSLANG_WEB
bool f16ShadowCompare = (*argp)[1]->getAsTyped()->getBasicType() == EbtFloat16 &&
arg0->getType().getSampler().shadow;
if (f16ShadowCompare)
++arg;
-#endif
if (! (*argp)[arg]->getAsTyped()->getQualifier().isConstant())
error(loc, "argument must be compile-time constant", "texel offset", "");
else if ((*argp)[arg]->getAsConstantUnion()) {
break;
}
-#ifndef GLSLANG_WEB
case EOpTraceNV:
if (!(*argp)[10]->getAsConstantUnion())
error(loc, "argument must be compile-time constant", "payload number", "a");
}
break;
-#endif
default:
break;
}
}
-#ifndef GLSLANG_WEB
-
extern bool PureOperatorBuiltins;
// Deprecated! Use PureOperatorBuiltins == true instead, in which case this
}
}
-#endif
-
//
// Do any extra checking for a user function call.
//
bool errorReturn = false;
switch(binaryNode->getOp()) {
-#ifndef GLSLANG_WEB
case EOpIndexDirect:
case EOpIndexIndirect:
// ... tessellation control shader ...
}
}
break; // left node is checked by base class
-#endif
case EOpVectorSwizzle:
errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft());
if (!errorReturn) {
//
bool TParseContext::lineContinuationCheck(const TSourceLoc& loc, bool endOfComment)
{
-#ifdef GLSLANG_WEB
- return true;
-#endif
-
const char* message = "line continuation";
bool lineContinuationAllowed = (isEsProfile() && version >= 300) ||
// it, in which case the type comes from the argument instead of from the
// constructor function.
switch (op) {
-#ifndef GLSLANG_WEB
case EOpConstructNonuniform:
if (node != nullptr && node->getAsTyped() != nullptr) {
type.shallowCopy(node->getAsTyped()->getType());
type.getQualifier().nonUniform = true;
}
break;
-#endif
default:
type.shallowCopy(function.getType());
break;
case EOpConstructMat4x2:
case EOpConstructMat4x3:
case EOpConstructMat4x4:
-#ifndef GLSLANG_WEB
case EOpConstructDMat2x2:
case EOpConstructDMat2x3:
case EOpConstructDMat2x4:
case EOpConstructF16Mat4x2:
case EOpConstructF16Mat4x3:
case EOpConstructF16Mat4x4:
-#endif
constructingMatrix = true;
break;
default:
if (op == EOpConstructNonuniform)
constType = false;
-#ifndef GLSLANG_WEB
switch (op) {
case EOpConstructFloat16:
case EOpConstructF16Vec2:
default:
break;
}
-#endif
// inherit constness from children
if (constType) {
case EOpConstructUVec2:
case EOpConstructUVec3:
case EOpConstructUVec4:
-#ifndef GLSLANG_WEB
case EOpConstructUint8:
case EOpConstructInt16:
case EOpConstructUint16:
case EOpConstructU64Vec2:
case EOpConstructU64Vec3:
case EOpConstructU64Vec4:
-#endif
// This was the list of valid ones, if they aren't converting from float
// and aren't making an array.
makeSpecConst = ! floatArgument && ! type.isArray();
}
}
-#ifndef GLSLANG_WEB
-
void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
{
if (type.getQualifier().storage == EvqUniform)
}
-#endif // GLSLANG_WEB
-
void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
{
if (parsingBuiltins)
if (!nonuniformOkay && qualifier.isNonUniform())
error(loc, "for non-parameter, can only apply to 'in' or no storage qualifier", "nonuniformEXT", "");
-#ifndef GLSLANG_WEB
if (qualifier.isSpirvByReference())
error(loc, "can only apply to parameter", "spirv_by_reference", "");
if (qualifier.isSpirvLiteral())
error(loc, "can only apply to parameter", "spirv_literal", "");
-#endif
// Storage qualifier isn't ready for memberQualifierCheck, we should skip invariantCheck for it.
if (!isMemberCheck || structNestingLevel > 0)
if (! symbolTable.atBuiltInLevel())
error(loc, "global storage input qualifier cannot be used in a compute shader", "in", "");
break;
-#ifndef GLSLANG_WEB
case EShLangTessControl:
if (qualifier.patch)
error(loc, "can only use on output in tessellation-control shader", "patch", "");
break;
-#endif
default:
break;
}
case EShLangCompute:
error(loc, "global storage output qualifier cannot be used in a compute shader", "out", "");
break;
-#ifndef GLSLANG_WEB
case EShLangTessEvaluation:
if (qualifier.patch)
error(loc, "can only use on input in tessellation-evaluation shader", "patch", "");
break;
-#endif
default:
break;
}
if (dst.precision == EpqNone || (force && src.precision != EpqNone))
dst.precision = src.precision;
-#ifndef GLSLANG_WEB
if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
(src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
(src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent/shadercallcoherent qualifier allowed",
GetPrecisionQualifierString(src.precision), "");
}
-#endif
+
// Layout qualifiers
mergeObjectLayoutQualifiers(dst, src, false);
MERGE_SINGLETON(smooth);
MERGE_SINGLETON(flat);
MERGE_SINGLETON(specConstant);
-#ifndef GLSLANG_WEB
MERGE_SINGLETON(noContraction);
MERGE_SINGLETON(nopersp);
MERGE_SINGLETON(explicitInterp);
MERGE_SINGLETON(readonly);
MERGE_SINGLETON(writeonly);
MERGE_SINGLETON(nonUniform);
-#endif
-#ifndef GLSLANG_WEB
// SPIR-V storage class qualifier (GL_EXT_spirv_intrinsics)
dst.spirvStorageClass = src.spirvStorageClass;
dst.spirvDecorate = src.spirvDecorate;
}
}
-#endif
if (repeated)
error(loc, "replicated qualifiers", "", "");
if (! obeyPrecisionQualifiers() || parsingBuiltins)
return;
-#ifndef GLSLANG_WEB
if (baseType == EbtAtomicUint && qualifier.precision != EpqNone && qualifier.precision != EpqHigh)
error(loc, "atomic counters can only be highp", "atomic_uint", "");
-#endif
if (isCoopMat)
return;
(qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal && qualifier.storage != EvqShared && qualifier.storage != EvqConst))
error(loc, "only outermost dimension of an array of arrays can be a specialization constant", "[]", "");
-#ifndef GLSLANG_WEB
-
// desktop always allows outer-dimension-unsized variable arrays,
if (!isEsProfile())
return;
break;
}
-#endif
-
// last member of ssbo block exception:
if (qualifier.storage == EvqBuffer && lastMember)
return;
if (symbolTable.atGlobalLevel())
trackLinkage(*symbol);
-#ifndef GLSLANG_WEB
if (! symbolTable.atBuiltInLevel()) {
if (isIoResizeArray(type)) {
ioArraySymbolResizeList.push_back(symbol);
} else
fixIoArraySize(loc, symbol->getWritableType());
}
-#endif
return;
}
return;
}
-#ifndef GLSLANG_WEB
if (existingType.isSizedArray()) {
// be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size
if (! (isIoResizeArray(type) && existingType.getOuterArraySize() == type.getOuterArraySize()))
if (isIoResizeArray(type))
checkIoArraysConsistency(loc);
-#endif
}
-#ifndef GLSLANG_WEB
-
// Policy and error check for needing a runtime sized array.
void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermTyped& base)
{
}
}
-#endif // GLSLANG_WEB
-
// Returns true if the first argument to the #line directive is the line number for the next line.
//
// Desktop, pre-version 3.30: "After processing this directive
TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TString& identifier,
const TQualifier& qualifier, const TShaderQualifiers& publicType)
{
-#ifndef GLSLANG_WEB
if (! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel())
return nullptr;
return symbol;
}
-#endif
return nullptr;
}
void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newTypeList, const TString& blockName,
const TString* instanceName, TArraySizes* arraySizes)
{
-#ifndef GLSLANG_WEB
const char* feature = "built-in block redeclaration";
profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature);
profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature);
// Save it in the AST for linker use.
trackLinkage(*block);
-#endif // GLSLANG_WEB
}
void TParseContext::paramCheckFixStorage(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type)
void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& qualifier, TType& type)
{
-#ifndef GLSLANG_WEB
if (qualifier.isMemory()) {
type.getQualifier().volatil = qualifier.volatil;
type.getQualifier().coherent = qualifier.coherent;
type.getQualifier().writeonly = qualifier.writeonly;
type.getQualifier().restrict = qualifier.restrict;
}
-#endif
if (qualifier.isAuxiliary() ||
qualifier.isInterpolation())
}
if (qualifier.isNonUniform())
type.getQualifier().nonUniform = qualifier.nonUniform;
-#ifndef GLSLANG_WEB
if (qualifier.isSpirvByReference())
type.getQualifier().setSpirvByReference();
if (qualifier.isSpirvLiteral()) {
type.getQualifier().setSpirvLiteral();
else
error(loc, "cannot use spirv_literal qualifier", type.getBasicTypeString().c_str(), "");
-#endif
}
paramCheckFixStorage(loc, qualifier.storage, type);
void TParseContext::referenceCheck(const TSourceLoc& loc, const TType& type, const char* op)
{
-#ifndef GLSLANG_WEB
if (containsFieldWithBasicType(type, EbtReference))
error(loc, "can't use with reference types", op, "");
-#endif
}
void TParseContext::storage16BitAssignmentCheck(const TSourceLoc& loc, const TType& type, const char* op)
{
-#ifndef GLSLANG_WEB
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtFloat16))
requireFloat16Arithmetic(loc, op, "can't use with structs containing float16");
if (type.isArray() && type.getBasicType() == EbtUint8)
requireInt8Arithmetic(loc, op, "can't use with arrays containing uint8");
-#endif
}
void TParseContext::specializationCheck(const TSourceLoc& loc, const TType& type, const char* op)
//
void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, TIntermLoop* loop)
{
-#ifndef GLSLANG_WEB
// loop index init must exist and be a declaration, which shows up in the AST as an aggregate of size 1 of the declaration
bool badInit = false;
if (! init || ! init->getAsAggregate() || init->getAsAggregate()->getSequence().size() != 1)
// the body
inductiveLoopBodyCheck(loop->getBody(), loopIndex, symbolTable);
-#endif
}
-#ifndef GLSLANG_WEB
// Do limit checks for built-in arrays.
void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identifier, int size)
{
else if (identifier.compare("gl_CullDistancePerViewNV") == 0)
limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistancePerViewNV array size");
}
-#endif // GLSLANG_WEB
// See if the provided value is less than or equal to the symbol indicated by limit,
// which should be a constant in the symbol table.
error(loc, "must be less than or equal to", feature, "%s (%d)", limit, constArray[0].getIConst());
}
-#ifndef GLSLANG_WEB
-
//
// Do any additional error checking, etc., once we know the parsing is done.
//
}
}
}
-#endif // GLSLANG_WEB
//
// Layout qualifier stuff.
publicType.qualifier.layoutPacking = ElpStd140;
return;
}
-#ifndef GLSLANG_WEB
if (id == TQualifier::getLayoutPackingString(ElpStd430)) {
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430");
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_shader_storage_buffer_object, "std430");
publicType.shaderQualifiers.layoutPrimitiveCulling = true;
return;
}
-#endif
error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), "");
}
error(loc, "needs a literal integer", "set", "");
return;
} else if (id == "binding") {
-#ifndef GLSLANG_WEB
profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, "binding");
profileRequires(loc, EEsProfile, 310, nullptr, "binding");
-#endif
if ((unsigned int)value >= TQualifier::layoutBindingEnd)
error(loc, "binding is too large", id.c_str(), "");
else
error(loc, "needs a literal integer", "constant_id", "");
return;
}
-#ifndef GLSLANG_WEB
if (id == "component") {
requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component");
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "component");
error(loc, "needs a literal integer", "buffer_reference_align", "");
return;
}
-#endif
switch (language) {
-#ifndef GLSLANG_WEB
case EShLangTessControl:
if (id == "vertices") {
if (value == 0)
case EShLangTask:
// Fall through
-#endif
case EShLangCompute:
if (id.compare(0, 11, "local_size_") == 0) {
-#ifndef GLSLANG_WEB
if (language == EShLangMesh || language == EShLangTask) {
requireExtensions(loc, Num_AEP_mesh_shader, AEP_mesh_shader, "gl_WorkGroupSize");
} else {
profileRequires(loc, EEsProfile, 310, nullptr, "gl_WorkGroupSize");
profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize");
}
-#endif
if (nonLiteral)
error(loc, "needs a literal integer", "local_size", "");
if (id.size() == 12 && value == 0) {
if (src.hasPacking())
dst.layoutPacking = src.layoutPacking;
-#ifndef GLSLANG_WEB
if (src.hasStream())
dst.layoutStream = src.layoutStream;
if (src.hasFormat())
dst.layoutXfbBuffer = src.layoutXfbBuffer;
if (src.hasBufferReferenceAlign())
dst.layoutBufferReferenceAlign = src.layoutBufferReferenceAlign;
-#endif
if (src.hasAlign())
dst.layoutAlign = src.layoutAlign;
if (src.hasSpecConstantId())
dst.layoutSpecConstantId = src.layoutSpecConstantId;
-#ifndef GLSLANG_WEB
if (src.hasComponent())
dst.layoutComponent = src.layoutComponent;
if (src.hasIndex())
dst.pervertexEXT = true;
if (src.layoutHitObjectShaderRecordNV)
dst.layoutHitObjectShaderRecordNV = true;
-#endif
}
}
case EvqVaryingIn:
case EvqVaryingOut:
if (!type.getQualifier().isTaskMemory() &&
-#ifndef GLSLANG_WEB
!type.getQualifier().hasSprivDecorate() &&
-#endif
(type.getBasicType() != EbtBlock ||
(!(*type.getStruct())[0].type->getQualifier().hasLocation() &&
(*type.getStruct())[0].type->getQualifier().builtIn == EbvNone)))
// Do layout error checking with respect to a type.
void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
{
-#ifndef GLSLANG_WEB
if (extensionTurnedOn(E_GL_EXT_spirv_intrinsics))
return; // Skip any check if GL_EXT_spirv_intrinsics is turned on
-#endif
const TQualifier& qualifier = type.getQualifier();
case EvqtaskPayloadSharedEXT:
error(loc, "cannot apply to taskPayloadSharedEXT", "location", "");
break;
-#ifndef GLSLANG_WEB
case EvqPayload:
case EvqPayloadIn:
case EvqHitAttr:
case EvqCallableDataIn:
case EvqHitObjectAttrNV:
break;
-#endif
case EvqTileImageEXT:
break;
default:
error(loc, "fragment outputs or tileImageEXTs sharing the same location", "location", "%d must be the same basic type", repeated);
}
-#ifndef GLSLANG_WEB
if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) {
if (type.isUnsizedArray()) {
error(loc, "unsized array", "xfb_offset", "in buffer %d", qualifier.layoutXfbBuffer);
if (! intermediate.setXfbBufferStride(qualifier.layoutXfbBuffer, qualifier.layoutXfbStride))
error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer);
}
-#endif
if (qualifier.hasBinding()) {
// Binding checking, from the spec:
if (type.isSizedArray())
lastBinding += (type.getCumulativeArraySize() - 1);
else {
-#ifndef GLSLANG_WEB
warn(loc, "assuming binding count of one for compile-time checking of binding numbers for unsized array", "[]", "");
-#endif
}
}
}
-#ifndef GLSLANG_WEB
if (spvVersion.vulkan == 0 && lastBinding >= resources.maxCombinedTextureImageUnits)
error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : "");
-#endif
}
if (type.isAtomic() && !spvVersion.vulkanRelaxed) {
if (qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) {
// output block declarations, and output block member declarations."
switch (qualifier.storage) {
-#ifndef GLSLANG_WEB
case EvqVaryingIn:
{
const char* feature = "location qualifier on input";
}
break;
}
-#endif
case EvqUniform:
case EvqBuffer:
{
// For places that can't have shader-level layout qualifiers
void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQualifiers& shaderQualifiers)
{
-#ifndef GLSLANG_WEB
const char* message = "can only apply to a standalone qualifier";
if (shaderQualifiers.geometry != ElgNone)
error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), "");
if (shaderQualifiers.layoutPrimitiveCulling)
error(loc, "can only be applied as standalone", "primitive_culling", "");
-#endif
}
// Correct and/or advance an object's offset layout qualifier.
void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol)
{
const TQualifier& qualifier = symbol.getType().getQualifier();
-#ifndef GLSLANG_WEB
if (symbol.getType().isAtomic()) {
if (qualifier.hasBinding() && (int)qualifier.layoutBinding < resources.maxAtomicCounterBindings) {
atomicUintOffsets[qualifier.layoutBinding] = offset + numOffsets;
}
}
-#endif
}
//
return nullptr;
}
-#ifdef GLSLANG_WEB
- return findFunctionExact(loc, call, builtIn);
-#endif
-
const TFunction* function = nullptr;
// debugPrintfEXT has var args and is in the symbol table as "debugPrintfEXT()",
{
TIntermTyped* result = nullptr;
-#ifndef GLSLANG_WEB
if (function->getBuiltInOp() != EOpNull) {
return nullptr;
}
result = arguments->getAsTyped();
}
}
-#endif
return result;
}
// to establish defaults.
void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType& publicType)
{
-#ifndef GLSLANG_WEB
if (publicType.basicType == EbtAtomicUint && publicType.qualifier.hasBinding()) {
if (publicType.qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) {
error(loc, "atomic_uint binding is too large", "binding", "");
if (publicType.qualifier.hasLayout() && !publicType.qualifier.hasBufferReference())
warn(loc, "useless application of layout qualifier", "layout", "");
-#endif
}
void TParseContext::coopMatTypeParametersCheck(const TSourceLoc& loc, const TPublicType& publicType)
{
if (parsingBuiltins || symbolTable.atBuiltInLevel() || !symbolTable.atGlobalLevel() ||
type.getQualifier().storage != EvqUniform ||
- !(type.containsNonOpaque()
-#ifndef GLSLANG_WEB
- || type.getBasicType() == EbtAtomicUint
-#endif
- )) {
+ !(type.containsNonOpaque()|| type.getBasicType() == EbtAtomicUint)) {
return false;
}
int bufferBinding = TQualifier::layoutBindingEnd;
TVariable* updatedBlock = nullptr;
-#ifndef GLSLANG_WEB
// Convert atomic_uint into members of a buffer block
if (type.isAtomic()) {
type.setBasicType(EbtUint);
growAtomicCounterBlock(bufferBinding, loc, type, identifier, nullptr);
updatedBlock = atomicCounterBuffers[bufferBinding];
}
-#endif
if (!updatedBlock) {
growGlobalUniformBlock(loc, type, identifier, nullptr);
samplerCheck(loc, type, identifier, initializer);
transparentOpaqueCheck(loc, type, identifier);
-#ifndef GLSLANG_WEB
atomicUintCheck(loc, type, identifier);
accStructCheck(loc, type, identifier);
checkAndResizeMeshViewDim(loc, type, /*isBlockMember*/ false);
-#endif
if (type.getQualifier().storage == EvqConst && type.containsReference()) {
error(loc, "variables with reference type can't have qualifier 'const'", "qualifier", "");
}
// Pick up global defaults from the provide global defaults into dst.
void TParseContext::inheritGlobalDefaults(TQualifier& dst) const
{
-#ifndef GLSLANG_WEB
if (dst.storage == EvqVaryingOut) {
if (! dst.hasStream() && language == EShLangGeometry)
dst.layoutStream = globalOutputDefaults.layoutStream;
if (! dst.hasXfbBuffer())
dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
}
-#endif
}
//
// make a new variable
TVariable* variable = new TVariable(&identifier, type);
-#ifndef GLSLANG_WEB
ioArrayCheck(loc, type, identifier);
-#endif
// add variable to symbol table
if (symbolTable.insert(*variable)) {
TType skeletalType;
skeletalType.shallowCopy(variable->getType());
skeletalType.getQualifier().makeTemporary();
-#ifndef GLSLANG_WEB
initializer = convertInitializerList(loc, skeletalType, initializer);
-#endif
if (! initializer) {
// error recovery; don't leave const without constant values
if (qualifier == EvqConst)
intermediate.addBuiltInFunctionCall(node->getLoc(), EOpPackUint2x32, true, node, type);
return newNode;
}
-#ifndef GLSLANG_WEB
-
case EOpConstructDVec2:
case EOpConstructDVec3:
case EOpConstructDVec4:
type);
} else
return nullptr;
-#endif // GLSLANG_WEB
default:
error(loc, "unsupported construction", "", "");
// If a memory qualifier is present in 'to', also make it present in 'from'.
void TParseContext::inheritMemoryQualifiers(const TQualifier& from, TQualifier& to)
{
-#ifndef GLSLANG_WEB
if (from.isReadOnly())
to.readonly = from.readonly;
if (from.isWriteOnly())
to.volatil = from.volatil;
if (from.restrict)
to.restrict = from.restrict;
-#endif
}
//
error(memberLoc, "member storage qualifier cannot contradict block storage qualifier", memberType.getFieldName().c_str(), "");
memberQualifier.storage = currentBlockQualifier.storage;
globalQualifierFixCheck(memberLoc, memberQualifier);
-#ifndef GLSLANG_WEB
inheritMemoryQualifiers(currentBlockQualifier, memberQualifier);
if (currentBlockQualifier.perPrimitiveNV)
memberQualifier.perPrimitiveNV = currentBlockQualifier.perPrimitiveNV;
error(memberLoc, "member cannot have a spirv_storage_class qualifier", memberType.getFieldName().c_str(), "");
if (memberQualifier.hasSprivDecorate() && !memberQualifier.getSpirvDecorate().decorateIds.empty())
error(memberLoc, "member cannot have a spirv_decorate_id qualifier", memberType.getFieldName().c_str(), "");
-#endif
if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary()))
error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), "");
if (memberType.isArray())
for (unsigned int member = 0; member < typeList.size(); ++member) {
TQualifier& memberQualifier = typeList[member].type->getQualifier();
const TSourceLoc& memberLoc = typeList[member].loc;
-#ifndef GLSLANG_WEB
if (memberQualifier.hasStream()) {
if (defaultQualification.layoutStream != memberQualifier.layoutStream)
error(memberLoc, "member cannot contradict block", "stream", "");
if (defaultQualification.layoutXfbBuffer != memberQualifier.layoutXfbBuffer)
error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", "");
}
-#endif
if (memberQualifier.hasPacking())
error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), "");
if (memberQualifier.hasLocation()) {
const char* feature = "location on block member";
switch (currentBlockQualifier.storage) {
-#ifndef GLSLANG_WEB
case EvqVaryingIn:
case EvqVaryingOut:
requireProfile(memberLoc, ECoreProfile | ECompatibilityProfile | EEsProfile, feature);
profileRequires(memberLoc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature);
memberWithLocation = true;
break;
-#endif
default:
error(memberLoc, "can only use in an in/out block", feature, "");
break;
layoutMemberLocationArrayCheck(loc, memberWithLocation, arraySizes);
-#ifndef GLSLANG_WEB
// Ensure that the block has an XfbBuffer assigned. This is needed
// because if the block has a XfbOffset assigned, then it is
// assumed that it has implicitly assigned the current global
if (!currentBlockQualifier.hasXfbBuffer() && currentBlockQualifier.hasXfbOffset())
currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
}
-#endif
// Process the members
fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation);
for (unsigned int member = 0; member < typeList.size(); ++member)
layoutTypeCheck(typeList[member].loc, *typeList[member].type);
-#ifndef GLSLANG_WEB
if (memberWithPerViewQualifier) {
for (unsigned int member = 0; member < typeList.size(); ++member) {
checkAndResizeMeshViewDim(typeList[member].loc, *typeList[member].type, /*isBlockMember*/ true);
}
}
-#endif
// reverse merge, so that currentBlockQualifier now has all layout information
// (can't use defaultQualification directly, it's missing other non-layout-default-class qualifiers)
if (arraySizes != nullptr)
blockType.transferArraySizes(arraySizes);
-#ifndef GLSLANG_WEB
if (arraySizes == nullptr)
ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName);
if (currentBlockQualifier.hasBufferReference()) {
if (!instanceName) {
return;
}
- } else
-#endif
- {
+ } else {
//
// Don't make a user-defined type out of block name; that will cause an error
// if the same block name gets reused in a different interface.
// Check for general layout qualifier errors
layoutObjectCheck(loc, variable);
-#ifndef GLSLANG_WEB
// fix up
if (isIoResizeArray(blockType)) {
ioArraySymbolResizeList.push_back(&variable);
checkIoArraysConsistency(loc, true);
} else
fixIoArraySize(loc, variable.getWritableType());
-#endif
// Save it in the AST for linker use.
trackLinkage(variable);
}
profileRequires(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shared_memory_block, "shared block");
break;
-#ifndef GLSLANG_WEB
case EvqPayload:
profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadNV block");
requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask),
profileRequires(loc, ~EEsProfile, 460, E_GL_NV_shader_invocation_reorder, "hitObjectAttributeNV block");
requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | EShLangMissMask), "hitObjectAttributeNV block");
break;
-#endif
default:
error(loc, "only uniform, buffer, in, or out blocks are supported", blockName->c_str(), "");
break;
void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList)
{
-#ifndef GLSLANG_WEB
// "If a block is qualified with xfb_offset, all its
// members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any
// members of that block not qualified with an xfb_offset will not be assigned transform feedback buffer
// The above gave all block members an offset, so we can take it off the block now,
// which will avoid double counting the offset usage.
qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd;
-#endif
}
// Calculate and save the offset of each block member, using the recursively
//
void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, const TPublicType& publicType)
{
-#ifndef GLSLANG_WEB
if (publicType.shaderQualifiers.vertices != TQualifier::layoutNotSet) {
assert(language == EShLangTessControl || language == EShLangGeometry || language == EShLangMesh);
const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices";
else
error(loc, "can only apply to 'in'", "point_mode", "");
}
-#endif
+
for (int i = 0; i < 3; ++i) {
if (publicType.shaderQualifiers.localSizeNotDefault[i]) {
if (publicType.qualifier.storage == EvqVaryingIn) {
}
if (intermediate.getLocalSize(i) > (unsigned int)max)
error(loc, "too large; see gl_MaxComputeWorkGroupSize", "local_size", "");
- }
-#ifndef GLSLANG_WEB
- else if (language == EShLangMesh) {
+ } else if (language == EShLangMesh) {
switch (i) {
case 0:
max = extensionTurnedOn(E_GL_EXT_mesh_shader) ?
"gl_MaxTaskWorkGroupSizeEXT" : "gl_MaxTaskWorkGroupSizeNV");
error(loc, maxsErrtring.c_str(), "local_size", "");
}
- }
-#endif
- else {
+ } else {
assert(0);
}
}
}
-#ifndef GLSLANG_WEB
if (publicType.shaderQualifiers.earlyFragmentTests) {
if (publicType.qualifier.storage == EvqVaryingIn)
intermediate.setEarlyFragmentTests();
// Exit early as further checks are not valid
return;
}
-#endif
+
const TQualifier& qualifier = publicType.qualifier;
if (qualifier.isAuxiliary() ||
case EvqVaryingIn:
break;
case EvqVaryingOut:
-#ifndef GLSLANG_WEB
if (qualifier.hasStream())
globalOutputDefaults.layoutStream = qualifier.layoutStream;
if (qualifier.hasXfbBuffer())
if (! intermediate.setXfbBufferStride(globalOutputDefaults.layoutXfbBuffer, qualifier.layoutXfbStride))
error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer);
}
-#endif
break;
case EvqShared:
if (qualifier.hasMatrix())
}
virtual ~TParseContextBase() { }
-#if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL)
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...);
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...);
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...);
-#endif
virtual void setLimits(const TBuiltInResource&) = 0;
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
-#ifndef GLSLANG_WEB
void makeEditable(TSymbol*&) override;
void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
-#endif
bool isIoResizeArray(const TType&) const;
void fixIoArraySize(const TSourceLoc&, TType&);
void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
const TTypeList* recordStructCopy(TStructRecord&, const TType*, const TType*);
TLayoutFormat mapLegacyLayoutFormat(TLayoutFormat legacyLayoutFormat, TBasicType imageType);
-#ifndef GLSLANG_WEB
TAttributeType attributeFromName(const TString& name) const;
TAttributes* makeAttributes(const TString& identifier) const;
TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const;
TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value);
TSpirvInstruction* mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1,
TSpirvInstruction* spirvInst2);
-#endif
-
void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember);
protected:
bool isRuntimeLength(const TIntermTyped&) const;
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
-#ifndef GLSLANG_WEB
void finish() override;
-#endif
virtual const char* getGlobalUniformBlockName() const override;
virtual void finalizeGlobalUniformBlockLayout(TVariable&) override;
TQualifier globalOutputDefaults;
TQualifier globalSharedDefaults;
TString currentCaller; // name of last function body entered (not valid when at global scope)
-#ifndef GLSLANG_WEB
int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point
bool anyIndexLimits;
TIdSetType inductiveLoopIds;
// array-sizing declarations
//
TVector<TSymbol*> ioArraySymbolResizeList;
-#endif
};
} // end namespace glslang
// A single global usable by all threads, by all versions, by all languages.
// After a single process-level initialization, this is read only and thread safe
std::unordered_map<const char*, int, str_hash, str_eq>* KeywordMap = nullptr;
-#ifndef GLSLANG_WEB
std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr;
-#endif
}
(*KeywordMap)["uvec3"] = UVEC3;
(*KeywordMap)["uvec4"] = UVEC4;
-#ifndef GLSLANG_WEB
(*KeywordMap)["nonuniformEXT"] = NONUNIFORM;
(*KeywordMap)["demote"] = DEMOTE;
(*KeywordMap)["attribute"] = ATTRIBUTE;
(*KeywordMap)["spirv_storage_class"] = SPIRV_STORAGE_CLASS;
(*KeywordMap)["spirv_by_reference"] = SPIRV_BY_REFERENCE;
(*KeywordMap)["spirv_literal"] = SPIRV_LITERAL;
-#endif
(*KeywordMap)["sampler2D"] = SAMPLER2D;
(*KeywordMap)["samplerCube"] = SAMPLERCUBE;
(*KeywordMap)["sampler"] = SAMPLER;
(*KeywordMap)["samplerShadow"] = SAMPLERSHADOW;
-#ifndef GLSLANG_WEB
(*KeywordMap)["textureCubeArray"] = TEXTURECUBEARRAY;
(*KeywordMap)["itextureCubeArray"] = ITEXTURECUBEARRAY;
(*KeywordMap)["utextureCubeArray"] = UTEXTURECUBEARRAY;
ReservedSet->insert("cast");
ReservedSet->insert("namespace");
ReservedSet->insert("using");
-#endif
}
void TScanContext::deleteKeywordMap()
{
delete KeywordMap;
KeywordMap = nullptr;
-#ifndef GLSLANG_WEB
delete ReservedSet;
ReservedSet = nullptr;
-#endif
}
// Called by yylex to get the next token.
case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT;
case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT;
case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT;
-#ifndef GLSLANG_WEB
case PpAtomConstInt16: parserToken->sType.lex.i = ppToken.ival; return INT16CONSTANT;
case PpAtomConstUint16: parserToken->sType.lex.i = ppToken.ival; return UINT16CONSTANT;
case PpAtomConstInt64: parserToken->sType.lex.i64 = ppToken.i64val; return INT64CONSTANT;
case PpAtomConstUint64: parserToken->sType.lex.i64 = ppToken.i64val; return UINT64CONSTANT;
case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT;
case PpAtomConstFloat16: parserToken->sType.lex.d = ppToken.dval; return FLOAT16CONSTANT;
-#endif
case PpAtomIdentifier:
{
int token = tokenizeIdentifier();
int TScanContext::tokenizeIdentifier()
{
-#ifndef GLSLANG_WEB
if (ReservedSet->find(tokenText) != ReservedSet->end())
return reservedWord();
-#endif
auto it = KeywordMap->find(tokenText);
if (it == KeywordMap->end()) {
return identifierOrReserved(reserved);
}
-#ifndef GLSLANG_WEB
case NOPERSPECTIVE:
if (parseContext.extensionTurnedOn(E_GL_NV_shader_noperspective_interpolation))
return keyword;
case SUBROUTINE:
return es30ReservedFromGLSL(400);
-#endif
+
case SHARED:
if ((parseContext.isEsProfile() && parseContext.version < 300) ||
(!parseContext.isEsProfile() && parseContext.version < 140))
case MAT4X4:
return matNxM();
-#ifndef GLSLANG_WEB
case DMAT2:
case DMAT3:
case DMAT4:
return keyword;
else
return identifierOrType();
-#endif
case UINT:
case UVEC2:
else
return identifierOrType();
-#ifndef GLSLANG_WEB
case ISAMPLER1D:
case ISAMPLER1DARRAY:
case SAMPLER1DARRAYSHADOW:
&& parseContext.extensionTurnedOn(E_GL_NV_shader_invocation_reorder)))
return keyword;
return identifierOrType();
-#endif
default:
parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable,
TSymbolTable** symbolTables)
{
-#ifdef GLSLANG_WEB
- profile = EEsProfile;
- version = 310;
-#endif
-
(*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]);
InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source,
infoSink, *symbolTables[language]);
//
bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables, int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
{
-#ifdef GLSLANG_WEB
- profile = EEsProfile;
- version = 310;
-#endif
-
std::unique_ptr<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));
if (builtInParseables == nullptr)
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source,
infoSink, commonTable, symbolTables);
-#ifndef GLSLANG_WEB
// check for tessellation
if ((profile != EEsProfile && version >= 150) ||
(profile == EEsProfile && version >= 310)) {
(profile == EEsProfile && version >= 320))
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTask, source,
infoSink, commonTable, symbolTables);
-#endif // !GLSLANG_WEB
return true;
}
// Function to Print all builtins
void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable)
{
-#if !defined(GLSLANG_WEB)
infoSink.debug << "BuiltinSymbolTable {\n";
symbolTable.dump(infoSink, true);
infoSink.debug << "}\n";
-#endif
}
// Return true if the shader was correctly specified for version/profile/stage.
break;
}
-#if !defined(GLSLANG_WEB)
// Correct for stage type...
switch (stage) {
case EShLangGeometry:
break;
}
}
-#endif
return correct;
}
: userInput.scanVersion(version, profile, versionNotFirstToken);
bool versionNotFound = version == 0;
if (forceDefaultVersionAndProfile && source == EShSourceGlsl) {
-#if !defined(GLSLANG_WEB)
if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
(version != defaultVersion || profile != defaultProfile)) {
compiler->infoSink.info << "Warning, (version, profile) forced to be ("
<< "), while in source code it is ("
<< version << ", " << ProfileName(profile) << ")\n";
}
-#endif
+
if (versionNotFound) {
versionNotFirstToken = false;
versionNotFirst = false;
bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage,
versionNotFirst, defaultVersion, source, version, profile, spvVersion);
-#ifdef GLSLANG_WEB
- profile = EEsProfile;
- version = 310;
-#endif
-
bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst));
-#if !defined(GLSLANG_WEB)
bool warnVersionNotFirst = false;
if (! versionWillBeError && versionNotFirstToken) {
if (messages & EShMsgRelaxedErrors)
else
versionWillBeError = true;
}
-#endif
intermediate.setSource(source);
intermediate.setVersion(version);
parseContext->setLimits(*resources);
if (! goodVersion)
parseContext->addError();
-#if !defined(GLSLANG_WEB)
if (warnVersionNotFirst) {
TSourceLoc loc;
loc.init();
parseContext->warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", "");
}
-#endif
parseContext->initializeExtensionBehavior();
return success;
}
-#if !defined(GLSLANG_WEB)
-
// Responsible for keeping track of the most recent source string and line in
// the preprocessor and outputting newlines appropriately if the source string
// or line changes.
std::string* outputString;
};
-#endif
-
// DoFullParse is a valid ProcessingConext template argument for fully
// parsing the shader. It populates the "intermediate" with the AST.
struct DoFullParse{
}
};
-#if !defined(GLSLANG_WEB)
// Take a single compilation unit, and run the preprocessor on it.
// Return: True if there were no issues found in preprocessing,
// False if during preprocessing any unknown version, pragmas or
forwardCompatible, messages, intermediate, parser,
false, includer, "", environment);
}
-#endif
//
// do a partial compile on the given strings for a single compilation unit
void TShader::setEnhancedMsgs() { intermediate->setEnhancedMsgs(); }
void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); }
-#ifndef GLSLANG_WEB
-
// Set binding base for given resource type
void TShader::setShiftBinding(TResourceType res, unsigned int base) {
intermediate->setShiftBinding(res, base);
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
void TShader::setResourceSetBinding(const std::vector<std::string>& base) { intermediate->setResourceSetBinding(base); }
void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
-#endif
void TShader::addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing) { intermediate->addBlockStorageOverride(nameStr, backing); }
&environment);
}
-#if !defined(GLSLANG_WEB)
// Fill in a string with the result of preprocessing ShaderStrings
// Returns true if all extensions, pragmas and version strings were valid.
//
forwardCompatible, message, includer, *intermediate, output_string,
&environment);
}
-#endif
const char* TShader::getInfoLog()
{
return infoSink->debug.c_str();
}
-TProgram::TProgram() :
-#if !defined(GLSLANG_WEB)
- reflection(nullptr),
-#endif
- linked(false)
+TProgram::TProgram() : reflection(nullptr), linked(false)
{
pool = new TPoolAllocator;
infoSink = new TInfoSink;
TProgram::~TProgram()
{
delete infoSink;
-#if !defined(GLSLANG_WEB)
delete reflection;
-#endif
for (int s = 0; s < EShLangCount; ++s)
if (newedIntermediate[s])
if (stages[stage].size() == 0)
return true;
-#if !defined(GLSLANG_WEB)
int numEsShaders = 0, numNonEsShaders = 0;
for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) {
if ((*it)->intermediate->getProfile() == EEsProfile) {
for (it = stages[stage].begin(); it != stages[stage].end(); ++it)
intermediate[stage]->merge(*infoSink, *(*it)->intermediate);
}
-#else
- intermediate[stage] = stages[stage].front()->intermediate;
-#endif
intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0);
if (messages & EShMsgAST)
return infoSink->debug.c_str();
}
-#if !defined(GLSLANG_WEB)
-
//
// Reflection implementation.
//
return ioMapper->doMap(pResolver, *infoSink);
}
-#endif // !GLSLANG_WEB
-
} // end namespace glslang
// POSSIBILITY OF SUCH DAMAGE.
//
-#ifndef GLSLANG_WEB
-
//
// GL_EXT_spirv_intrinsics
//
}
} // end namespace glslang
-
-#endif // GLSLANG_WEB
case EbtInt: mangledName += 'i'; break;
case EbtUint: mangledName += 'u'; break;
case EbtBool: mangledName += 'b'; break;
-#ifndef GLSLANG_WEB
case EbtDouble: mangledName += 'd'; break;
case EbtFloat16: mangledName += "f16"; break;
case EbtInt8: mangledName += "i8"; break;
case EbtRayQuery: mangledName += "rq"; break;
case EbtSpirvType: mangledName += "spv-t"; break;
case EbtHitObjectNV: mangledName += "ho"; break;
-#endif
case EbtSampler:
switch (sampler.type) {
-#ifndef GLSLANG_WEB
case EbtFloat16: mangledName += "f16"; break;
-#endif
case EbtInt: mangledName += "i"; break;
case EbtUint: mangledName += "u"; break;
case EbtInt64: mangledName += "i64"; break;
case Esd2D: mangledName += "2"; break;
case Esd3D: mangledName += "3"; break;
case EsdCube: mangledName += "C"; break;
-#ifndef GLSLANG_WEB
case Esd1D: mangledName += "1"; break;
case EsdRect: mangledName += "R2"; break;
case EsdBuffer: mangledName += "B"; break;
case EsdSubpass: mangledName += "P"; break;
-#endif
default: break; // some compilers want this
}
}
}
-#if !defined(GLSLANG_WEB)
-
//
// Dump functions.
//
}
}
-#endif
-
//
// Functions have buried pointers to delete.
//
implicitThis = copyOf.implicitThis;
illegalImplicitThis = copyOf.illegalImplicitThis;
defaultParamCount = copyOf.defaultParamCount;
-#ifndef GLSLANG_WEB
spirvInst = copyOf.spirvInst;
-#endif
}
TFunction* TFunction::clone() const
virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); }
virtual const char** getExtensions() const { return extensions->data(); }
-#if !defined(GLSLANG_WEB)
virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0;
void dumpExtensions(TInfoSink& infoSink) const;
-#endif
virtual bool isReadOnly() const { return ! writable; }
virtual void makeReadOnly() { writable = false; }
}
virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); }
-#if !defined(GLSLANG_WEB)
virtual void dump(TInfoSink& infoSink, bool complete = false) const;
-#endif
protected:
explicit TVariable(const TVariable&);
virtual const TParameter& operator[](int i) const { return parameters[i]; }
const TQualifier& getQualifier() const { return returnType.getQualifier(); }
-#ifndef GLSLANG_WEB
virtual void setSpirvInstruction(const TSpirvInstruction& inst)
{
relateToOperator(EOpSpirvInst);
spirvInst = inst;
}
virtual const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
-#endif
-#if !defined(GLSLANG_WEB)
virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
-#endif
protected:
explicit TFunction(const TFunction&);
// but is not allowed to use them, or see hidden symbols instead.
int defaultParamCount;
-#ifndef GLSLANG_WEB
TSpirvInstruction spirvInst; // SPIR-V instruction qualifiers
-#endif
};
//
virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); }
virtual int getAnonId() const { return anonId; }
-#if !defined(GLSLANG_WEB)
virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
-#endif
protected:
explicit TAnonMember(const TAnonMember&);
void relateToOperator(const char* name, TOperator op);
void setFunctionExtensions(const char* name, int num, const char* const extensions[]);
-#if !defined(GLSLANG_WEB)
void dump(TInfoSink& infoSink, bool complete = false) const;
-#endif
TSymbolTableLevel* clone() const;
void readOnly();
}
long long getMaxSymbolId() { return uniqueId; }
-#if !defined(GLSLANG_WEB)
void dump(TInfoSink& infoSink, bool complete = false) const;
-#endif
void copyTable(const TSymbolTable& copyOf);
void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); }
namespace glslang {
-#ifndef GLSLANG_WEB
-
//
// Initialize all extensions, almost always to 'disable', as once their features
// are incorporated into a core version, their features are supported through allowing that
spvUnsupportedExt.push_back(E_GL_ARB_bindless_texture);
}
-#endif // GLSLANG_WEB
-
// Get code that is not part of a shared symbol table, is specific to this shader,
// or needed by the preprocessor (which does not use a shared symbol table).
void TParseVersions::getPreamble(std::string& preamble)
preamble =
"#define GL_ES 1\n"
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
-#ifdef GLSLANG_WEB
- ;
-#else
"#define GL_OES_texture_3D 1\n"
"#define GL_OES_standard_derivatives 1\n"
"#define GL_EXT_frag_depth 1\n"
if (version >= 130) {
preamble +="#define GL_FRAGMENT_PRECISION_HIGH 1\n";
}
-
-#endif // GLSLANG_WEB
}
-#ifndef GLSLANG_WEB
if ((!isEsProfile() && version >= 140) ||
(isEsProfile() && version >= 310)) {
preamble +=
preamble +=
"#define GL_EXT_terminate_invocation 1\n"
;
-#endif
// #define VULKAN XXXX
const int numberBufSize = 12;
preamble += "\n";
}
-#ifndef GLSLANG_WEB
// #define GL_SPIRV XXXX
if (spvVersion.openGl > 0) {
preamble += "#define GL_SPIRV ";
preamble += numberBuf;
preamble += "\n";
}
-#endif
-#ifndef GLSLANG_WEB
// GL_EXT_spirv_intrinsics
if (!isEsProfile()) {
switch (language) {
default: break;
}
}
-#endif
}
//
case EShLangVertex: return "vertex";
case EShLangFragment: return "fragment";
case EShLangCompute: return "compute";
-#ifndef GLSLANG_WEB
case EShLangTessControl: return "tessellation control";
case EShLangTessEvaluation: return "tessellation evaluation";
case EShLangGeometry: return "geometry";
case EShLangCallable: return "callable";
case EShLangMesh: return "mesh";
case EShLangTask: return "task";
-#endif
default: return "unknown stage";
}
}
requireStage(loc, static_cast<EShLanguageMask>(1 << stage), featureDesc);
}
-#ifndef GLSLANG_WEB
//
// When to use requireProfile():
//
{
if (profile & profileMask) {
bool okay = minVersion > 0 && version >= minVersion;
-#ifndef GLSLANG_WEB
for (int i = 0; i < numExtensions; ++i) {
switch (getExtensionBehavior(extensions[i])) {
case EBhWarn:
default: break; // some compilers want this
}
}
-#endif
if (! okay)
error(loc, "not supported for this version or the enabled extensions", featureDesc, "");
}
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
}
}
-#endif // GLSLANG_WEB
+
// Call for any operation removed because SPIR-V is in use.
void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
{
// Call for any operation that requires Vulkan.
void TParseVersions::requireVulkan(const TSourceLoc& loc, const char* op)
{
-#ifndef GLSLANG_WEB
if (spvVersion.vulkan == 0)
error(loc, "only allowed when using GLSL for Vulkan", op, "");
-#endif
}
// Call for any operation that requires SPIR-V.
void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op)
{
-#ifndef GLSLANG_WEB
if (spvVersion.spv == 0)
error(loc, "only allowed when generating SPIR-V", op, "");
-#endif
}
void TParseVersions::requireSpv(const TSourceLoc& loc, const char *op, unsigned int version)
{
-#ifndef GLSLANG_WEB
if (spvVersion.spv < version)
error(loc, "not supported for current targeted SPIR-V version", op, "");
-#endif
}
} // end namespace glslang
// POSSIBILITY OF SUCH DAMAGE.
//
-#ifndef GLSLANG_WEB
-
#include "attribute.h"
#include "../Include/intermediate.h"
#include "ParseHelper.h"
}
} // end namespace glslang
-
-#endif // GLSLANG_WEB
// The .y bison file is not a source file, it is a derivative of the .m4 file.
// The m4 file needs to be processed by m4 to generate the .y bison file.
//
-// Code sandwiched between a pair:
-//
-// GLSLANG_WEB_EXCLUDE_ON
-// ...
-// ...
-// ...
-// GLSLANG_WEB_EXCLUDE_OFF
-//
-// Will be excluded from the grammar when m4 is executed as:
-//
-// m4 -P -DGLSLANG_WEB
-//
-// It will be included when m4 is executed as:
-//
// m4 -P
//
-m4_define(`GLSLANG_WEB_EXCLUDE_ON', `m4_ifdef(`GLSLANG_WEB', `m4_divert(`-1')')')
-m4_define(`GLSLANG_WEB_EXCLUDE_OFF', `m4_ifdef(`GLSLANG_WEB', `m4_divert')')
-
/**
* This is bison grammar and productions for parsing all versions of the
* GLSL shading languages.
%token <lex> ITEXTURE2D ITEXTURE3D ITEXTURECUBE ITEXTURE2DARRAY
%token <lex> UTEXTURE2D UTEXTURE3D UTEXTURECUBE UTEXTURE2DARRAY
-GLSLANG_WEB_EXCLUDE_ON
-
%token <lex> ATTRIBUTE VARYING
%token <lex> FLOAT16_T FLOAT32_T DOUBLE FLOAT64_T
%token <lex> INT64_T UINT64_T INT32_T UINT32_T INT16_T UINT16_T INT8_T UINT8_T
%token <lex> SPIRV_TYPE SPIRV_STORAGE_CLASS SPIRV_BY_REFERENCE SPIRV_LITERAL
%token <lex> ATTACHMENTEXT IATTACHMENTEXT UATTACHMENTEXT
-GLSLANG_WEB_EXCLUDE_OFF
-
%token <lex> LEFT_OP RIGHT_OP
%token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
%token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
%token <lex> UNIFORM SHARED BUFFER TILEIMAGEEXT
%token <lex> FLAT SMOOTH LAYOUT
-GLSLANG_WEB_EXCLUDE_ON
%token <lex> DOUBLECONSTANT INT16CONSTANT UINT16CONSTANT FLOAT16CONSTANT INT32CONSTANT UINT32CONSTANT
%token <lex> INT64CONSTANT UINT64CONSTANT
%token <lex> SUBROUTINE DEMOTE
%token <lex> SUBGROUPCOHERENT NONPRIVATE SHADERCALLCOHERENT
%token <lex> NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXEXT PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV PERPRIMITIVEEXT TASKPAYLOADWORKGROUPEXT
%token <lex> PRECISE
-GLSLANG_WEB_EXCLUDE_OFF
%type <interm> assignment_operator unary_operator
%type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
%type <interm.identifierList> identifier_list
-GLSLANG_WEB_EXCLUDE_ON
%type <interm.type> precise_qualifier non_uniform_qualifier
%type <interm.typeList> type_name_list
%type <interm.attributes> attribute attribute_list single_attribute
%type <interm.spirvTypeParams> spirv_type_parameter_list spirv_type_parameter
%type <interm.spirvInst> spirv_instruction_qualifier
%type <interm.spirvInst> spirv_instruction_qualifier_list spirv_instruction_qualifier_id
-GLSLANG_WEB_EXCLUDE_OFF
%start translation_unit
%%
| BOOLCONSTANT {
$$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
}
-GLSLANG_WEB_EXCLUDE_ON
| STRING_LITERAL {
$$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true);
}
parseContext.float16Check($1.loc, "half float literal");
$$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat16, $1.loc, true);
}
-GLSLANG_WEB_EXCLUDE_OFF
;
postfix_expression
$$.function = new TFunction(empty, TType(EbtVoid), EOpNull);
}
}
-GLSLANG_WEB_EXCLUDE_ON
| non_uniform_qualifier {
// Constructor
$$.intermNode = 0;
$$.function = parseContext.handleConstructorCall($1.loc, $1);
}
-GLSLANG_WEB_EXCLUDE_OFF
;
unary_expression
$$ = 0;
// TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
}
-GLSLANG_WEB_EXCLUDE_ON
| spirv_instruction_qualifier function_prototype SEMICOLON {
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V instruction qualifier");
$2.function->setSpirvInstruction(*$1); // Attach SPIR-V intruction qualifier
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V execution mode qualifier");
$$ = 0;
}
-GLSLANG_WEB_EXCLUDE_OFF
| init_declarator_list SEMICOLON {
if ($1.intermNode && $1.intermNode->getAsAggregate())
$1.intermNode->getAsAggregate()->setOperator(EOpSequence);
: fully_specified_type {
$$.type = $1;
$$.intermNode = 0;
-GLSLANG_WEB_EXCLUDE_ON
parseContext.declareTypeDefaults($$.loc, $$.type);
-GLSLANG_WEB_EXCLUDE_OFF
}
| fully_specified_type IDENTIFIER {
$$.type = $1;
$$.init($1.loc);
$$.qualifier.flat = true;
}
-GLSLANG_WEB_EXCLUDE_ON
| NOPERSPECTIVE {
parseContext.globalCheck($1.loc, "noperspective");
parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_NV_shader_noperspective_interpolation, "noperspective");
$$.init($1.loc);
$$.qualifier.perTaskNV = true;
}
-GLSLANG_WEB_EXCLUDE_OFF
;
layout_qualifier
}
;
-GLSLANG_WEB_EXCLUDE_ON
precise_qualifier
: PRECISE {
parseContext.profileRequires($$.loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader5, "precise");
$$.qualifier.noContraction = true;
}
;
-GLSLANG_WEB_EXCLUDE_OFF
type_qualifier
: single_type_qualifier {
// allow inheritance of storage qualifier from block declaration
$$ = $1;
}
-GLSLANG_WEB_EXCLUDE_ON
| precise_qualifier {
// allow inheritance of storage qualifier from block declaration
$$ = $1;
$$.init($1.loc);
$$.qualifier.setSpirvLiteral();
}
-GLSLANG_WEB_EXCLUDE_OFF
;
storage_qualifier
$$.init($1.loc);
$$.qualifier.storage = EvqBuffer;
}
-GLSLANG_WEB_EXCLUDE_ON
| ATTRIBUTE {
parseContext.requireStage($1.loc, EShLangVertex, "attribute");
parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "attribute");
$$.init($1.loc);
$$.qualifier.storage = EvqtaskPayloadSharedEXT;
}
-GLSLANG_WEB_EXCLUDE_OFF
;
-GLSLANG_WEB_EXCLUDE_ON
non_uniform_qualifier
: NONUNIFORM {
$$.init($1.loc);
// 2) save all of the identifiers for future comparison with the declared function
}
;
-GLSLANG_WEB_EXCLUDE_OFF
type_specifier
: type_specifier_nonarray type_parameter_specifier_opt {
$$.basicType = EbtFloat;
$$.setMatrix(4, 4);
}
-GLSLANG_WEB_EXCLUDE_ON
| DOUBLE {
parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double");
if (! parseContext.symbolTable.atBuiltInLevel())
$$.basicType = EbtSampler;
$$.sampler.set(EbtFloat, Esd1D);
}
-GLSLANG_WEB_EXCLUDE_OFF
| SAMPLER2D {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtSampler;
$$.basicType = EbtSampler;
$$.sampler.set(EbtFloat, Esd2D, true, true);
}
-GLSLANG_WEB_EXCLUDE_ON
| SAMPLER1DSHADOW {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtSampler;
$$.basicType = EbtSampler;
$$.sampler.set(EbtInt, Esd1D);
}
-GLSLANG_WEB_EXCLUDE_OFF
| ISAMPLER2D {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtSampler;
$$.basicType = EbtSampler;
$$.sampler.set(EbtUint, EsdCube);
}
-GLSLANG_WEB_EXCLUDE_ON
| ISAMPLER1DARRAY {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtSampler;
$$.basicType = EbtSampler;
$$.sampler.setTexture(EbtUint, EsdCube, true);
}
-GLSLANG_WEB_EXCLUDE_OFF
| USAMPLER2DARRAY {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtSampler;
$$.basicType = EbtSampler;
$$.sampler.setPureSampler(true);
}
-GLSLANG_WEB_EXCLUDE_ON
| SAMPLER2DRECT {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtSampler;
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtHitObjectNV;
}
-GLSLANG_WEB_EXCLUDE_OFF
| struct_specifier {
$$ = $1;
$$.qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
: assignment_expression {
$$ = $1;
}
-GLSLANG_WEB_EXCLUDE_ON
| LEFT_BRACE initializer_list RIGHT_BRACE {
const char* initFeature = "{ } style initializers";
parseContext.requireProfile($1.loc, ~EEsProfile, initFeature);
parseContext.profileRequires($1.loc, ~EEsProfile, 0, E_GL_EXT_null_initializer, initFeature);
$$ = parseContext.intermediate.makeAggregate($1.loc);
}
-GLSLANG_WEB_EXCLUDE_OFF
;
-GLSLANG_WEB_EXCLUDE_ON
initializer_list
: initializer {
$$ = parseContext.intermediate.growAggregate(0, $1, $1->getLoc());
$$ = parseContext.intermediate.growAggregate($1, $3);
}
;
-GLSLANG_WEB_EXCLUDE_OFF
declaration_statement
: declaration { $$ = $1; }
| case_label { $$ = $1; }
| iteration_statement { $$ = $1; }
| jump_statement { $$ = $1; }
-GLSLANG_WEB_EXCLUDE_ON
| demote_statement { $$ = $1; }
-GLSLANG_WEB_EXCLUDE_OFF
;
-GLSLANG_WEB_EXCLUDE_ON
demote_statement
: DEMOTE SEMICOLON {
parseContext.requireStage($1.loc, EShLangFragment, "demote");
$$ = parseContext.intermediate.addBranch(EOpDemote, $1.loc);
}
;
-GLSLANG_WEB_EXCLUDE_OFF
compound_statement
: LEFT_BRACE RIGHT_BRACE { $$ = 0; }
: selection_statement_nonattributed {
$$ = $1;
}
-GLSLANG_WEB_EXCLUDE_ON
| attribute selection_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleSelectionAttributes(*$1, $2);
$$ = $2;
}
-GLSLANG_WEB_EXCLUDE_OFF
selection_statement_nonattributed
: IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
: switch_statement_nonattributed {
$$ = $1;
}
-GLSLANG_WEB_EXCLUDE_ON
| attribute switch_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleSwitchAttributes(*$1, $2);
$$ = $2;
}
-GLSLANG_WEB_EXCLUDE_OFF
switch_statement_nonattributed
: SWITCH LEFT_PAREN expression RIGHT_PAREN {
: iteration_statement_nonattributed {
$$ = $1;
}
-GLSLANG_WEB_EXCLUDE_ON
| attribute iteration_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleLoopAttributes(*$1, $2);
$$ = $2;
}
-GLSLANG_WEB_EXCLUDE_OFF
iteration_statement_nonattributed
: WHILE LEFT_PAREN {
parseContext.requireStage($1.loc, EShLangFragment, "terminateInvocation");
$$ = parseContext.intermediate.addBranch(EOpTerminateInvocation, $1.loc);
}
-GLSLANG_WEB_EXCLUDE_ON
| TERMINATE_RAY SEMICOLON {
parseContext.requireStage($1.loc, EShLangAnyHit, "terminateRayEXT");
$$ = parseContext.intermediate.addBranch(EOpTerminateRayKHR, $1.loc);
parseContext.requireStage($1.loc, EShLangAnyHit, "ignoreIntersectionEXT");
$$ = parseContext.intermediate.addBranch(EOpIgnoreIntersectionKHR, $1.loc);
}
-GLSLANG_WEB_EXCLUDE_OFF
;
// Grammar Note: No 'goto'. Gotos are not supported.
| declaration {
$$ = $1;
}
-GLSLANG_WEB_EXCLUDE_ON
| SEMICOLON {
parseContext.requireProfile($1.loc, ~EEsProfile, "extraneous semicolon");
parseContext.profileRequires($1.loc, ~EEsProfile, 460, nullptr, "extraneous semicolon");
$$ = nullptr;
}
-GLSLANG_WEB_EXCLUDE_OFF
;
function_definition
}
;
-GLSLANG_WEB_EXCLUDE_ON
attribute
: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET {
$$ = $3;
| IDENTIFIER LEFT_PAREN constant_expression RIGHT_PAREN {
$$ = parseContext.makeAttributes(*$1.string, $3);
}
-GLSLANG_WEB_EXCLUDE_OFF
-GLSLANG_WEB_EXCLUDE_ON
spirv_requirements_list
: spirv_requirements_parameter {
$$ = $1;
| IDENTIFIER EQUAL INTCONSTANT {
$$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, $3.i);
}
-GLSLANG_WEB_EXCLUDE_OFF
%%
// The .y bison file is not a source file, it is a derivative of the .m4 file.
// The m4 file needs to be processed by m4 to generate the .y bison file.
//
-// Code sandwiched between a pair:
-//
-// GLSLANG_WEB_EXCLUDE_ON
-// ...
-// ...
-// ...
-// GLSLANG_WEB_EXCLUDE_OFF
-//
-// Will be excluded from the grammar when m4 is executed as:
-//
-// m4 -P -DGLSLANG_WEB
-//
-// It will be included when m4 is executed as:
-//
// m4 -P
//
-
-
-
/**
* This is bison grammar and productions for parsing all versions of the
* GLSL shading languages.
%token <lex> ITEXTURE2D ITEXTURE3D ITEXTURECUBE ITEXTURE2DARRAY
%token <lex> UTEXTURE2D UTEXTURE3D UTEXTURECUBE UTEXTURE2DARRAY
-
-
%token <lex> ATTRIBUTE VARYING
%token <lex> FLOAT16_T FLOAT32_T DOUBLE FLOAT64_T
%token <lex> INT64_T UINT64_T INT32_T UINT32_T INT16_T UINT16_T INT8_T UINT8_T
%token <lex> SPIRV_TYPE SPIRV_STORAGE_CLASS SPIRV_BY_REFERENCE SPIRV_LITERAL
%token <lex> ATTACHMENTEXT IATTACHMENTEXT UATTACHMENTEXT
-
-
%token <lex> LEFT_OP RIGHT_OP
%token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
%token <lex> AND_OP OR_OP XOR_OP MUL_ASSIGN DIV_ASSIGN ADD_ASSIGN
%token <lex> UNIFORM SHARED BUFFER TILEIMAGEEXT
%token <lex> FLAT SMOOTH LAYOUT
-
%token <lex> DOUBLECONSTANT INT16CONSTANT UINT16CONSTANT FLOAT16CONSTANT INT32CONSTANT UINT32CONSTANT
%token <lex> INT64CONSTANT UINT64CONSTANT
%token <lex> SUBROUTINE DEMOTE
%token <lex> NOPERSPECTIVE EXPLICITINTERPAMD PERVERTEXEXT PERVERTEXNV PERPRIMITIVENV PERVIEWNV PERTASKNV PERPRIMITIVEEXT TASKPAYLOADWORKGROUPEXT
%token <lex> PRECISE
-
%type <interm> assignment_operator unary_operator
%type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
%type <interm.intermTypedNode> expression integer_expression assignment_expression
%type <interm.identifierList> identifier_list
-
%type <interm.type> precise_qualifier non_uniform_qualifier
%type <interm.typeList> type_name_list
%type <interm.attributes> attribute attribute_list single_attribute
%type <interm.spirvInst> spirv_instruction_qualifier
%type <interm.spirvInst> spirv_instruction_qualifier_list spirv_instruction_qualifier_id
-
%start translation_unit
%%
| BOOLCONSTANT {
$$ = parseContext.intermediate.addConstantUnion($1.b, $1.loc, true);
}
-
| STRING_LITERAL {
$$ = parseContext.intermediate.addConstantUnion($1.string, $1.loc, true);
}
parseContext.float16Check($1.loc, "half float literal");
$$ = parseContext.intermediate.addConstantUnion($1.d, EbtFloat16, $1.loc, true);
}
-
;
postfix_expression
$$.function = new TFunction(empty, TType(EbtVoid), EOpNull);
}
}
-
| non_uniform_qualifier {
// Constructor
$$.intermNode = 0;
$$.function = parseContext.handleConstructorCall($1.loc, $1);
}
-
;
unary_expression
$$ = 0;
// TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature
}
-
| spirv_instruction_qualifier function_prototype SEMICOLON {
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V instruction qualifier");
$2.function->setSpirvInstruction(*$1); // Attach SPIR-V intruction qualifier
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V execution mode qualifier");
$$ = 0;
}
-
| init_declarator_list SEMICOLON {
if ($1.intermNode && $1.intermNode->getAsAggregate())
$1.intermNode->getAsAggregate()->setOperator(EOpSequence);
: fully_specified_type {
$$.type = $1;
$$.intermNode = 0;
-
parseContext.declareTypeDefaults($$.loc, $$.type);
-
}
| fully_specified_type IDENTIFIER {
$$.type = $1;
$$.init($1.loc);
$$.qualifier.flat = true;
}
-
| NOPERSPECTIVE {
parseContext.globalCheck($1.loc, "noperspective");
parseContext.profileRequires($1.loc, EEsProfile, 0, E_GL_NV_shader_noperspective_interpolation, "noperspective");
$$.init($1.loc);
$$.qualifier.perTaskNV = true;
}
-
;
layout_qualifier
}
;
-
precise_qualifier
: PRECISE {
parseContext.profileRequires($$.loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader5, "precise");
}
;
-
type_qualifier
: single_type_qualifier {
$$ = $1;
// allow inheritance of storage qualifier from block declaration
$$ = $1;
}
-
| precise_qualifier {
// allow inheritance of storage qualifier from block declaration
$$ = $1;
$$.init($1.loc);
$$.qualifier.setSpirvLiteral();
}
-
;
storage_qualifier
$$.init($1.loc);
$$.qualifier.storage = EvqBuffer;
}
-
| ATTRIBUTE {
parseContext.requireStage($1.loc, EShLangVertex, "attribute");
parseContext.checkDeprecated($1.loc, ECoreProfile, 130, "attribute");
$$.init($1.loc);
$$.qualifier.storage = EvqtaskPayloadSharedEXT;
}
-
;
-
non_uniform_qualifier
: NONUNIFORM {
$$.init($1.loc);
}
;
-
type_specifier
: type_specifier_nonarray type_parameter_specifier_opt {
$$ = $1;
$$.basicType = EbtFloat;
$$.setMatrix(4, 4);
}
-
| DOUBLE {
parseContext.requireProfile($1.loc, ECoreProfile | ECompatibilityProfile, "double");
if (! parseContext.symbolTable.atBuiltInLevel())
$$.basicType = EbtSampler;
$$.sampler.set(EbtFloat, Esd1D);
}
-
| SAMPLER2D {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtSampler;
$$.basicType = EbtSampler;
$$.sampler.set(EbtFloat, Esd2D, true, true);
}
-
| SAMPLER1DSHADOW {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtSampler;
$$.basicType = EbtSampler;
$$.sampler.set(EbtInt, Esd1D);
}
-
| ISAMPLER2D {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtSampler;
$$.basicType = EbtSampler;
$$.sampler.set(EbtUint, EsdCube);
}
-
| ISAMPLER1DARRAY {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtSampler;
$$.basicType = EbtSampler;
$$.sampler.setTexture(EbtUint, EsdCube, true);
}
-
| USAMPLER2DARRAY {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtSampler;
$$.basicType = EbtSampler;
$$.sampler.setPureSampler(true);
}
-
| SAMPLER2DRECT {
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtSampler;
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtHitObjectNV;
}
-
| struct_specifier {
$$ = $1;
$$.qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
: assignment_expression {
$$ = $1;
}
-
| LEFT_BRACE initializer_list RIGHT_BRACE {
const char* initFeature = "{ } style initializers";
parseContext.requireProfile($1.loc, ~EEsProfile, initFeature);
parseContext.profileRequires($1.loc, ~EEsProfile, 0, E_GL_EXT_null_initializer, initFeature);
$$ = parseContext.intermediate.makeAggregate($1.loc);
}
-
;
-
initializer_list
: initializer {
$$ = parseContext.intermediate.growAggregate(0, $1, $1->getLoc());
}
;
-
declaration_statement
: declaration { $$ = $1; }
;
| case_label { $$ = $1; }
| iteration_statement { $$ = $1; }
| jump_statement { $$ = $1; }
-
| demote_statement { $$ = $1; }
-
;
-
demote_statement
: DEMOTE SEMICOLON {
parseContext.requireStage($1.loc, EShLangFragment, "demote");
}
;
-
compound_statement
: LEFT_BRACE RIGHT_BRACE { $$ = 0; }
| LEFT_BRACE {
: selection_statement_nonattributed {
$$ = $1;
}
-
| attribute selection_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleSelectionAttributes(*$1, $2);
$$ = $2;
}
-
selection_statement_nonattributed
: IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
parseContext.boolCheck($1.loc, $3);
: switch_statement_nonattributed {
$$ = $1;
}
-
| attribute switch_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleSwitchAttributes(*$1, $2);
$$ = $2;
}
-
switch_statement_nonattributed
: SWITCH LEFT_PAREN expression RIGHT_PAREN {
// start new switch sequence on the switch stack
: iteration_statement_nonattributed {
$$ = $1;
}
-
| attribute iteration_statement_nonattributed {
parseContext.requireExtensions($2->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute");
parseContext.handleLoopAttributes(*$1, $2);
$$ = $2;
}
-
iteration_statement_nonattributed
: WHILE LEFT_PAREN {
if (! parseContext.limits.whileLoops)
parseContext.requireStage($1.loc, EShLangFragment, "terminateInvocation");
$$ = parseContext.intermediate.addBranch(EOpTerminateInvocation, $1.loc);
}
-
| TERMINATE_RAY SEMICOLON {
parseContext.requireStage($1.loc, EShLangAnyHit, "terminateRayEXT");
$$ = parseContext.intermediate.addBranch(EOpTerminateRayKHR, $1.loc);
parseContext.requireStage($1.loc, EShLangAnyHit, "ignoreIntersectionEXT");
$$ = parseContext.intermediate.addBranch(EOpIgnoreIntersectionKHR, $1.loc);
}
-
;
// Grammar Note: No 'goto'. Gotos are not supported.
| declaration {
$$ = $1;
}
-
| SEMICOLON {
parseContext.requireProfile($1.loc, ~EEsProfile, "extraneous semicolon");
parseContext.profileRequires($1.loc, ~EEsProfile, 460, nullptr, "extraneous semicolon");
$$ = nullptr;
}
-
;
function_definition
}
;
-
attribute
: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET {
$$ = $3;
$$ = parseContext.makeAttributes(*$1.string, $3);
}
-
-
spirv_requirements_list
: spirv_requirements_parameter {
$$ = $1;
$$ = parseContext.makeSpirvInstruction($2.loc, *$1.string, $3.i);
}
-
%%
// POSSIBILITY OF SUCH DAMAGE.
//
-#if !defined(GLSLANG_WEB)
-
#include "localintermediate.h"
#include "../Include/InfoSink.h"
case EOpDeclare: out.debug << "Declare"; break;
-#ifndef GLSLANG_WEB
case EOpSpirvInst: out.debug << "spirv_instruction"; break;
-#endif
default: out.debug.message(EPrefixError, "Bad unary op");
}
case EOpHitObjectGetShaderRecordBufferHandleNV: out.debug << "HitObjectReadShaderRecordBufferHandleNV"; break;
case EOpReorderThreadNV: out.debug << "ReorderThreadNV"; break;
-#ifndef GLSLANG_WEB
case EOpSpirvInst: out.debug << "spirv_instruction"; break;
-#endif
case EOpStencilAttachmentReadEXT: out.debug << "stencilAttachmentReadEXT"; break;
case EOpDepthAttachmentReadEXT: out.debug << "depthAttachmentReadEXT"; break;
}
} // end namespace glslang
-
-#endif // !GLSLANG_WEB
// POSSIBILITY OF SUCH DAMAGE.
//
-#if !defined(GLSLANG_WEB)
-
#include "../Include/Common.h"
#include "../Include/InfoSink.h"
#include "../Include/Types.h"
}
} // end namespace glslang
-
-#endif // !GLSLANG_WEB
// POSSIBILITY OF SUCH DAMAGE.
//
-#if !defined(GLSLANG_WEB)
-
#ifndef _IOMAPPER_INCLUDED
#define _IOMAPPER_INCLUDED
} // end namespace glslang
#endif // _IOMAPPER_INCLUDED
-
-#endif // !GLSLANG_WEB
//
void TParseContext::constantIndexExpressionCheck(TIntermNode* index)
{
-#ifndef GLSLANG_WEB
TIndexTraverser it(inductiveLoopIds);
index->traverse(&it);
if (it.bad)
error(it.badLoc, "Non-constant-index-expression", "limitations", "");
-#endif
}
} // end namespace glslang
//
void TIntermediate::error(TInfoSink& infoSink, const char* message, EShLanguage unitStage)
{
-#ifndef GLSLANG_WEB
infoSink.info.prefix(EPrefixError);
if (unitStage < EShLangCount)
infoSink.info << "Linking " << StageName(getStage()) << " and " << StageName(unitStage) << " stages: " << message << "\n";
else
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
-#endif
++numErrors;
}
// Link-time warning.
void TIntermediate::warn(TInfoSink& infoSink, const char* message, EShLanguage unitStage)
{
-#ifndef GLSLANG_WEB
infoSink.info.prefix(EPrefixWarning);
if (unitStage < EShLangCount)
infoSink.info << "Linking " << StageName(language) << " and " << StageName(unitStage) << " stages: " << message << "\n";
else
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
-#endif
}
// TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block
//
void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
{
-#if !defined(GLSLANG_WEB)
mergeCallGraphs(infoSink, unit);
mergeModes(infoSink, unit);
mergeTrees(infoSink, unit);
-#endif
}
//
callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
}
-#if !defined(GLSLANG_WEB)
-
#define MERGE_MAX(member) member = std::max(member, unit.member)
#define MERGE_TRUE(member) if (unit.member) member = unit.member;
ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end());
}
-#endif
-
static const TString& getNameForIdMap(TIntermSymbol* symbol)
{
TShaderInterface si = symbol->getType().getShaderInterface();
//
void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, EShLanguage unitStage)
{
-#if !defined(GLSLANG_WEB)
bool crossStage = getStage() != unitStage;
bool writeTypeComparison = false;
bool errorReported = false;
}
}
}
-#endif
}
void TIntermediate::sharedBlockCheck(TInfoSink& infoSink)
// overlap/alias/missing I/O, etc.
inOutLocationCheck(infoSink);
-#ifndef GLSLANG_WEB
if (getNumPushConstants() > 1)
error(infoSink, "Only one push_constant block is allowed per stage");
} finalLinkTraverser;
treeRoot->traverse(&finalLinkTraverser);
-#endif
}
//
// For raytracing IO (payloads and callabledata) each declaration occupies a single
// slot irrespective of type.
int collision = -1; // no collision
-#ifndef GLSLANG_WEB
if (qualifier.isAnyPayload() || qualifier.isAnyCallable() || qualifier.isHitObjectAttrNV()) {
TRange range(qualifier.layoutLocation, qualifier.layoutLocation);
collision = checkLocationRT(set, qualifier.layoutLocation);
}
return collision;
}
-#endif
+
// Not a dvec3 in/out split across two locations, generic path.
// Need a single IO-range block.
if (type.isSizedArray() && !type.getQualifier().isPerView())
return type.getOuterArraySize() * computeTypeLocationSize(elementType, stage);
else {
-#ifndef GLSLANG_WEB
// unset perViewNV attributes for arrayed per-view outputs: "perviewNV vec4 v[MAX_VIEWS][3];"
elementType.getQualifier().perViewNV = false;
-#endif
return computeTypeLocationSize(elementType, stage);
}
}
return 1;
}
-#ifndef GLSLANG_WEB
-
// Accumulate xfb buffer ranges and check for collisions as the accumulation is done.
//
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
}
}
-#endif
-
const int baseAlignmentVec4Std140 = 16;
// Return the size and alignment of a component of the given type.
// Return value is the alignment..
int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
{
-#ifdef GLSLANG_WEB
- size = 4; return 4;
-#endif
-
switch (type.getBasicType()) {
case EbtInt64:
case EbtUint64:
return size;
}
-#ifndef GLSLANG_WEB
bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) {
return type.isArray() &&
((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) ||
(language == EShLangMesh && type.getQualifier().storage == EvqVaryingOut &&
!type.getQualifier().perTaskNV));
}
-#endif // not GLSLANG_WEB
} // end namespace glslang
TRange offset;
};
-#ifndef GLSLANG_WEB
// Things that need to be tracked per xfb buffer.
struct TXfbBuffer {
TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false),
bool contains32BitType;
bool contains16BitType;
};
-#endif
// Track a set of strings describing how the module was processed.
// This includes command line options, transforms, etc., ideally inclusive enough
atomicCounterBlockName(""),
globalUniformBlockSet(TQualifier::layoutSetEnd),
globalUniformBlockBinding(TQualifier::layoutBindingEnd),
- atomicCounterBlockSet(TQualifier::layoutSetEnd)
-#ifndef GLSLANG_WEB
- ,
+ atomicCounterBlockSet(TQualifier::layoutSetEnd),
implicitThisName("@this"), implicitCounterName("@count"),
source(EShSourceNone),
useVulkanMemoryModel(false),
spirvRequirement(nullptr),
spirvExecutionMode(nullptr),
uniformLocationBase(0)
-#endif
{
localSize[0] = 1;
localSize[1] = 1;
localSizeSpecId[0] = TQualifier::layoutNotSet;
localSizeSpecId[1] = TQualifier::layoutNotSet;
localSizeSpecId[2] = TQualifier::layoutNotSet;
-#ifndef GLSLANG_WEB
xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
shiftBinding.fill(0);
-#endif
}
void setVersion(int v)
localSizeSpecId[1] != TQualifier::layoutNotSet ||
localSizeSpecId[2] != TQualifier::layoutNotSet;
}
-#ifdef GLSLANG_WEB
- void output(TInfoSink&, bool tree) { }
-
- bool isEsProfile() const { return false; }
- bool getXfbMode() const { return false; }
- bool isMultiStream() const { return false; }
- TLayoutGeometry getOutputPrimitive() const { return ElgNone; }
- bool getNonCoherentColorAttachmentReadEXT() const { return false; }
- bool getNonCoherentDepthAttachmentReadEXT() const { return false; }
- bool getNonCoherentStencilAttachmentReadEXT() const { return false; }
- bool getPostDepthCoverage() const { return false; }
- bool getEarlyFragmentTests() const { return false; }
- TLayoutDepth getDepth() const { return EldNone; }
- bool getPixelCenterInteger() const { return false; }
- void setOriginUpperLeft() { }
- bool getOriginUpperLeft() const { return true; }
- TInterlockOrdering getInterlockOrdering() const { return EioNone; }
-
- bool getAutoMapBindings() const { return false; }
- bool getAutoMapLocations() const { return false; }
- int getNumPushConstants() const { return 0; }
- void addShaderRecordCount() { }
- void addTaskNVCount() { }
- void addTaskPayloadEXTCount() { }
- void setUseVulkanMemoryModel() { }
- bool usingVulkanMemoryModel() const { return false; }
- bool usingPhysicalStorageBuffer() const { return false; }
- bool usingVariablePointers() const { return false; }
- unsigned getXfbStride(int buffer) const { return 0; }
- bool hasLayoutDerivativeModeNone() const { return false; }
- ComputeDerivativeMode getLayoutDerivativeModeNone() const { return LayoutDerivativeNone; }
-#else
void output(TInfoSink&, bool tree);
bool isEsProfile() const { return profile == EEsProfile; }
void insertSpirvExecutionModeId(int executionMode, const TIntermAggregate* args);
bool hasSpirvExecutionMode() const { return spirvExecutionMode != nullptr; }
const TSpirvExecutionMode& getSpirvExecutionMode() const { return *spirvExecutionMode; }
-#endif // GLSLANG_WEB
void addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing)
{
void setUniqueId(unsigned long long id) { uniqueId = id; }
// Certain explicit conversions are allowed conditionally
-#ifdef GLSLANG_WEB
- bool getArithemeticInt8Enabled() const { return false; }
- bool getArithemeticInt16Enabled() const { return false; }
- bool getArithemeticFloat16Enabled() const { return false; }
- void updateNumericFeature(TNumericFeatures::feature f, bool on) { }
-#else
bool getArithemeticInt8Enabled() const {
return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8);
}
void updateNumericFeature(TNumericFeatures::feature f, bool on)
{ on ? numericFeatures.insert(f) : numericFeatures.erase(f); }
-#endif
protected:
TIntermSymbol* addSymbol(long long Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
unsigned int globalUniformBlockBinding;
unsigned int atomicCounterBlockSet;
-#ifndef GLSLANG_WEB
public:
const char* const implicitThisName;
const char* const implicitCounterName;
std::unordered_map<std::string, int> uniformLocationOverrides;
int uniformLocationBase;
TNumericFeatures numericFeatures;
-#endif
std::unordered_map<std::string, TBlockStorageClass> blockBackingOverrides;
std::unordered_set<int> usedConstantId; // specialization constant ids used
const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink,
bool forwardCompatible, EShMessages messages)
:
-#if !defined(GLSLANG_WEB)
forwardCompatible(forwardCompatible),
profile(profile),
-#endif
infoSink(infoSink), version(version),
language(language),
spvVersion(spvVersion),
virtual ~TParseVersions() { }
void requireStage(const TSourceLoc&, EShLanguageMask, const char* featureDesc);
void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc);
-#ifdef GLSLANG_WEB
- const EProfile profile = EEsProfile;
- bool isEsProfile() const { return true; }
- void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc)
- {
- if (! (EEsProfile & profileMask))
- error(loc, "not supported with this profile:", featureDesc, ProfileName(profile));
- }
- void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions,
- const char* const extensions[], const char* featureDesc)
- {
- if ((EEsProfile & profileMask) && (minVersion == 0 || version < minVersion))
- error(loc, "not supported for this version or the enabled extensions", featureDesc, "");
- }
- void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension,
- const char* featureDesc)
- {
- profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc);
- }
- void initializeExtensionBehavior() { }
- void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc) { }
- void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc) { }
- void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
- const char* featureDesc) { }
- void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
- const char* featureDesc) { }
- TExtensionBehavior getExtensionBehavior(const char*) { return EBhMissing; }
- bool extensionTurnedOn(const char* const extension) { return false; }
- bool extensionsTurnedOn(int numExtensions, const char* const extensions[]) { return false; }
- void updateExtensionBehavior(int line, const char* const extension, const char* behavior) { }
- void updateExtensionBehavior(const char* const extension, TExtensionBehavior) { }
- void checkExtensionStage(const TSourceLoc&, const char* const extension) { }
- void extensionRequires(const TSourceLoc&, const char* const extension, const char* behavior) { }
- void fullIntegerCheck(const TSourceLoc&, const char* op) { }
- void doubleCheck(const TSourceLoc&, const char* op) { }
- bool float16Arithmetic() { return false; }
- void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
- bool int16Arithmetic() { return false; }
- void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
- bool int8Arithmetic() { return false; }
- void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
- void int64Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
- void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
- void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false) { }
- bool relaxedErrors() const { return false; }
- bool suppressWarnings() const { return true; }
- bool isForwardCompatible() const { return false; }
-#else
+
bool forwardCompatible; // true if errors are to be given for use of deprecated features
EProfile profile; // the declared profile in the shader (core by default)
bool isEsProfile() const { return profile == EEsProfile; }
bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; }
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
bool isForwardCompatible() const { return forwardCompatible; }
-#endif // GLSLANG_WEB
+
virtual void spvRemoved(const TSourceLoc&, const char* op);
virtual void vulkanRemoved(const TSourceLoc&, const char* op);
virtual void requireVulkan(const TSourceLoc&, const char* op);
virtual void requireSpv(const TSourceLoc&, const char* op);
virtual void requireSpv(const TSourceLoc&, const char *op, unsigned int version);
-
-#if defined(GLSLANG_WEB) && !defined(GLSLANG_WEB_DEVEL)
- void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
- const char* szExtraInfoFormat, ...) { addError(); }
- void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
- const char* szExtraInfoFormat, ...) { }
- void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken,
- const char* szExtraInfoFormat, ...) { addError(); }
- void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
- const char* szExtraInfoFormat, ...) { }
-#else
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) = 0;
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) = 0;
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
const char* szExtraInfoFormat, ...) = 0;
-#endif
void addError() { ++numErrors; }
int getNumErrors() const { return numErrors; }
parseContext.setCurrentLine(lineRes);
if (token != '\n') {
-#ifndef GLSLANG_WEB
if (token == PpAtomConstString) {
parseContext.ppRequireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line");
// We need to save a copy of the string instead of pointing
parseContext.setCurrentSourceName(sourceName);
hasFile = true;
token = scanToken(ppToken);
- } else
-#endif
- {
+ } else {
token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken);
if (! fileErr) {
parseContext.setCurrentString(fileRes);
case PpAtomLine:
token = CPPline(ppToken);
break;
-#ifndef GLSLANG_WEB
case PpAtomInclude:
if(!parseContext.isReadingHLSL()) {
parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include");
case PpAtomPragma:
token = CPPpragma(ppToken);
break;
-#endif
case PpAtomUndef:
token = CPPundef(ppToken);
break;
// Suffix:
bool isDouble = false;
bool isFloat16 = false;
-#ifndef GLSLANG_WEB
if (ch == 'l' || ch == 'L') {
if (ifdepth == 0 && parseContext.intermediate.getSource() == EShSourceGlsl)
parseContext.doubleCheck(ppToken->loc, "double floating-point suffix");
isFloat16 = true;
}
} else
-#endif
if (ch == 'f' || ch == 'F') {
-#ifndef GLSLANG_WEB
if (ifdepth == 0)
parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix");
if (ifdepth == 0 && !parseContext.relaxedErrors())
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix");
-#endif
if (ifdepth == 0 && !hasDecimalOrExponent)
parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
saveName(ch);
ppToken->name[len++] = (char)ch;
isUnsigned = true;
-#ifndef GLSLANG_WEB
int nextCh = getch();
if (nextCh == 'l' || nextCh == 'L') {
if (len < MaxTokenLength)
if (len < MaxTokenLength)
ppToken->name[len++] = (char)ch;
isInt16 = true;
-#endif
} else
ungetch();
ppToken->name[len] = '\0';
ppToken->name[len++] = (char)ch;
isUnsigned = true;
-#ifndef GLSLANG_WEB
int nextCh = getch();
if (nextCh == 'l' || nextCh == 'L') {
if (len < MaxTokenLength)
if (len < MaxTokenLength)
ppToken->name[len++] = (char)ch;
isInt16 = true;
-#endif
} else {
ungetch();
}
ppToken->name[len++] = (char)ch;
isUnsigned = true;
-#ifndef GLSLANG_WEB
int nextCh = getch();
if (nextCh == 'l' || nextCh == 'L') {
if (len < MaxTokenLength)
if (len < MaxTokenLength)
ppToken->name[len++] = (char)ch;
isInt16 = true;
-#endif
} else
ungetch();
ppToken->name[len] = '\0';
ppToken->name[len++] = (char)ch;
isUnsigned = true;
-#ifndef GLSLANG_WEB
int nextCh = getch();
if (nextCh == 'l' || nextCh == 'L') {
if (len < MaxTokenLength)
if (len < MaxTokenLength)
ppToken->name[len++] = (char)ch;
isInt16 = true;
-#endif
} else
ungetch();
int atom = stream[currentPos++].get(*ppToken);
ppToken->loc = parseContext.getCurrentLoc();
-#ifndef GLSLANG_WEB
// Check for ##, unless the current # is the last character
if (atom == '#') {
if (peekToken('#')) {
atom = PpAtomPaste;
}
}
-#endif
return atom;
}
// propagate the 'noContraction' qualifier.
//
-#ifndef GLSLANG_WEB
-
#include "propagateNoContraction.h"
#include <cstdlib>
}
}
}
-
-#endif // GLSLANG_WEB
// POSSIBILITY OF SUCH DAMAGE.
//
-#if !defined(GLSLANG_WEB)
-
#include "../Include/Common.h"
#include "reflection.h"
#include "LiveTraverser.h"
}
} // end namespace glslang
-
-#endif // !GLSLANG_WEB
// POSSIBILITY OF SUCH DAMAGE.
//
-#if !defined(GLSLANG_WEB)
-
#ifndef _REFLECTION_INCLUDED
#define _REFLECTION_INCLUDED
} // end namespace glslang
#endif // _REFLECTION_INCLUDED
-
-#endif // !GLSLANG_WEB
TShader& operator=(TShader&);
};
-#if !defined(GLSLANG_WEB)
-
//
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
//
virtual void addStage(EShLanguage stage, TIntermediate& stageIntermediate) = 0;
};
-#endif // !GLSLANG_WEB
-
// Make one TProgram per set of shaders that will get linked together. Add all
// the shaders that are to be linked together. After calling shader.parse()
// for all shaders, call link().
TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
-#if !defined(GLSLANG_WEB)
-
// Reflection Interface
// call first, to do liveness analysis, index mapping, etc.; returns false on failure
// If resolver is not provided it uses the previous approach
// and respects auto assignment and offsets.
GLSLANG_EXPORT bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr);
-#endif // !GLSLANG_WEB
protected:
GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages);
TIntermediate* intermediate[EShLangCount];
bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage
TInfoSink* infoSink;
-#if !defined(GLSLANG_WEB)
TReflection* reflection;
-#endif
bool linked;
private:
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
-if [ "$1" = 'web' ]
-then
- m4 -P -DGLSLANG_WEB MachineIndependent/glslang.m4 > MachineIndependent/glslang.y
-elif [ "$#" -eq 0 ]
-then
- m4 -P MachineIndependent/glslang.m4 > MachineIndependent/glslang.y
-else
- echo usage:
- echo $0 web
- echo $0
- exit
-fi
-
+m4 -P MachineIndependent/glslang.m4 > MachineIndependent/glslang.y
bison --defines=MachineIndependent/glslang_tab.cpp.h -t MachineIndependent/glslang.y -o MachineIndependent/glslang_tab.cpp
#include "glslang/MachineIndependent/iomapper.h"
#include "glslang/MachineIndependent/reflection.h"
-#ifndef GLSLANG_WEB
namespace glslangtest {
namespace {
} // anonymous namespace
} // namespace glslangtest
-#endif
result.linkingOutput = program.getInfoLog();
result.linkingError = program.getInfoDebugLog();
-#if !defined(GLSLANG_WEB)
- if (success)
- program.mapIO();
-#endif
+ if (success)
+ program.mapIO();
if (success && (controls & EShMsgSpvRules)) {
spv::SpvBuildLogger logger;
glslang::TProgram program;
program.addShader(&shader);
success &= program.link(controls);
-#if !defined(GLSLANG_WEB)
if (success)
program.mapIO();
-#endif
if (success && (controls & EShMsgSpvRules)) {
spv::SpvBuildLogger logger;
program.addShader(&shader);
success &= program.link(controls);
-#if !defined(GLSLANG_WEB)
if (success)
program.mapIO();
-#endif
spv::SpvBuildLogger logger;
glslang::TProgram program;
program.addShader(&shader);
success &= program.link(controls);
-#if !defined(GLSLANG_WEB)
if (success)
program.mapIO();
-#endif
if (success && (controls & EShMsgSpvRules)) {
spv::SpvBuildLogger logger;
#include "glslang/MachineIndependent/iomapper.h"
#include "glslang/MachineIndependent/reflection.h"
-#ifndef GLSLANG_WEB
namespace glslangtest {
namespace {
} // anonymous namespace
} // namespace glslangtest
-#endif