Updated glslang.
This commit is contained in:
parent
6e454877d3
commit
4d7fcf9f7d
71
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
71
3rdparty/glslang/SPIRV/GlslangToSpv.cpp
vendored
@ -107,7 +107,8 @@ private:
|
||||
//
|
||||
class TGlslangToSpvTraverser : public glslang::TIntermTraverser {
|
||||
public:
|
||||
TGlslangToSpvTraverser(const glslang::TIntermediate*, spv::SpvBuildLogger* logger, glslang::SpvOptions& options);
|
||||
TGlslangToSpvTraverser(unsigned int spvVersion, const glslang::TIntermediate*, spv::SpvBuildLogger* logger,
|
||||
glslang::SpvOptions& options);
|
||||
virtual ~TGlslangToSpvTraverser() { }
|
||||
|
||||
bool visitAggregate(glslang::TVisit, glslang::TIntermAggregate*);
|
||||
@ -128,8 +129,9 @@ protected:
|
||||
spv::Decoration TranslateAuxiliaryStorageDecoration(const glslang::TQualifier& qualifier);
|
||||
spv::BuiltIn TranslateBuiltInDecoration(glslang::TBuiltInVariable, bool memberDeclaration);
|
||||
spv::ImageFormat TranslateImageFormat(const glslang::TType& type);
|
||||
spv::SelectionControlMask TranslateSelectionControl(glslang::TSelectionControl) const;
|
||||
spv::LoopControlMask TranslateLoopControl(glslang::TLoopControl) const;
|
||||
spv::SelectionControlMask TranslateSelectionControl(const glslang::TIntermSelection&) const;
|
||||
spv::SelectionControlMask TranslateSwitchControl(const glslang::TIntermSwitch&) const;
|
||||
spv::LoopControlMask TranslateLoopControl(const glslang::TIntermLoop&, unsigned int& dependencyLength) const;
|
||||
spv::StorageClass TranslateStorageClass(const glslang::TType&);
|
||||
spv::Id createSpvVariable(const glslang::TIntermSymbol*);
|
||||
spv::Id getSampledType(const glslang::TSampler&);
|
||||
@ -747,26 +749,42 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy
|
||||
}
|
||||
}
|
||||
|
||||
spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(glslang::TSelectionControl selectionControl) const
|
||||
spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSelectionControl(const glslang::TIntermSelection& selectionNode) const
|
||||
{
|
||||
switch (selectionControl) {
|
||||
case glslang::ESelectionControlNone: return spv::SelectionControlMaskNone;
|
||||
case glslang::ESelectionControlFlatten: return spv::SelectionControlFlattenMask;
|
||||
case glslang::ESelectionControlDontFlatten: return spv::SelectionControlDontFlattenMask;
|
||||
default: return spv::SelectionControlMaskNone;
|
||||
}
|
||||
if (selectionNode.getFlatten())
|
||||
return spv::SelectionControlFlattenMask;
|
||||
if (selectionNode.getDontFlatten())
|
||||
return spv::SelectionControlDontFlattenMask;
|
||||
return spv::SelectionControlMaskNone;
|
||||
}
|
||||
|
||||
spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(glslang::TLoopControl loopControl) const
|
||||
spv::SelectionControlMask TGlslangToSpvTraverser::TranslateSwitchControl(const glslang::TIntermSwitch& switchNode) const
|
||||
{
|
||||
switch (loopControl) {
|
||||
case glslang::ELoopControlNone: return spv::LoopControlMaskNone;
|
||||
case glslang::ELoopControlUnroll: return spv::LoopControlUnrollMask;
|
||||
case glslang::ELoopControlDontUnroll: return spv::LoopControlDontUnrollMask;
|
||||
// TODO: DependencyInfinite
|
||||
// TODO: DependencyLength
|
||||
default: return spv::LoopControlMaskNone;
|
||||
if (switchNode.getFlatten())
|
||||
return spv::SelectionControlFlattenMask;
|
||||
if (switchNode.getDontFlatten())
|
||||
return spv::SelectionControlDontFlattenMask;
|
||||
return spv::SelectionControlMaskNone;
|
||||
}
|
||||
|
||||
// return a non-0 dependency if the dependency argument must be set
|
||||
spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang::TIntermLoop& loopNode,
|
||||
unsigned int& dependencyLength) const
|
||||
{
|
||||
spv::LoopControlMask control = spv::LoopControlMaskNone;
|
||||
|
||||
if (loopNode.getDontUnroll())
|
||||
control = control | spv::LoopControlDontUnrollMask;
|
||||
if (loopNode.getUnroll())
|
||||
control = control | spv::LoopControlUnrollMask;
|
||||
if (loopNode.getLoopDependency() == glslang::TIntermLoop::dependencyInfinite)
|
||||
control = control | spv::LoopControlDependencyInfiniteMask;
|
||||
else if (loopNode.getLoopDependency() > 0) {
|
||||
control = control | spv::LoopControlDependencyLengthMask;
|
||||
dependencyLength = loopNode.getLoopDependency();
|
||||
}
|
||||
|
||||
return control;
|
||||
}
|
||||
|
||||
// Translate glslang type to SPIR-V storage class.
|
||||
@ -880,13 +898,13 @@ bool HasNonLayoutQualifiers(const glslang::TType& type, const glslang::TQualifie
|
||||
// Implement the TGlslangToSpvTraverser class.
|
||||
//
|
||||
|
||||
TGlslangToSpvTraverser::TGlslangToSpvTraverser(const glslang::TIntermediate* glslangIntermediate,
|
||||
TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, const glslang::TIntermediate* glslangIntermediate,
|
||||
spv::SpvBuildLogger* buildLogger, glslang::SpvOptions& options)
|
||||
: TIntermTraverser(true, false, true),
|
||||
options(options),
|
||||
shaderEntry(nullptr), currentFunction(nullptr),
|
||||
sequenceDepth(0), logger(buildLogger),
|
||||
builder((glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger),
|
||||
builder(spvVersion, (glslang::GetKhronosToolId() << 16) | glslang::GetSpirvGeneratorVersion(), logger),
|
||||
inEntryPoint(false), entryPointTerminated(false), linkageOnly(false),
|
||||
glslangIntermediate(glslangIntermediate)
|
||||
{
|
||||
@ -2025,7 +2043,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang
|
||||
node->getCondition()->traverse(this);
|
||||
|
||||
// Selection control:
|
||||
const spv::SelectionControlMask control = TranslateSelectionControl(node->getSelectionControl());
|
||||
const spv::SelectionControlMask control = TranslateSelectionControl(*node);
|
||||
|
||||
// make an "if" based on the value created by the condition
|
||||
spv::Builder::If ifBuilder(accessChainLoad(node->getCondition()->getType()), control, builder);
|
||||
@ -2067,7 +2085,7 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T
|
||||
spv::Id selector = accessChainLoad(node->getCondition()->getAsTyped()->getType());
|
||||
|
||||
// Selection control:
|
||||
const spv::SelectionControlMask control = TranslateSelectionControl(node->getSelectionControl());
|
||||
const spv::SelectionControlMask control = TranslateSwitchControl(*node);
|
||||
|
||||
// browse the children to sort out code segments
|
||||
int defaultSegment = -1;
|
||||
@ -2127,9 +2145,8 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
|
||||
builder.createBranch(&blocks.head);
|
||||
|
||||
// Loop control:
|
||||
const spv::LoopControlMask control = TranslateLoopControl(node->getLoopControl());
|
||||
|
||||
// TODO: dependency length
|
||||
unsigned int dependencyLength = glslang::TIntermLoop::dependencyInfinite;
|
||||
const spv::LoopControlMask control = TranslateLoopControl(*node, dependencyLength);
|
||||
|
||||
// Spec requires back edges to target header blocks, and every header block
|
||||
// must dominate its merge block. Make a header block first to ensure these
|
||||
@ -2139,7 +2156,7 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn
|
||||
// including merges of its own.
|
||||
builder.setLine(node->getLoc().line);
|
||||
builder.setBuildPoint(&blocks.head);
|
||||
builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control);
|
||||
builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control, dependencyLength);
|
||||
if (node->testFirst() && node->getTest()) {
|
||||
spv::Block& test = builder.makeNewBlock();
|
||||
builder.createBranch(&test);
|
||||
@ -6067,7 +6084,7 @@ void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsign
|
||||
|
||||
glslang::GetThreadPoolAllocator().push();
|
||||
|
||||
TGlslangToSpvTraverser it(&intermediate, logger, *options);
|
||||
TGlslangToSpvTraverser it(intermediate.getSpv().spv, &intermediate, logger, *options);
|
||||
root->traverse(&it);
|
||||
it.finishSpv();
|
||||
it.dumpSpv(spirv);
|
||||
|
12
3rdparty/glslang/SPIRV/SpvBuilder.cpp
vendored
12
3rdparty/glslang/SPIRV/SpvBuilder.cpp
vendored
@ -56,7 +56,8 @@
|
||||
|
||||
namespace spv {
|
||||
|
||||
Builder::Builder(unsigned int magicNumber, SpvBuildLogger* buildLogger) :
|
||||
Builder::Builder(unsigned int spvVersion, unsigned int magicNumber, SpvBuildLogger* buildLogger) :
|
||||
spvVersion(spvVersion),
|
||||
source(SourceLanguageUnknown),
|
||||
sourceVersion(0),
|
||||
sourceFileStringId(NoResult),
|
||||
@ -2403,7 +2404,7 @@ void Builder::dump(std::vector<unsigned int>& out) const
|
||||
{
|
||||
// Header, before first instructions:
|
||||
out.push_back(MagicNumber);
|
||||
out.push_back(Version);
|
||||
out.push_back(spvVersion);
|
||||
out.push_back(builderNumber);
|
||||
out.push_back(uniqueId + 1);
|
||||
out.push_back(0);
|
||||
@ -2572,12 +2573,15 @@ void Builder::createSelectionMerge(Block* mergeBlock, unsigned int control)
|
||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));
|
||||
}
|
||||
|
||||
void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control)
|
||||
void Builder::createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control,
|
||||
unsigned int dependencyLength)
|
||||
{
|
||||
Instruction* merge = new Instruction(OpLoopMerge);
|
||||
merge->addIdOperand(mergeBlock->getId());
|
||||
merge->addIdOperand(continueBlock->getId());
|
||||
merge->addImmediateOperand(control);
|
||||
if ((control & LoopControlDependencyLengthMask) != 0)
|
||||
merge->addImmediateOperand(dependencyLength);
|
||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(merge));
|
||||
}
|
||||
|
||||
@ -2644,8 +2648,6 @@ void Builder::dumpInstructions(std::vector<unsigned int>& out, const std::vector
|
||||
void Builder::dumpModuleProcesses(std::vector<unsigned int>& out) const
|
||||
{
|
||||
for (int i = 0; i < (int)moduleProcesses.size(); ++i) {
|
||||
// TODO: switch this out for the 1.1 headers
|
||||
const spv::Op OpModuleProcessed = (spv::Op)330;
|
||||
Instruction moduleProcessed(OpModuleProcessed);
|
||||
moduleProcessed.addStringOperand(moduleProcesses[i]);
|
||||
moduleProcessed.dump(out);
|
||||
|
5
3rdparty/glslang/SPIRV/SpvBuilder.h
vendored
5
3rdparty/glslang/SPIRV/SpvBuilder.h
vendored
@ -60,7 +60,7 @@ namespace spv {
|
||||
|
||||
class Builder {
|
||||
public:
|
||||
Builder(unsigned int userNumber, SpvBuildLogger* logger);
|
||||
Builder(unsigned int spvVersion, unsigned int userNumber, SpvBuildLogger* logger);
|
||||
virtual ~Builder();
|
||||
|
||||
static const int maxMatrixSize = 4;
|
||||
@ -561,7 +561,7 @@ public:
|
||||
|
||||
void createBranch(Block* block);
|
||||
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
|
||||
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control);
|
||||
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, unsigned int dependencyLength);
|
||||
|
||||
// Sets to generate opcode for specialization constants.
|
||||
void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }
|
||||
@ -585,6 +585,7 @@ public:
|
||||
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
||||
void dumpModuleProcesses(std::vector<unsigned int>&) const;
|
||||
|
||||
unsigned int spvVersion; // the version of SPIR-V to emit in the header
|
||||
SourceLanguage source;
|
||||
int sourceVersion;
|
||||
spv::Id sourceFileStringId;
|
||||
|
1
3rdparty/glslang/SPIRV/doc.cpp
vendored
1
3rdparty/glslang/SPIRV/doc.cpp
vendored
@ -2558,6 +2558,7 @@ void Parameterize()
|
||||
InstructionDesc[OpLoopMerge].operands.push(OperandId, "'Merge Block'");
|
||||
InstructionDesc[OpLoopMerge].operands.push(OperandId, "'Continue Target'");
|
||||
InstructionDesc[OpLoopMerge].operands.push(OperandLoop, "");
|
||||
InstructionDesc[OpLoopMerge].operands.push(OperandOptionalLiteral, "");
|
||||
|
||||
InstructionDesc[OpSelectionMerge].operands.push(OperandId, "'Merge Block'");
|
||||
InstructionDesc[OpSelectionMerge].operands.push(OperandSelect, "");
|
||||
|
39
3rdparty/glslang/SPIRV/spirv.hpp
vendored
39
3rdparty/glslang/SPIRV/spirv.hpp
vendored
@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2014-2017 The Khronos Group Inc.
|
||||
// Copyright (c) 2014-2018 The Khronos Group Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and/or associated documentation files (the "Materials"),
|
||||
@ -46,12 +46,12 @@ namespace spv {
|
||||
|
||||
typedef unsigned int Id;
|
||||
|
||||
#define SPV_VERSION 0x10000
|
||||
#define SPV_REVISION 12
|
||||
#define SPV_VERSION 0x10200
|
||||
#define SPV_REVISION 3
|
||||
|
||||
static const unsigned int MagicNumber = 0x07230203;
|
||||
static const unsigned int Version = 0x00010000;
|
||||
static const unsigned int Revision = 12;
|
||||
static const unsigned int Version = 0x00010200;
|
||||
static const unsigned int Revision = 3;
|
||||
static const unsigned int OpCodeMask = 0xffff;
|
||||
static const unsigned int WordCountShift = 16;
|
||||
|
||||
@ -122,6 +122,13 @@ enum ExecutionMode {
|
||||
ExecutionModeOutputTriangleStrip = 29,
|
||||
ExecutionModeVecTypeHint = 30,
|
||||
ExecutionModeContractionOff = 31,
|
||||
ExecutionModeInitializer = 33,
|
||||
ExecutionModeFinalizer = 34,
|
||||
ExecutionModeSubgroupSize = 35,
|
||||
ExecutionModeSubgroupsPerWorkgroup = 36,
|
||||
ExecutionModeSubgroupsPerWorkgroupId = 37,
|
||||
ExecutionModeLocalSizeId = 38,
|
||||
ExecutionModeLocalSizeHintId = 39,
|
||||
ExecutionModePostDepthCoverage = 4446,
|
||||
ExecutionModeStencilRefReplacingEXT = 5027,
|
||||
ExecutionModeMax = 0x7fffffff,
|
||||
@ -378,6 +385,9 @@ enum Decoration {
|
||||
DecorationNoContraction = 42,
|
||||
DecorationInputAttachmentIndex = 43,
|
||||
DecorationAlignment = 44,
|
||||
DecorationMaxByteOffset = 45,
|
||||
DecorationAlignmentId = 46,
|
||||
DecorationMaxByteOffsetId = 47,
|
||||
DecorationExplicitInterpAMD = 4999,
|
||||
DecorationOverrideCoverageNV = 5248,
|
||||
DecorationPassthroughNV = 5250,
|
||||
@ -470,6 +480,8 @@ enum SelectionControlMask {
|
||||
enum LoopControlShift {
|
||||
LoopControlUnrollShift = 0,
|
||||
LoopControlDontUnrollShift = 1,
|
||||
LoopControlDependencyInfiniteShift = 2,
|
||||
LoopControlDependencyLengthShift = 3,
|
||||
LoopControlMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
@ -477,6 +489,8 @@ enum LoopControlMask {
|
||||
LoopControlMaskNone = 0,
|
||||
LoopControlUnrollMask = 0x00000001,
|
||||
LoopControlDontUnrollMask = 0x00000002,
|
||||
LoopControlDependencyInfiniteMask = 0x00000004,
|
||||
LoopControlDependencyLengthMask = 0x00000008,
|
||||
};
|
||||
|
||||
enum FunctionControlShift {
|
||||
@ -627,6 +641,9 @@ enum Capability {
|
||||
CapabilityStorageImageReadWithoutFormat = 55,
|
||||
CapabilityStorageImageWriteWithoutFormat = 56,
|
||||
CapabilityMultiViewport = 57,
|
||||
CapabilitySubgroupDispatch = 58,
|
||||
CapabilityNamedBarrier = 59,
|
||||
CapabilityPipeStorage = 60,
|
||||
CapabilitySubgroupBallotKHR = 4423,
|
||||
CapabilityDrawParameters = 4427,
|
||||
CapabilitySubgroupVoteKHR = 4431,
|
||||
@ -955,6 +972,18 @@ enum Op {
|
||||
OpAtomicFlagTestAndSet = 318,
|
||||
OpAtomicFlagClear = 319,
|
||||
OpImageSparseRead = 320,
|
||||
OpSizeOf = 321,
|
||||
OpTypePipeStorage = 322,
|
||||
OpConstantPipeStorage = 323,
|
||||
OpCreatePipeFromPipeStorage = 324,
|
||||
OpGetKernelLocalSizeForSubgroupCount = 325,
|
||||
OpGetKernelMaxNumSubgroups = 326,
|
||||
OpTypeNamedBarrier = 327,
|
||||
OpNamedBarrierInitialize = 328,
|
||||
OpMemoryNamedBarrier = 329,
|
||||
OpModuleProcessed = 330,
|
||||
OpExecutionModeId = 331,
|
||||
OpDecorateId = 332,
|
||||
OpSubgroupBallotKHR = 4421,
|
||||
OpSubgroupFirstInvocationKHR = 4422,
|
||||
OpSubgroupAllKHR = 4428,
|
||||
|
4
3rdparty/glslang/StandAlone/StandAlone.cpp
vendored
4
3rdparty/glslang/StandAlone/StandAlone.cpp
vendored
@ -159,7 +159,7 @@ std::vector<std::string> IncludeDirectoryList;
|
||||
int ClientInputSemanticsVersion = 100; // maps to, say, #define VULKAN 100
|
||||
int VulkanClientVersion = 100; // would map to, say, Vulkan 1.0
|
||||
int OpenGLClientVersion = 450; // doesn't influence anything yet, but maps to OpenGL 4.50
|
||||
unsigned int TargetVersion = 0x00001000; // maps to, say, SPIR-V 1.0
|
||||
unsigned int TargetVersion = 0x00010000; // maps to, say, SPIR-V 1.0
|
||||
std::vector<std::string> Processes; // what should be recorded by OpModuleProcessed, or equivalent
|
||||
|
||||
// Per descriptor-set binding base data
|
||||
@ -855,7 +855,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
||||
: glslang::EShSourceGlsl,
|
||||
compUnit.stage, glslang::EShClientVulkan, ClientInputSemanticsVersion);
|
||||
shader->setEnvClient(glslang::EShClientVulkan, VulkanClientVersion);
|
||||
shader->setEnvTarget(glslang::EshTargetSpv, TargetVersion);
|
||||
shader->setEnvTarget(glslang::EShTargetSpv, TargetVersion);
|
||||
} else {
|
||||
shader->setEnvInput((Options & EOptionReadHlsl) ? glslang::EShSourceHlsl
|
||||
: glslang::EShSourceGlsl,
|
||||
|
6
3rdparty/glslang/Test/310AofA.vert
vendored
6
3rdparty/glslang/Test/310AofA.vert
vendored
@ -113,3 +113,9 @@ out float outArray[2][3]; // ERROR
|
||||
uniform ubaa {
|
||||
int a;
|
||||
} ubaaname[2][3]; // ERROR
|
||||
|
||||
vec3 func(in mat3[2] x[3])
|
||||
{
|
||||
mat3 a0 = x[2][1];
|
||||
return a0[2];
|
||||
}
|
||||
|
15
3rdparty/glslang/Test/460.frag
vendored
15
3rdparty/glslang/Test/460.frag
vendored
@ -15,3 +15,18 @@ void main()
|
||||
b1 = allInvocations(b1);
|
||||
b1 = allInvocationsEqual(b1);
|
||||
}
|
||||
|
||||
void attExtBad()
|
||||
{
|
||||
// ERRORs, not enabled
|
||||
[[dependency_length(1+3)]] for (int i = 0; i < 8; ++i) { }
|
||||
[[flatten]] if (true) { } else { }
|
||||
}
|
||||
|
||||
#extension GL_EXT_control_flow_attributes : enable
|
||||
|
||||
void attExt()
|
||||
{
|
||||
[[dependency_length(-3)]] do { } while(true); // ERROR, not positive
|
||||
[[dependency_length(0)]] do { } while(true); // ERROR, not positive
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ ERROR: 0:82: 'xr' : vector swizzle selectors not from the same set
|
||||
ERROR: 0:83: 'xyxyx' : vector swizzle too long
|
||||
ERROR: 0:84: 'z' : vector swizzle selection out of range
|
||||
ERROR: 0:85: 'assign' : l-value required
|
||||
ERROR: 0:91: 'int' : overloaded functions must have the same return type
|
||||
ERROR: 0:91: 'main' : overloaded functions must have the same return type
|
||||
ERROR: 0:91: 'main' : function already has a body
|
||||
ERROR: 0:91: 'int' : entry point cannot return a value
|
||||
ERROR: 0:92: 'main' : function cannot take any parameter(s)
|
||||
|
@ -34,7 +34,7 @@ ERROR: 0:51: 'arrays of arrays' : not supported with this profile: none
|
||||
ERROR: 0:52: 'arrays of arrays' : not supported with this profile: none
|
||||
ERROR: 0:53: 'arrays of arrays' : not supported with this profile: none
|
||||
ERROR: 0:56: 'out' : overloaded functions must have the same parameter storage qualifiers for argument 1
|
||||
ERROR: 0:57: 'float' : overloaded functions must have the same return type
|
||||
ERROR: 0:57: 'overloadA' : overloaded functions must have the same return type
|
||||
ERROR: 0:87: 'overloadC' : no matching overloaded function found
|
||||
ERROR: 0:90: 'overloadC' : no matching overloaded function found
|
||||
ERROR: 0:95: 'overloadD' : ambiguous function signature match: multiple signatures match under implicit type conversion
|
||||
|
@ -317,6 +317,25 @@ ERROR: node is still EOpNull!
|
||||
0:99 0 (const int)
|
||||
0:99 Constant:
|
||||
0:99 1 (const int)
|
||||
0:117 Function Definition: func(mf33[3][2]; ( global highp 3-component vector of float)
|
||||
0:117 Function Parameters:
|
||||
0:117 'x' ( in 3-element array of 2-element array of highp 3X3 matrix of float)
|
||||
0:119 Sequence
|
||||
0:119 Sequence
|
||||
0:119 move second child to first child ( temp highp 3X3 matrix of float)
|
||||
0:119 'a0' ( temp highp 3X3 matrix of float)
|
||||
0:119 direct index ( temp highp 3X3 matrix of float)
|
||||
0:119 direct index ( temp 2-element array of highp 3X3 matrix of float)
|
||||
0:119 'x' ( in 3-element array of 2-element array of highp 3X3 matrix of float)
|
||||
0:119 Constant:
|
||||
0:119 2 (const int)
|
||||
0:119 Constant:
|
||||
0:119 1 (const int)
|
||||
0:120 Branch: Return with expression
|
||||
0:120 direct index ( temp highp 3-component vector of float)
|
||||
0:120 'a0' ( temp highp 3X3 matrix of float)
|
||||
0:120 Constant:
|
||||
0:120 2 (const int)
|
||||
0:? Linker Objects
|
||||
0:? 'name' (layout( column_major shared) buffer 3-element array of block{layout( column_major shared) buffer implicitly-sized array of highp float u, layout( column_major shared) buffer implicitly-sized array of highp 4-component vector of float v})
|
||||
0:? 'uname' (layout( column_major shared) uniform 3-element array of block{layout( column_major shared) uniform highp float u, layout( column_major shared) uniform implicitly-sized array of highp 4-component vector of float v})
|
||||
|
50
3rdparty/glslang/Test/baseResults/460.frag.out
vendored
50
3rdparty/glslang/Test/baseResults/460.frag.out
vendored
@ -1,6 +1,14 @@
|
||||
460.frag
|
||||
ERROR: 0:22: 'attribute' : required extension not requested: GL_EXT_control_flow_attributes
|
||||
ERROR: 0:23: 'attribute' : required extension not requested: GL_EXT_control_flow_attributes
|
||||
ERROR: 0:30: 'dependency_length' : must be positive
|
||||
ERROR: 0:31: 'dependency_length' : must be positive
|
||||
ERROR: 4 compilation errors. No code generated.
|
||||
|
||||
|
||||
Shader version: 460
|
||||
0:? Sequence
|
||||
Requested GL_EXT_control_flow_attributes
|
||||
ERROR: node is still EOpNull!
|
||||
0:10 Function Definition: main( ( global void)
|
||||
0:10 Function Parameters:
|
||||
0:12 Sequence
|
||||
@ -21,6 +29,43 @@ Shader version: 460
|
||||
0:16 'b1' ( temp bool)
|
||||
0:16 allInvocationsEqual ( global bool)
|
||||
0:16 'b1' ( temp bool)
|
||||
0:19 Function Definition: attExtBad( ( global void)
|
||||
0:19 Function Parameters:
|
||||
0:22 Sequence
|
||||
0:22 Sequence
|
||||
0:22 Sequence
|
||||
0:22 move second child to first child ( temp int)
|
||||
0:22 'i' ( temp int)
|
||||
0:22 Constant:
|
||||
0:22 0 (const int)
|
||||
0:22 Loop with condition tested first: Dependency 4
|
||||
0:22 Loop Condition
|
||||
0:22 Compare Less Than ( temp bool)
|
||||
0:22 'i' ( temp int)
|
||||
0:22 Constant:
|
||||
0:22 8 (const int)
|
||||
0:22 No loop body
|
||||
0:22 Loop Terminal Expression
|
||||
0:22 Pre-Increment ( temp int)
|
||||
0:22 'i' ( temp int)
|
||||
0:23 Test condition and select ( temp void): Flatten
|
||||
0:23 Condition
|
||||
0:23 Constant:
|
||||
0:23 true (const bool)
|
||||
0:23 true case is null
|
||||
0:28 Function Definition: attExt( ( global void)
|
||||
0:28 Function Parameters:
|
||||
0:30 Sequence
|
||||
0:30 Loop with condition not tested first: Dependency -3
|
||||
0:30 Loop Condition
|
||||
0:30 Constant:
|
||||
0:30 true (const bool)
|
||||
0:30 No loop body
|
||||
0:31 Loop with condition not tested first
|
||||
0:31 Loop Condition
|
||||
0:31 Constant:
|
||||
0:31 true (const bool)
|
||||
0:31 No loop body
|
||||
0:? Linker Objects
|
||||
0:? 's' ( smooth in structure{ global float f, global 4-component vector of float v})
|
||||
|
||||
@ -29,7 +74,8 @@ Linked fragment stage:
|
||||
|
||||
|
||||
Shader version: 460
|
||||
0:? Sequence
|
||||
Requested GL_EXT_control_flow_attributes
|
||||
ERROR: node is still EOpNull!
|
||||
0:10 Function Definition: main( ( global void)
|
||||
0:10 Function Parameters:
|
||||
0:12 Sequence
|
||||
|
@ -10,7 +10,7 @@ local_size = (4, 6, 8)
|
||||
0:11 'x' ( temp int)
|
||||
0:11 Constant:
|
||||
0:11 0 (const int)
|
||||
0:11 Loop with condition tested first
|
||||
0:11 Loop with condition tested first: Unroll
|
||||
0:11 Loop Condition
|
||||
0:11 Compare Less Than ( temp bool)
|
||||
0:11 'x' ( temp int)
|
||||
@ -53,7 +53,7 @@ local_size = (4, 6, 8)
|
||||
0:11 'x' ( temp int)
|
||||
0:11 Constant:
|
||||
0:11 0 (const int)
|
||||
0:11 Loop with condition tested first
|
||||
0:11 Loop with condition tested first: Unroll
|
||||
0:11 Loop Condition
|
||||
0:11 Compare Less Than ( temp bool)
|
||||
0:11 'x' ( temp int)
|
||||
|
@ -6,7 +6,7 @@ gl_FragCoord origin is upper left
|
||||
0:2 Function Parameters:
|
||||
0:2 'input' ( in 4-component vector of float)
|
||||
0:? Sequence
|
||||
0:11 Test condition and select ( temp void)
|
||||
0:11 Test condition and select ( temp void): DontFlatten
|
||||
0:11 Condition
|
||||
0:11 Constant:
|
||||
0:11 false (const bool)
|
||||
@ -33,7 +33,7 @@ gl_FragCoord origin is upper left
|
||||
0:2 Function Parameters:
|
||||
0:2 'input' ( in 4-component vector of float)
|
||||
0:? Sequence
|
||||
0:11 Test condition and select ( temp void)
|
||||
0:11 Test condition and select ( temp void): DontFlatten
|
||||
0:11 Condition
|
||||
0:11 Constant:
|
||||
0:11 false (const bool)
|
||||
|
@ -6,12 +6,12 @@ gl_FragCoord origin is upper left
|
||||
0:2 Function Parameters:
|
||||
0:2 'input' ( in float)
|
||||
0:? Sequence
|
||||
0:3 Loop with condition not tested first
|
||||
0:3 Loop with condition not tested first: Unroll
|
||||
0:3 Loop Condition
|
||||
0:3 Constant:
|
||||
0:3 false (const bool)
|
||||
0:3 No loop body
|
||||
0:4 Loop with condition not tested first
|
||||
0:4 Loop with condition not tested first: Unroll
|
||||
0:4 Loop Condition
|
||||
0:4 Constant:
|
||||
0:4 false (const bool)
|
||||
@ -80,12 +80,12 @@ gl_FragCoord origin is upper left
|
||||
0:2 Function Parameters:
|
||||
0:2 'input' ( in float)
|
||||
0:? Sequence
|
||||
0:3 Loop with condition not tested first
|
||||
0:3 Loop with condition not tested first: Unroll
|
||||
0:3 Loop Condition
|
||||
0:3 Constant:
|
||||
0:3 false (const bool)
|
||||
0:3 No loop body
|
||||
0:4 Loop with condition not tested first
|
||||
0:4 Loop with condition not tested first: Unroll
|
||||
0:4 Loop Condition
|
||||
0:4 Constant:
|
||||
0:4 false (const bool)
|
||||
|
@ -17,7 +17,7 @@ gl_FragCoord origin is upper left
|
||||
0:4 No loop condition
|
||||
0:4 No loop body
|
||||
0:? Sequence
|
||||
0:5 Loop with condition tested first
|
||||
0:5 Loop with condition tested first: Unroll
|
||||
0:5 Loop Condition
|
||||
0:5 any ( temp bool)
|
||||
0:5 NotEqual ( temp 4-component vector of bool)
|
||||
@ -220,7 +220,7 @@ gl_FragCoord origin is upper left
|
||||
0:4 No loop condition
|
||||
0:4 No loop body
|
||||
0:? Sequence
|
||||
0:5 Loop with condition tested first
|
||||
0:5 Loop with condition tested first: Unroll
|
||||
0:5 Loop Condition
|
||||
0:5 any ( temp bool)
|
||||
0:5 NotEqual ( temp 4-component vector of bool)
|
||||
|
@ -42,7 +42,7 @@ gl_FragCoord origin is upper left
|
||||
0:14 'input' ( in 4-component vector of float)
|
||||
0:14 'input' ( in 4-component vector of float)
|
||||
0:14 true case is null
|
||||
0:19 Test condition and select ( temp void)
|
||||
0:19 Test condition and select ( temp void): Flatten
|
||||
0:19 Condition
|
||||
0:19 all ( temp bool)
|
||||
0:19 Equal ( temp 4-component vector of bool)
|
||||
@ -152,7 +152,7 @@ gl_FragCoord origin is upper left
|
||||
0:14 'input' ( in 4-component vector of float)
|
||||
0:14 'input' ( in 4-component vector of float)
|
||||
0:14 true case is null
|
||||
0:19 Test condition and select ( temp void)
|
||||
0:19 Test condition and select ( temp void): Flatten
|
||||
0:19 Condition
|
||||
0:19 all ( temp bool)
|
||||
0:19 Equal ( temp 4-component vector of bool)
|
||||
|
@ -10,7 +10,7 @@ gl_FragCoord origin is upper left
|
||||
0:5 'x' ( temp int)
|
||||
0:5 Constant:
|
||||
0:5 0 (const int)
|
||||
0:5 Loop with condition tested first
|
||||
0:5 Loop with condition tested first: Unroll
|
||||
0:5 Loop Condition
|
||||
0:5 Compare Less Than ( temp bool)
|
||||
0:5 'x' ( temp int)
|
||||
@ -25,7 +25,7 @@ gl_FragCoord origin is upper left
|
||||
0:8 'y' ( temp int)
|
||||
0:8 Constant:
|
||||
0:8 0 (const int)
|
||||
0:8 Loop with condition tested first
|
||||
0:8 Loop with condition tested first: DontUnroll
|
||||
0:8 Loop Condition
|
||||
0:8 Compare Less Than ( temp bool)
|
||||
0:8 'y' ( temp int)
|
||||
@ -80,7 +80,7 @@ gl_FragCoord origin is upper left
|
||||
0:5 'x' ( temp int)
|
||||
0:5 Constant:
|
||||
0:5 0 (const int)
|
||||
0:5 Loop with condition tested first
|
||||
0:5 Loop with condition tested first: Unroll
|
||||
0:5 Loop Condition
|
||||
0:5 Compare Less Than ( temp bool)
|
||||
0:5 'x' ( temp int)
|
||||
@ -95,7 +95,7 @@ gl_FragCoord origin is upper left
|
||||
0:8 'y' ( temp int)
|
||||
0:8 Constant:
|
||||
0:8 0 (const int)
|
||||
0:8 Loop with condition tested first
|
||||
0:8 Loop with condition tested first: DontUnroll
|
||||
0:8 Loop Condition
|
||||
0:8 Compare Less Than ( temp bool)
|
||||
0:8 'y' ( temp int)
|
||||
|
@ -1,20 +1,20 @@
|
||||
hlsl.numthreads.comp
|
||||
Shader version: 500
|
||||
local_size = (4, 4, 2)
|
||||
local_size = (1, 4, 8)
|
||||
0:? Sequence
|
||||
0:4 Function Definition: main(vu3; ( temp void)
|
||||
0:4 Function Parameters:
|
||||
0:4 'tid' ( in 3-component vector of uint)
|
||||
0:9 Function Definition: @main_aux1(vu3; ( temp void)
|
||||
0:9 Function Definition: @main_aux2(vu3; ( temp void)
|
||||
0:9 Function Parameters:
|
||||
0:9 'tid' ( in 3-component vector of uint)
|
||||
0:9 Function Definition: main_aux1( ( temp void)
|
||||
0:9 Function Definition: main_aux2( ( temp void)
|
||||
0:9 Function Parameters:
|
||||
0:? Sequence
|
||||
0:9 move second child to first child ( temp 3-component vector of uint)
|
||||
0:? 'tid' ( temp 3-component vector of uint)
|
||||
0:? 'tid' ( in 3-component vector of uint GlobalInvocationID)
|
||||
0:9 Function Call: @main_aux1(vu3; ( temp void)
|
||||
0:9 Function Call: @main_aux2(vu3; ( temp void)
|
||||
0:? 'tid' ( temp 3-component vector of uint)
|
||||
0:? Linker Objects
|
||||
0:? 'tid' ( in 3-component vector of uint GlobalInvocationID)
|
||||
@ -24,21 +24,21 @@ Linked compute stage:
|
||||
|
||||
|
||||
Shader version: 500
|
||||
local_size = (4, 4, 2)
|
||||
local_size = (1, 4, 8)
|
||||
0:? Sequence
|
||||
0:4 Function Definition: main(vu3; ( temp void)
|
||||
0:4 Function Parameters:
|
||||
0:4 'tid' ( in 3-component vector of uint)
|
||||
0:9 Function Definition: @main_aux1(vu3; ( temp void)
|
||||
0:9 Function Definition: @main_aux2(vu3; ( temp void)
|
||||
0:9 Function Parameters:
|
||||
0:9 'tid' ( in 3-component vector of uint)
|
||||
0:9 Function Definition: main_aux1( ( temp void)
|
||||
0:9 Function Definition: main_aux2( ( temp void)
|
||||
0:9 Function Parameters:
|
||||
0:? Sequence
|
||||
0:9 move second child to first child ( temp 3-component vector of uint)
|
||||
0:? 'tid' ( temp 3-component vector of uint)
|
||||
0:? 'tid' ( in 3-component vector of uint GlobalInvocationID)
|
||||
0:9 Function Call: @main_aux1(vu3; ( temp void)
|
||||
0:9 Function Call: @main_aux2(vu3; ( temp void)
|
||||
0:? 'tid' ( temp 3-component vector of uint)
|
||||
0:? Linker Objects
|
||||
0:? 'tid' ( in 3-component vector of uint GlobalInvocationID)
|
||||
@ -50,13 +50,13 @@ local_size = (4, 4, 2)
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint GLCompute 4 "main_aux1" 18
|
||||
ExecutionMode 4 LocalSize 4 4 2
|
||||
EntryPoint GLCompute 4 "main_aux2" 18
|
||||
ExecutionMode 4 LocalSize 1 4 8
|
||||
Source HLSL 500
|
||||
Name 4 "main_aux1"
|
||||
Name 4 "main_aux2"
|
||||
Name 11 "main(vu3;"
|
||||
Name 10 "tid"
|
||||
Name 14 "@main_aux1(vu3;"
|
||||
Name 14 "@main_aux2(vu3;"
|
||||
Name 13 "tid"
|
||||
Name 16 "tid"
|
||||
Name 18 "tid"
|
||||
@ -70,7 +70,7 @@ local_size = (4, 4, 2)
|
||||
9: TypeFunction 2 8(ptr)
|
||||
17: TypePointer Input 7(ivec3)
|
||||
18(tid): 17(ptr) Variable Input
|
||||
4(main_aux1): 2 Function None 3
|
||||
4(main_aux2): 2 Function None 3
|
||||
5: Label
|
||||
16(tid): 8(ptr) Variable Function
|
||||
20(param): 8(ptr) Variable Function
|
||||
@ -78,7 +78,7 @@ local_size = (4, 4, 2)
|
||||
Store 16(tid) 19
|
||||
21: 7(ivec3) Load 16(tid)
|
||||
Store 20(param) 21
|
||||
22: 2 FunctionCall 14(@main_aux1(vu3;) 20(param)
|
||||
22: 2 FunctionCall 14(@main_aux2(vu3;) 20(param)
|
||||
Return
|
||||
FunctionEnd
|
||||
11(main(vu3;): 2 Function None 9
|
||||
@ -86,7 +86,7 @@ local_size = (4, 4, 2)
|
||||
12: Label
|
||||
Return
|
||||
FunctionEnd
|
||||
14(@main_aux1(vu3;): 2 Function None 9
|
||||
14(@main_aux2(vu3;): 2 Function None 9
|
||||
13(tid): 8(ptr) FunctionParameter
|
||||
15: Label
|
||||
Return
|
||||
|
@ -36,7 +36,7 @@ gl_FragCoord origin is upper left
|
||||
0:17 Pre-Decrement ( temp 4-component vector of float)
|
||||
0:17 'input' ( in 4-component vector of float)
|
||||
0:18 Branch: Break
|
||||
0:21 switch
|
||||
0:21 switch: DontFlatten
|
||||
0:21 condition
|
||||
0:21 'c' ( in int)
|
||||
0:21 body
|
||||
@ -186,7 +186,7 @@ gl_FragCoord origin is upper left
|
||||
0:17 Pre-Decrement ( temp 4-component vector of float)
|
||||
0:17 'input' ( in 4-component vector of float)
|
||||
0:18 Branch: Break
|
||||
0:21 switch
|
||||
0:21 switch: DontFlatten
|
||||
0:21 condition
|
||||
0:21 'c' ( in int)
|
||||
0:21 body
|
||||
|
@ -21,7 +21,7 @@ gl_FragCoord origin is upper left
|
||||
0:4 Constant:
|
||||
0:4 false (const bool)
|
||||
0:4 No loop body
|
||||
0:5 Loop with condition tested first
|
||||
0:5 Loop with condition tested first: Unroll
|
||||
0:5 Loop Condition
|
||||
0:5 Constant:
|
||||
0:5 false (const bool)
|
||||
@ -71,7 +71,7 @@ gl_FragCoord origin is upper left
|
||||
0:4 Constant:
|
||||
0:4 false (const bool)
|
||||
0:4 No loop body
|
||||
0:5 Loop with condition tested first
|
||||
0:5 Loop with condition tested first: Unroll
|
||||
0:5 Loop Condition
|
||||
0:5 Constant:
|
||||
0:5 false (const bool)
|
||||
|
238
3rdparty/glslang/Test/baseResults/spv.controlFlowAttributes.frag.out
vendored
Executable file
238
3rdparty/glslang/Test/baseResults/spv.controlFlowAttributes.frag.out
vendored
Executable file
@ -0,0 +1,238 @@
|
||||
spv.controlFlowAttributes.frag
|
||||
WARNING: 0:20: '' : attribute with arguments not recognized, skipping
|
||||
WARNING: 0:21: '' : attribute with arguments not recognized, skipping
|
||||
WARNING: 0:22: '' : attribute with arguments not recognized, skipping
|
||||
WARNING: 0:23: 'dependency_length' : expected a single integer argument
|
||||
WARNING: 0:24: '' : attribute with arguments not recognized, skipping
|
||||
WARNING: 0:25: '' : attribute with arguments not recognized, skipping
|
||||
WARNING: 0:26: '' : attribute with arguments not recognized, skipping
|
||||
|
||||
// Module Version 10000
|
||||
// Generated by (magic number): 80003
|
||||
// Id's are bound by 118
|
||||
|
||||
Capability Shader
|
||||
1: ExtInstImport "GLSL.std.450"
|
||||
MemoryModel Logical GLSL450
|
||||
EntryPoint Fragment 4 "main"
|
||||
ExecutionMode 4 OriginUpperLeft
|
||||
Source GLSL 450
|
||||
SourceExtension "GL_EXT_control_flow_attributes"
|
||||
Name 4 "main"
|
||||
Name 8 "i"
|
||||
Name 36 "i"
|
||||
Name 47 "cond"
|
||||
Name 60 "i"
|
||||
Name 79 "i"
|
||||
2: TypeVoid
|
||||
3: TypeFunction 2
|
||||
6: TypeInt 32 1
|
||||
7: TypePointer Function 6(int)
|
||||
9: 6(int) Constant 0
|
||||
16: 6(int) Constant 8
|
||||
17: TypeBool
|
||||
20: 6(int) Constant 1
|
||||
31: 17(bool) ConstantTrue
|
||||
46: TypePointer Private 17(bool)
|
||||
47(cond): 46(ptr) Variable Private
|
||||
54: 17(bool) ConstantFalse
|
||||
55: 6(int) Constant 3
|
||||
4(main): 2 Function None 3
|
||||
5: Label
|
||||
8(i): 7(ptr) Variable Function
|
||||
36(i): 7(ptr) Variable Function
|
||||
60(i): 7(ptr) Variable Function
|
||||
79(i): 7(ptr) Variable Function
|
||||
Store 8(i) 9
|
||||
Branch 10
|
||||
10: Label
|
||||
LoopMerge 12 13 Unroll
|
||||
Branch 14
|
||||
14: Label
|
||||
15: 6(int) Load 8(i)
|
||||
18: 17(bool) SLessThan 15 16
|
||||
BranchConditional 18 11 12
|
||||
11: Label
|
||||
Branch 13
|
||||
13: Label
|
||||
19: 6(int) Load 8(i)
|
||||
21: 6(int) IAdd 19 20
|
||||
Store 8(i) 21
|
||||
Branch 10
|
||||
12: Label
|
||||
Branch 22
|
||||
22: Label
|
||||
LoopMerge 24 25 DontUnroll
|
||||
Branch 23
|
||||
23: Label
|
||||
Branch 25
|
||||
25: Label
|
||||
Branch 22
|
||||
24: Label
|
||||
Branch 26
|
||||
26: Label
|
||||
LoopMerge 28 29 DontUnroll
|
||||
Branch 30
|
||||
30: Label
|
||||
BranchConditional 31 27 28
|
||||
27: Label
|
||||
Branch 29
|
||||
29: Label
|
||||
Branch 26
|
||||
28: Label
|
||||
Branch 32
|
||||
32: Label
|
||||
LoopMerge 34 35 DependencyInfinite
|
||||
Branch 33
|
||||
33: Label
|
||||
Branch 35
|
||||
35: Label
|
||||
BranchConditional 31 32 34
|
||||
34: Label
|
||||
Store 36(i) 9
|
||||
Branch 37
|
||||
37: Label
|
||||
LoopMerge 39 40 DependencyLength 4
|
||||
Branch 41
|
||||
41: Label
|
||||
42: 6(int) Load 36(i)
|
||||
43: 17(bool) SLessThan 42 16
|
||||
BranchConditional 43 38 39
|
||||
38: Label
|
||||
Branch 40
|
||||
40: Label
|
||||
44: 6(int) Load 36(i)
|
||||
45: 6(int) IAdd 44 20
|
||||
Store 36(i) 45
|
||||
Branch 37
|
||||
39: Label
|
||||
48: 17(bool) Load 47(cond)
|
||||
SelectionMerge 50 Flatten
|
||||
BranchConditional 48 49 50
|
||||
49: Label
|
||||
Branch 50
|
||||
50: Label
|
||||
51: 17(bool) Load 47(cond)
|
||||
SelectionMerge 53 DontFlatten
|
||||
BranchConditional 51 52 53
|
||||
52: Label
|
||||
Store 47(cond) 54
|
||||
Branch 53
|
||||
53: Label
|
||||
SelectionMerge 57 DontFlatten
|
||||
Switch 55 57
|
||||
case 3: 56
|
||||
56: Label
|
||||
Branch 57
|
||||
57: Label
|
||||
Store 60(i) 9
|
||||
Branch 61
|
||||
61: Label
|
||||
LoopMerge 63 64 None
|
||||
Branch 65
|
||||
65: Label
|
||||
66: 6(int) Load 60(i)
|
||||
67: 17(bool) SLessThan 66 16
|
||||
BranchConditional 67 62 63
|
||||
62: Label
|
||||
Branch 64
|
||||
64: Label
|
||||
68: 6(int) Load 60(i)
|
||||
69: 6(int) IAdd 68 20
|
||||
Store 60(i) 69
|
||||
Branch 61
|
||||
63: Label
|
||||
Branch 70
|
||||
70: Label
|
||||
LoopMerge 72 73 None
|
||||
Branch 74
|
||||
74: Label
|
||||
BranchConditional 31 71 72
|
||||
71: Label
|
||||
Branch 73
|
||||
73: Label
|
||||
Branch 70
|
||||
72: Label
|
||||
Branch 75
|
||||
75: Label
|
||||
LoopMerge 77 78 None
|
||||
Branch 76
|
||||
76: Label
|
||||
Branch 78
|
||||
78: Label
|
||||
BranchConditional 31 75 77
|
||||
77: Label
|
||||
Store 79(i) 9
|
||||
Branch 80
|
||||
80: Label
|
||||
LoopMerge 82 83 None
|
||||
Branch 84
|
||||
84: Label
|
||||
85: 6(int) Load 79(i)
|
||||
86: 17(bool) SLessThan 85 16
|
||||
BranchConditional 86 81 82
|
||||
81: Label
|
||||
Branch 83
|
||||
83: Label
|
||||
87: 6(int) Load 79(i)
|
||||
88: 6(int) IAdd 87 20
|
||||
Store 79(i) 88
|
||||
Branch 80
|
||||
82: Label
|
||||
89: 17(bool) Load 47(cond)
|
||||
SelectionMerge 91 None
|
||||
BranchConditional 89 90 91
|
||||
90: Label
|
||||
Branch 91
|
||||
91: Label
|
||||
92: 17(bool) Load 47(cond)
|
||||
SelectionMerge 94 None
|
||||
BranchConditional 92 93 94
|
||||
93: Label
|
||||
Store 47(cond) 54
|
||||
Branch 94
|
||||
94: Label
|
||||
SelectionMerge 96 None
|
||||
Switch 55 96
|
||||
case 3: 95
|
||||
95: Label
|
||||
Branch 96
|
||||
96: Label
|
||||
Branch 99
|
||||
99: Label
|
||||
LoopMerge 101 102 Unroll DontUnroll DependencyLength 2
|
||||
Branch 103
|
||||
103: Label
|
||||
104: 17(bool) Load 47(cond)
|
||||
BranchConditional 104 100 101
|
||||
100: Label
|
||||
Branch 102
|
||||
102: Label
|
||||
Branch 99
|
||||
101: Label
|
||||
SelectionMerge 106 DontFlatten
|
||||
Switch 55 106
|
||||
case 3: 105
|
||||
105: Label
|
||||
Branch 106
|
||||
106: Label
|
||||
109: 17(bool) Load 47(cond)
|
||||
SelectionMerge 111 Flatten
|
||||
BranchConditional 109 110 111
|
||||
110: Label
|
||||
Branch 111
|
||||
111: Label
|
||||
Branch 112
|
||||
112: Label
|
||||
LoopMerge 114 115 DependencyInfinite
|
||||
Branch 116
|
||||
116: Label
|
||||
117: 17(bool) Load 47(cond)
|
||||
BranchConditional 117 113 114
|
||||
113: Label
|
||||
Branch 115
|
||||
115: Label
|
||||
Branch 112
|
||||
114: Label
|
||||
Return
|
||||
FunctionEnd
|
7
3rdparty/glslang/Test/hlsl.numthreads.comp
vendored
7
3rdparty/glslang/Test/hlsl.numthreads.comp
vendored
@ -4,11 +4,8 @@ void main(uint3 tid : SV_DispatchThreadID )
|
||||
{
|
||||
}
|
||||
|
||||
[numTHreaDs(4,4,2)] // case insensitive
|
||||
void main_aux1(uint3 tid : SV_DispatchThreadID )
|
||||
[numthreads(1,4,8)]
|
||||
void main_aux2(uint3 tid : SV_DispatchThreadID )
|
||||
{
|
||||
}
|
||||
|
||||
[numthreads(1,4,8)]
|
||||
void main_aux2(uint3 tid : SV_DispatchThreadID );
|
||||
|
||||
|
39
3rdparty/glslang/Test/spv.controlFlowAttributes.frag
vendored
Normal file
39
3rdparty/glslang/Test/spv.controlFlowAttributes.frag
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
#version 450
|
||||
|
||||
#extension GL_EXT_control_flow_attributes : enable
|
||||
|
||||
bool cond;
|
||||
|
||||
void main()
|
||||
{
|
||||
[[unroll]] for (int i = 0; i < 8; ++i) { }
|
||||
[[loop]] for (;;) { }
|
||||
[[dont_unroll]] while(true) { }
|
||||
[[dependency_infinite]] do { } while(true);
|
||||
[[dependency_length(1+3)]] for (int i = 0; i < 8; ++i) { }
|
||||
[[flatten]] if (cond) { } else { }
|
||||
[[branch]] if (cond) cond = false;
|
||||
[[dont_flatten]] switch(3) { } // dropped
|
||||
[[dont_flatten]] switch(3) { case 3: break; }
|
||||
|
||||
// warnings on all these
|
||||
[[unroll(2)]] for (int i = 0; i < 8; ++i) { }
|
||||
[[dont_unroll(-2)]] while(true) { }
|
||||
[[dependency_infinite(3)]] do { } while(true);
|
||||
[[dependency_length]] for (int i = 0; i < 8; ++i) { }
|
||||
[[flatten(3)]] if (cond) { } else { }
|
||||
[[branch(5.2)]] if (cond) cond = false;
|
||||
[[dont_flatten(3 + 7)]] switch(3) { case 3: break; }
|
||||
|
||||
// other valid uses
|
||||
[[ unroll, dont_unroll, dependency_length(2) ]] while(cond) { }
|
||||
[ [ dont_flatten , branch ] ] switch(3) { case 3: break; }
|
||||
[
|
||||
// attribute
|
||||
[
|
||||
// here
|
||||
flatten
|
||||
]
|
||||
] if (cond) { } else { }
|
||||
[[ dependency_length(2), dependency_infinite ]] while(cond) { }
|
||||
}
|
2
3rdparty/glslang/glslang/CMakeLists.txt
vendored
2
3rdparty/glslang/glslang/CMakeLists.txt
vendored
@ -9,6 +9,7 @@ endif(WIN32)
|
||||
set(SOURCES
|
||||
MachineIndependent/glslang.y
|
||||
MachineIndependent/glslang_tab.cpp
|
||||
MachineIndependent/attribute.cpp
|
||||
MachineIndependent/Constant.cpp
|
||||
MachineIndependent/iomapper.cpp
|
||||
MachineIndependent/InfoSink.cpp
|
||||
@ -51,6 +52,7 @@ set(HEADERS
|
||||
Include/revision.h
|
||||
Include/ShHandle.h
|
||||
Include/Types.h
|
||||
MachineIndependent/attribute.h
|
||||
MachineIndependent/glslang_tab.cpp.h
|
||||
MachineIndependent/gl_types.h
|
||||
MachineIndependent/Initialize.h
|
||||
|
2
3rdparty/glslang/glslang/Include/Common.h
vendored
2
3rdparty/glslang/glslang/Include/Common.h
vendored
@ -155,7 +155,7 @@ inline TString* NewPoolTString(const char* s)
|
||||
return new(memory) TString(s);
|
||||
}
|
||||
|
||||
template<class T> inline T* NewPoolObject(T)
|
||||
template<class T> inline T* NewPoolObject(T*)
|
||||
{
|
||||
return new(GetThreadPoolAllocator().allocate(sizeof(T))) T;
|
||||
}
|
||||
|
@ -37,6 +37,9 @@
|
||||
#ifndef _CONSTANT_UNION_INCLUDED_
|
||||
#define _CONSTANT_UNION_INCLUDED_
|
||||
|
||||
#include "../Include/Common.h"
|
||||
#include "../Include/BaseTypes.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
class TConstUnion {
|
||||
@ -595,9 +598,6 @@ public:
|
||||
if (! unionArray || ! rhs.unionArray)
|
||||
return false;
|
||||
|
||||
if (! unionArray || ! rhs.unionArray)
|
||||
return false;
|
||||
|
||||
return *unionArray == *rhs.unionArray;
|
||||
}
|
||||
bool operator!=(const TConstUnionArray& rhs) const { return ! operator==(rhs); }
|
||||
|
75
3rdparty/glslang/glslang/Include/intermediate.h
vendored
75
3rdparty/glslang/glslang/Include/intermediate.h
vendored
@ -819,7 +819,7 @@ public:
|
||||
virtual glslang::TIntermMethod* getAsMethodNode() { return 0; }
|
||||
virtual glslang::TIntermSymbol* getAsSymbolNode() { return 0; }
|
||||
virtual glslang::TIntermBranch* getAsBranchNode() { return 0; }
|
||||
virtual glslang::TIntermLoop* getAsLoopNode() { return 0; }
|
||||
virtual glslang::TIntermLoop* getAsLoopNode() { return 0; }
|
||||
|
||||
virtual const glslang::TIntermTyped* getAsTyped() const { return 0; }
|
||||
virtual const glslang::TIntermOperator* getAsOperator() const { return 0; }
|
||||
@ -832,7 +832,7 @@ public:
|
||||
virtual const glslang::TIntermMethod* getAsMethodNode() const { return 0; }
|
||||
virtual const glslang::TIntermSymbol* getAsSymbolNode() const { return 0; }
|
||||
virtual const glslang::TIntermBranch* getAsBranchNode() const { return 0; }
|
||||
virtual const glslang::TIntermLoop* getAsLoopNode() const { return 0; }
|
||||
virtual const glslang::TIntermLoop* getAsLoopNode() const { return 0; }
|
||||
virtual ~TIntermNode() { }
|
||||
|
||||
protected:
|
||||
@ -885,24 +885,6 @@ protected:
|
||||
TType type;
|
||||
};
|
||||
|
||||
//
|
||||
// Selection control hints
|
||||
//
|
||||
enum TSelectionControl {
|
||||
ESelectionControlNone,
|
||||
ESelectionControlFlatten,
|
||||
ESelectionControlDontFlatten,
|
||||
};
|
||||
|
||||
//
|
||||
// Loop control hints
|
||||
//
|
||||
enum TLoopControl {
|
||||
ELoopControlNone,
|
||||
ELoopControlUnroll,
|
||||
ELoopControlDontUnroll,
|
||||
};
|
||||
|
||||
//
|
||||
// Handle for, do-while, and while loops.
|
||||
//
|
||||
@ -913,26 +895,36 @@ public:
|
||||
test(aTest),
|
||||
terminal(aTerminal),
|
||||
first(testFirst),
|
||||
control(ELoopControlNone)
|
||||
unroll(false),
|
||||
dontUnroll(false),
|
||||
dependency(0)
|
||||
{ }
|
||||
|
||||
virtual TIntermLoop* getAsLoopNode() { return this; }
|
||||
virtual const TIntermLoop* getAsLoopNode() const { return this; }
|
||||
virtual TIntermLoop* getAsLoopNode() { return this; }
|
||||
virtual const TIntermLoop* getAsLoopNode() const { return this; }
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
TIntermNode* getBody() const { return body; }
|
||||
TIntermTyped* getTest() const { return test; }
|
||||
TIntermTyped* getTerminal() const { return terminal; }
|
||||
bool testFirst() const { return first; }
|
||||
|
||||
void setLoopControl(TLoopControl c) { control = c; }
|
||||
TLoopControl getLoopControl() const { return control; }
|
||||
void setUnroll() { unroll = true; }
|
||||
void setDontUnroll() { dontUnroll = true; }
|
||||
bool getUnroll() const { return unroll; }
|
||||
bool getDontUnroll() const { return dontUnroll; }
|
||||
|
||||
static const unsigned int dependencyInfinite = 0xFFFFFFFF;
|
||||
void setLoopDependency(int d) { dependency = d; }
|
||||
int getLoopDependency() const { return dependency; }
|
||||
|
||||
protected:
|
||||
TIntermNode* body; // code to loop over
|
||||
TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
|
||||
TIntermTyped* terminal; // exists for for-loops
|
||||
bool first; // true for while and for, not for do-while
|
||||
TLoopControl control; // loop control hint
|
||||
bool unroll; // true if unroll requested
|
||||
bool dontUnroll; // true if request to not unroll
|
||||
unsigned int dependency; // loop dependency hint; 0 means not set or unknown
|
||||
};
|
||||
|
||||
//
|
||||
@ -1343,22 +1335,29 @@ protected:
|
||||
class TIntermSelection : public TIntermTyped {
|
||||
public:
|
||||
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
|
||||
TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB), control(ESelectionControlNone) {}
|
||||
TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB),
|
||||
flatten(false), dontFlatten(false) {}
|
||||
TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
|
||||
TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB), control(ESelectionControlNone) {}
|
||||
TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB),
|
||||
flatten(false), dontFlatten(false) {}
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
virtual TIntermTyped* getCondition() const { return condition; }
|
||||
virtual TIntermNode* getTrueBlock() const { return trueBlock; }
|
||||
virtual TIntermNode* getFalseBlock() const { return falseBlock; }
|
||||
virtual TIntermSelection* getAsSelectionNode() { return this; }
|
||||
virtual const TIntermSelection* getAsSelectionNode() const { return this; }
|
||||
void setSelectionControl(TSelectionControl c) { control = c; }
|
||||
TSelectionControl getSelectionControl() const { return control; }
|
||||
|
||||
void setFlatten() { flatten = true; }
|
||||
void setDontFlatten() { dontFlatten = true; }
|
||||
bool getFlatten() const { return flatten; }
|
||||
bool getDontFlatten() const { return dontFlatten; }
|
||||
|
||||
protected:
|
||||
TIntermTyped* condition;
|
||||
TIntermNode* trueBlock;
|
||||
TIntermNode* falseBlock;
|
||||
TSelectionControl control; // selection control hint
|
||||
bool flatten; // true if flatten requested
|
||||
bool dontFlatten; // true if requested to not flatten
|
||||
};
|
||||
|
||||
//
|
||||
@ -1369,18 +1368,24 @@ protected:
|
||||
//
|
||||
class TIntermSwitch : public TIntermNode {
|
||||
public:
|
||||
TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b), control(ESelectionControlNone) { }
|
||||
TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b),
|
||||
flatten(false), dontFlatten(false) {}
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
virtual TIntermNode* getCondition() const { return condition; }
|
||||
virtual TIntermAggregate* getBody() const { return body; }
|
||||
virtual TIntermSwitch* getAsSwitchNode() { return this; }
|
||||
virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
|
||||
void setSelectionControl(TSelectionControl c) { control = c; }
|
||||
TSelectionControl getSelectionControl() const { return control; }
|
||||
|
||||
void setFlatten() { flatten = true; }
|
||||
void setDontFlatten() { dontFlatten = true; }
|
||||
bool getFlatten() const { return flatten; }
|
||||
bool getDontFlatten() const { return dontFlatten; }
|
||||
|
||||
protected:
|
||||
TIntermTyped* condition;
|
||||
TIntermAggregate* body;
|
||||
TSelectionControl control; // selection control hint
|
||||
bool flatten; // true if flatten requested
|
||||
bool dontFlatten; // true if requested to not flatten
|
||||
};
|
||||
|
||||
enum TVisit
|
||||
|
@ -1614,7 +1614,7 @@ TIntermAggregate* TIntermediate::makeAggregate(const TSourceLoc& loc)
|
||||
//
|
||||
// Returns the selection node created.
|
||||
//
|
||||
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc, TSelectionControl control)
|
||||
TIntermSelection* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair nodePair, const TSourceLoc& loc)
|
||||
{
|
||||
//
|
||||
// Don't prune the false path for compile-time constants; it's needed
|
||||
@ -1623,7 +1623,6 @@ TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermNodePair no
|
||||
|
||||
TIntermSelection* node = new TIntermSelection(cond, nodePair.node1, nodePair.node2);
|
||||
node->setLoc(loc);
|
||||
node->setSelectionControl(control);
|
||||
|
||||
return node;
|
||||
}
|
||||
@ -1666,12 +1665,13 @@ TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, const TType& type,
|
||||
//
|
||||
// Returns the selection node created, or nullptr if one could not be.
|
||||
//
|
||||
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc& loc, TSelectionControl control)
|
||||
TIntermTyped* TIntermediate::addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock,
|
||||
const TSourceLoc& loc)
|
||||
{
|
||||
// If it's void, go to the if-then-else selection()
|
||||
if (trueBlock->getBasicType() == EbtVoid && falseBlock->getBasicType() == EbtVoid) {
|
||||
TIntermNodePair pair = { trueBlock, falseBlock };
|
||||
return addSelection(cond, pair, loc, control);
|
||||
return addSelection(cond, pair, loc);
|
||||
}
|
||||
|
||||
//
|
||||
@ -1909,11 +1909,11 @@ const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool
|
||||
//
|
||||
// Create while and do-while loop nodes.
|
||||
//
|
||||
TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control)
|
||||
TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst,
|
||||
const TSourceLoc& loc)
|
||||
{
|
||||
TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
|
||||
node->setLoc(loc);
|
||||
node->setLoopControl(control);
|
||||
|
||||
return node;
|
||||
}
|
||||
@ -1921,11 +1921,11 @@ TIntermLoop* TIntermediate::addLoop(TIntermNode* body, TIntermTyped* test, TInte
|
||||
//
|
||||
// Create a for-loop sequence.
|
||||
//
|
||||
TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TLoopControl control)
|
||||
TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* initializer, TIntermTyped* test,
|
||||
TIntermTyped* terminal, bool testFirst, const TSourceLoc& loc, TIntermLoop*& node)
|
||||
{
|
||||
TIntermLoop* node = new TIntermLoop(body, test, terminal, testFirst);
|
||||
node = new TIntermLoop(body, test, terminal, testFirst);
|
||||
node->setLoc(loc);
|
||||
node->setLoopControl(control);
|
||||
|
||||
// make a sequence of the initializer and statement, but try to reuse the
|
||||
// aggregate already created for whatever is in the initializer, if there is one
|
||||
|
@ -776,7 +776,7 @@ TFunction* TParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunct
|
||||
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.getType().getBasicTypeString().c_str(), "");
|
||||
error(loc, "overloaded functions must have the same return type", function.getName().c_str(), "");
|
||||
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);
|
||||
@ -3103,7 +3103,7 @@ void TParseContext::arrayDimCheck(const TSourceLoc& loc, const TType* type, cons
|
||||
//
|
||||
void TParseContext::arrayDimMerge(TType& type, const TArraySizes* sizes)
|
||||
{
|
||||
if (sizes)
|
||||
if (sizes != nullptr)
|
||||
type.addArrayOuterSizes(*sizes);
|
||||
}
|
||||
|
||||
|
@ -44,13 +44,15 @@
|
||||
#ifndef _PARSER_HELPER_INCLUDED_
|
||||
#define _PARSER_HELPER_INCLUDED_
|
||||
|
||||
#include <cstdarg>
|
||||
#include <functional>
|
||||
|
||||
#include "parseVersions.h"
|
||||
#include "../Include/ShHandle.h"
|
||||
#include "SymbolTable.h"
|
||||
#include "localintermediate.h"
|
||||
#include "Scan.h"
|
||||
#include <cstdarg>
|
||||
#include <functional>
|
||||
#include "attribute.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
@ -409,6 +411,17 @@ public:
|
||||
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
|
||||
|
||||
void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
|
||||
TAttributeType attributeFromName(const TString& name) const;
|
||||
TAttributes* makeAttributes(const TString& identifier) const;
|
||||
TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const;
|
||||
TAttributes* mergeAttributes(TAttributes*, TAttributes*) const;
|
||||
|
||||
// Determine selection control from attributes
|
||||
void handleSelectionAttributes(const TAttributes& attributes, TIntermNode*);
|
||||
void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*);
|
||||
|
||||
// Determine loop control from attributes
|
||||
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
|
||||
|
||||
protected:
|
||||
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "../Include/Types.h"
|
||||
#include "SymbolTable.h"
|
||||
#include "ParseHelper.h"
|
||||
#include "attribute.h"
|
||||
#include "glslang_tab.cpp.h"
|
||||
#include "ScanContext.h"
|
||||
#include "Scan.h"
|
||||
|
@ -188,6 +188,7 @@ void TParseVersions::initializeExtensionBehavior()
|
||||
extensionBehavior[E_GL_EXT_shader_non_constant_global_initializers] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_shader_image_load_formatted] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_post_depth_coverage] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_control_flow_attributes] = EBhDisable;
|
||||
|
||||
// #line and #include
|
||||
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
|
||||
@ -328,6 +329,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
||||
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
||||
"#define GL_EXT_shader_image_load_formatted 1\n"
|
||||
"#define GL_EXT_post_depth_coverage 1\n"
|
||||
"#define GL_EXT_control_flow_attributes 1\n"
|
||||
|
||||
#ifdef AMD_EXTENSIONS
|
||||
"#define GL_AMD_shader_ballot 1\n"
|
||||
|
@ -146,6 +146,7 @@ const char* const E_GL_EXT_shader_image_load_formatted = "GL_EXT_shader_image_lo
|
||||
const char* const E_GL_EXT_device_group = "GL_EXT_device_group";
|
||||
const char* const E_GL_EXT_multiview = "GL_EXT_multiview";
|
||||
const char* const E_GL_EXT_post_depth_coverage = "GL_EXT_post_depth_coverage";
|
||||
const char* const E_GL_EXT_control_flow_attributes = "GL_EXT_control_flow_attributes";
|
||||
|
||||
// Arrays of extensions for the above viewportEXTs duplications
|
||||
|
||||
|
257
3rdparty/glslang/glslang/MachineIndependent/attribute.cpp
vendored
Normal file
257
3rdparty/glslang/glslang/MachineIndependent/attribute.cpp
vendored
Normal file
@ -0,0 +1,257 @@
|
||||
//
|
||||
// Copyright (C) 2017 LunarG, Inc.
|
||||
// Copyright (C) 2018 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of Google, Inc., nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#include "attribute.h"
|
||||
#include "../Include/intermediate.h"
|
||||
#include "ParseHelper.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
// extract integers out of attribute arguments stored in attribute aggregate
|
||||
bool TAttributeArgs::getInt(int& value, int argNum) const
|
||||
{
|
||||
const TConstUnion* intConst = getConstUnion(EbtInt, argNum);
|
||||
|
||||
if (intConst == nullptr)
|
||||
return false;
|
||||
|
||||
value = intConst->getIConst();
|
||||
return true;
|
||||
}
|
||||
|
||||
// extract strings out of attribute arguments stored in attribute aggregate.
|
||||
// convert to lower case if converToLower is true (for case-insensitive compare convenience)
|
||||
bool TAttributeArgs::getString(TString& value, int argNum, bool convertToLower) const
|
||||
{
|
||||
const TConstUnion* stringConst = getConstUnion(EbtString, argNum);
|
||||
|
||||
if (stringConst == nullptr)
|
||||
return false;
|
||||
|
||||
value = *stringConst->getSConst();
|
||||
|
||||
// Convenience.
|
||||
if (convertToLower)
|
||||
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// How many arguments were supplied?
|
||||
int TAttributeArgs::size() const
|
||||
{
|
||||
return args == nullptr ? 0 : (int)args->getSequence().size();
|
||||
}
|
||||
|
||||
// Helper to get attribute const union. Returns nullptr on failure.
|
||||
const TConstUnion* TAttributeArgs::getConstUnion(TBasicType basicType, int argNum) const
|
||||
{
|
||||
if (args == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (argNum >= args->getSequence().size())
|
||||
return nullptr;
|
||||
|
||||
const TConstUnion* constVal = &args->getSequence()[argNum]->getAsConstantUnion()->getConstArray()[0];
|
||||
if (constVal == nullptr || constVal->getType() != basicType)
|
||||
return nullptr;
|
||||
|
||||
return constVal;
|
||||
}
|
||||
|
||||
// Implementation of TParseContext parts of attributes
|
||||
TAttributeType TParseContext::attributeFromName(const TString& name) const
|
||||
{
|
||||
if (name == "branch" || name == "dont_flatten")
|
||||
return EatBranch;
|
||||
else if (name == "flatten")
|
||||
return EatFlatten;
|
||||
else if (name == "unroll")
|
||||
return EatUnroll;
|
||||
else if (name == "loop" || name == "dont_unroll")
|
||||
return EatLoop;
|
||||
else if (name == "dependency_infinite")
|
||||
return EatDependencyInfinite;
|
||||
else if (name == "dependency_length")
|
||||
return EatDependencyLength;
|
||||
else
|
||||
return EatNone;
|
||||
}
|
||||
|
||||
// Make an initial leaf for the grammar from a no-argument attribute
|
||||
TAttributes* TParseContext::makeAttributes(const TString& identifier) const
|
||||
{
|
||||
TAttributes *attributes = nullptr;
|
||||
attributes = NewPoolObject(attributes);
|
||||
TAttributeArgs args = { attributeFromName(identifier), nullptr };
|
||||
attributes->push_back(args);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
// Make an initial leaf for the grammar from a one-argument attribute
|
||||
TAttributes* TParseContext::makeAttributes(const TString& identifier, TIntermNode* node) const
|
||||
{
|
||||
TAttributes *attributes = nullptr;
|
||||
attributes = NewPoolObject(attributes);
|
||||
|
||||
// for now, node is always a simple single expression, but other code expects
|
||||
// a list, so make it so
|
||||
TIntermAggregate* agg = intermediate.makeAggregate(node);
|
||||
TAttributeArgs args = { attributeFromName(identifier), agg };
|
||||
attributes->push_back(args);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
// Merge two sets of attributes into a single set.
|
||||
// The second argument is destructively consumed.
|
||||
TAttributes* TParseContext::mergeAttributes(TAttributes* attr1, TAttributes* attr2) const
|
||||
{
|
||||
attr1->splice(attr1->end(), *attr2);
|
||||
return attr1;
|
||||
}
|
||||
|
||||
//
|
||||
// Selection attributes
|
||||
//
|
||||
void TParseContext::handleSelectionAttributes(const TAttributes& attributes, TIntermNode* node)
|
||||
{
|
||||
TIntermSelection* selection = node->getAsSelectionNode();
|
||||
if (selection == nullptr)
|
||||
return;
|
||||
|
||||
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||
if (it->size() > 0) {
|
||||
warn(node->getLoc(), "attribute with arguments not recognized, skipping", "", "");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (it->name) {
|
||||
case EatFlatten:
|
||||
selection->setFlatten();
|
||||
break;
|
||||
case EatBranch:
|
||||
selection->setDontFlatten();
|
||||
break;
|
||||
default:
|
||||
warn(node->getLoc(), "attribute does not apply to a selection", "", "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Switch attributes
|
||||
//
|
||||
void TParseContext::handleSwitchAttributes(const TAttributes& attributes, TIntermNode* node)
|
||||
{
|
||||
TIntermSwitch* selection = node->getAsSwitchNode();
|
||||
if (selection == nullptr)
|
||||
return;
|
||||
|
||||
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||
if (it->size() > 0) {
|
||||
warn(node->getLoc(), "attribute with arguments not recognized, skipping", "", "");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (it->name) {
|
||||
case EatFlatten:
|
||||
selection->setFlatten();
|
||||
break;
|
||||
case EatBranch:
|
||||
selection->setDontFlatten();
|
||||
break;
|
||||
default:
|
||||
warn(node->getLoc(), "attribute does not apply to a switch", "", "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Loop attributes
|
||||
//
|
||||
void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermNode* node)
|
||||
{
|
||||
TIntermLoop* loop = node->getAsLoopNode();
|
||||
if (loop == nullptr) {
|
||||
// the actual loop might be part of a sequence
|
||||
TIntermAggregate* agg = node->getAsAggregate();
|
||||
if (agg == nullptr)
|
||||
return;
|
||||
for (auto it = agg->getSequence().begin(); it != agg->getSequence().end(); ++it) {
|
||||
loop = (*it)->getAsLoopNode();
|
||||
if (loop != nullptr)
|
||||
break;
|
||||
}
|
||||
if (loop == nullptr)
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||
if (it->name != EatDependencyLength && it->size() > 0) {
|
||||
warn(node->getLoc(), "attribute with arguments not recognized, skipping", "", "");
|
||||
continue;
|
||||
}
|
||||
|
||||
int value;
|
||||
switch (it->name) {
|
||||
case EatUnroll:
|
||||
loop->setUnroll();
|
||||
break;
|
||||
case EatLoop:
|
||||
loop->setDontUnroll();
|
||||
break;
|
||||
case EatDependencyInfinite:
|
||||
loop->setLoopDependency(TIntermLoop::dependencyInfinite);
|
||||
break;
|
||||
case EatDependencyLength:
|
||||
if (it->size() == 1 && it->getInt(value)) {
|
||||
if (value <= 0)
|
||||
error(node->getLoc(), "must be positive", "dependency_length", "");
|
||||
loop->setLoopDependency(value);
|
||||
} else
|
||||
warn(node->getLoc(), "expected a single integer argument", "dependency_length", "");
|
||||
break;
|
||||
default:
|
||||
warn(node->getLoc(), "attribute does not apply to a loop", "", "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end namespace glslang
|
102
3rdparty/glslang/glslang/MachineIndependent/attribute.h
vendored
Normal file
102
3rdparty/glslang/glslang/MachineIndependent/attribute.h
vendored
Normal file
@ -0,0 +1,102 @@
|
||||
//
|
||||
// Copyright (C) 2017 LunarG, Inc.
|
||||
// Copyright (C) 2018 Google, Inc.
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions
|
||||
// are met:
|
||||
//
|
||||
// Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
//
|
||||
// Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following
|
||||
// disclaimer in the documentation and/or other materials provided
|
||||
// with the distribution.
|
||||
//
|
||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived
|
||||
// from this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#ifndef _ATTRIBUTE_INCLUDED_
|
||||
#define _ATTRIBUTE_INCLUDED_
|
||||
|
||||
#include "../Include/Common.h"
|
||||
#include "../Include/ConstantUnion.h"
|
||||
|
||||
namespace glslang {
|
||||
|
||||
enum TAttributeType {
|
||||
EatNone,
|
||||
EatAllow_uav_condition,
|
||||
EatBranch,
|
||||
EatCall,
|
||||
EatDomain,
|
||||
EatEarlyDepthStencil,
|
||||
EatFastOpt,
|
||||
EatFlatten,
|
||||
EatForceCase,
|
||||
EatInstance,
|
||||
EatMaxTessFactor,
|
||||
EatNumThreads,
|
||||
EatMaxVertexCount,
|
||||
EatOutputControlPoints,
|
||||
EatOutputTopology,
|
||||
EatPartitioning,
|
||||
EatPatchConstantFunc,
|
||||
EatPatchSize,
|
||||
EatUnroll,
|
||||
EatLoop,
|
||||
EatBinding,
|
||||
EatGlobalBinding,
|
||||
EatLocation,
|
||||
EatInputAttachment,
|
||||
EatBuiltIn,
|
||||
EatPushConstant,
|
||||
EatConstantId,
|
||||
EatDependencyInfinite,
|
||||
EatDependencyLength
|
||||
};
|
||||
|
||||
class TIntermAggregate;
|
||||
|
||||
struct TAttributeArgs {
|
||||
TAttributeType name;
|
||||
const TIntermAggregate* args;
|
||||
|
||||
// Obtain attribute as integer
|
||||
// Return false if it cannot be obtained
|
||||
bool getInt(int& value, int argNum = 0) const;
|
||||
|
||||
// Obtain attribute as string, with optional to-lower transform
|
||||
// Return false if it cannot be obtained
|
||||
bool getString(TString& value, int argNum = 0, bool convertToLower = true) const;
|
||||
|
||||
// How many arguments were provided to the attribute?
|
||||
int size() const;
|
||||
|
||||
protected:
|
||||
const TConstUnion* getConstUnion(TBasicType basicType, int argNum) const;
|
||||
};
|
||||
|
||||
typedef TList<TAttributeArgs> TAttributes;
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // _ATTRIBUTE_INCLUDED_
|
@ -58,6 +58,7 @@ Jutta Degener, 1995
|
||||
#include "SymbolTable.h"
|
||||
#include "ParseHelper.h"
|
||||
#include "../Public/ShaderLang.h"
|
||||
#include "attribute.h"
|
||||
|
||||
using namespace glslang;
|
||||
|
||||
@ -86,6 +87,7 @@ using namespace glslang;
|
||||
TIntermNode* intermNode;
|
||||
glslang::TIntermNodePair nodePair;
|
||||
glslang::TIntermTyped* intermTypedNode;
|
||||
glslang::TAttributes* attributes;
|
||||
};
|
||||
union {
|
||||
glslang::TPublicType type;
|
||||
@ -218,12 +220,12 @@ extern int yylex(YYSTYPE*, TParseContext&);
|
||||
%type <interm.intermNode> translation_unit function_definition
|
||||
%type <interm.intermNode> statement simple_statement
|
||||
%type <interm.intermNode> statement_list switch_statement_list compound_statement
|
||||
%type <interm.intermNode> declaration_statement selection_statement expression_statement
|
||||
%type <interm.intermNode> switch_statement case_label
|
||||
%type <interm.intermNode> declaration_statement selection_statement selection_statement_nonattributed expression_statement
|
||||
%type <interm.intermNode> switch_statement switch_statement_nonattributed case_label
|
||||
%type <interm.intermNode> declaration external_declaration
|
||||
%type <interm.intermNode> for_init_statement compound_statement_no_new_scope
|
||||
%type <interm.nodePair> selection_rest_statement for_rest_statement
|
||||
%type <interm.intermNode> iteration_statement jump_statement statement_no_new_scope statement_scoped
|
||||
%type <interm.intermNode> iteration_statement iteration_statement_nonattributed jump_statement statement_no_new_scope statement_scoped
|
||||
%type <interm> single_declaration init_declarator_list
|
||||
|
||||
%type <interm> parameter_declaration parameter_declarator parameter_type_specifier
|
||||
@ -246,6 +248,8 @@ extern int yylex(YYSTYPE*, TParseContext&);
|
||||
|
||||
%type <interm.identifierList> identifier_list
|
||||
|
||||
%type <interm.attributes> attribute attribute_list single_attribute
|
||||
|
||||
%start translation_unit
|
||||
%%
|
||||
|
||||
@ -898,9 +902,9 @@ parameter_declarator
|
||||
parseContext.arraySizeRequiredCheck($3.loc, *$3.arraySizes);
|
||||
parseContext.reservedErrorCheck($2.loc, *$2.string);
|
||||
|
||||
$1.arraySizes = $3.arraySizes;
|
||||
|
||||
TParameter param = { $2.string, new TType($1)};
|
||||
parseContext.arrayDimMerge(*param.type, $3.arraySizes);
|
||||
|
||||
$$.loc = $2.loc;
|
||||
$$.param = param;
|
||||
}
|
||||
@ -2673,6 +2677,15 @@ expression_statement
|
||||
;
|
||||
|
||||
selection_statement
|
||||
: selection_statement_nonattributed {
|
||||
$$ = $1;
|
||||
}
|
||||
| attribute selection_statement_nonattributed {
|
||||
parseContext.handleSelectionAttributes(*$1, $2);
|
||||
$$ = $2;
|
||||
}
|
||||
|
||||
selection_statement_nonattributed
|
||||
: IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement {
|
||||
parseContext.boolCheck($1.loc, $3);
|
||||
$$ = parseContext.intermediate.addSelection($3, $5, $1.loc);
|
||||
@ -2709,6 +2722,15 @@ condition
|
||||
;
|
||||
|
||||
switch_statement
|
||||
: switch_statement_nonattributed {
|
||||
$$ = $1;
|
||||
}
|
||||
| attribute switch_statement_nonattributed {
|
||||
parseContext.handleSwitchAttributes(*$1, $2);
|
||||
$$ = $2;
|
||||
}
|
||||
|
||||
switch_statement_nonattributed
|
||||
: SWITCH LEFT_PAREN expression RIGHT_PAREN {
|
||||
// start new switch sequence on the switch stack
|
||||
++parseContext.controlFlowNestingLevel;
|
||||
@ -2762,6 +2784,15 @@ case_label
|
||||
;
|
||||
|
||||
iteration_statement
|
||||
: iteration_statement_nonattributed {
|
||||
$$ = $1;
|
||||
}
|
||||
| attribute iteration_statement_nonattributed {
|
||||
parseContext.handleLoopAttributes(*$1, $2);
|
||||
$$ = $2;
|
||||
}
|
||||
|
||||
iteration_statement_nonattributed
|
||||
: WHILE LEFT_PAREN {
|
||||
if (! parseContext.limits.whileLoops)
|
||||
parseContext.error($1.loc, "while loops not available", "limitation", "");
|
||||
@ -2920,4 +2951,26 @@ function_definition
|
||||
}
|
||||
;
|
||||
|
||||
attribute
|
||||
: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET {
|
||||
$$ = $3;
|
||||
parseContext.requireExtensions($1.loc, 1, &E_GL_EXT_control_flow_attributes, "attribute");
|
||||
}
|
||||
|
||||
attribute_list
|
||||
: single_attribute {
|
||||
$$ = $1;
|
||||
}
|
||||
| attribute_list COMMA single_attribute {
|
||||
$$ = parseContext.mergeAttributes($1, $3);
|
||||
}
|
||||
|
||||
single_attribute
|
||||
: IDENTIFIER {
|
||||
$$ = parseContext.makeAttributes(*$1.string);
|
||||
}
|
||||
| IDENTIFIER LEFT_PAREN constant_expression RIGHT_PAREN {
|
||||
$$ = parseContext.makeAttributes(*$1.string, $3);
|
||||
}
|
||||
|
||||
%%
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -348,7 +348,7 @@ extern int yydebug;
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 68 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
||||
#line 69 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
||||
|
||||
struct {
|
||||
glslang::TSourceLoc loc;
|
||||
@ -370,6 +370,7 @@ union YYSTYPE
|
||||
TIntermNode* intermNode;
|
||||
glslang::TIntermNodePair nodePair;
|
||||
glslang::TIntermTyped* intermTypedNode;
|
||||
glslang::TAttributes* attributes;
|
||||
};
|
||||
union {
|
||||
glslang::TPublicType type;
|
||||
@ -382,7 +383,7 @@ union YYSTYPE
|
||||
};
|
||||
} interm;
|
||||
|
||||
#line 386 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
||||
#line 387 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
||||
};
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
|
@ -817,7 +817,13 @@ bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node
|
||||
OutputTreeText(out, node, depth);
|
||||
|
||||
out.debug << "Test condition and select";
|
||||
out.debug << " (" << node->getCompleteString() << ")\n";
|
||||
out.debug << " (" << node->getCompleteString() << ")";
|
||||
|
||||
if (node->getFlatten())
|
||||
out.debug << ": Flatten";
|
||||
if (node->getDontFlatten())
|
||||
out.debug << ": DontFlatten";
|
||||
out.debug << "\n";
|
||||
|
||||
++depth;
|
||||
|
||||
@ -979,7 +985,17 @@ bool TOutputTraverser::visitLoop(TVisit /* visit */, TIntermLoop* node)
|
||||
out.debug << "Loop with condition ";
|
||||
if (! node->testFirst())
|
||||
out.debug << "not ";
|
||||
out.debug << "tested first\n";
|
||||
out.debug << "tested first";
|
||||
|
||||
if (node->getUnroll())
|
||||
out.debug << ": Unroll";
|
||||
if (node->getDontUnroll())
|
||||
out.debug << ": DontUnroll";
|
||||
if (node->getLoopDependency()) {
|
||||
out.debug << ": Dependency ";
|
||||
out.debug << node->getLoopDependency();
|
||||
}
|
||||
out.debug << "\n";
|
||||
|
||||
++depth;
|
||||
|
||||
@ -1040,7 +1056,13 @@ bool TOutputTraverser::visitSwitch(TVisit /* visit */, TIntermSwitch* node)
|
||||
TInfoSink& out = infoSink;
|
||||
|
||||
OutputTreeText(out, node, depth);
|
||||
out.debug << "switch\n";
|
||||
out.debug << "switch";
|
||||
|
||||
if (node->getFlatten())
|
||||
out.debug << ": Flatten";
|
||||
if (node->getDontFlatten())
|
||||
out.debug << ": DontFlatten";
|
||||
out.debug << "\n";
|
||||
|
||||
OutputTreeText(out, node, depth);
|
||||
out.debug << "condition\n";
|
||||
|
@ -420,8 +420,8 @@ public:
|
||||
TIntermAggregate* makeAggregate(const TSourceLoc&);
|
||||
TIntermTyped* setAggregateOperator(TIntermNode*, TOperator, const TType& type, TSourceLoc);
|
||||
bool areAllChildConst(TIntermAggregate* aggrNode);
|
||||
TIntermTyped* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&, TSelectionControl = ESelectionControlNone);
|
||||
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&, TSelectionControl = ESelectionControlNone);
|
||||
TIntermSelection* addSelection(TIntermTyped* cond, TIntermNodePair code, const TSourceLoc&);
|
||||
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, const TSourceLoc&);
|
||||
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, const TSourceLoc&);
|
||||
TIntermTyped* addMethod(TIntermTyped*, const TType&, const TString*, const TSourceLoc&);
|
||||
TIntermConstantUnion* addConstantUnion(const TConstUnionArray&, const TType&, const TSourceLoc&, bool literal = false) const;
|
||||
@ -439,8 +439,9 @@ public:
|
||||
TIntermConstantUnion* addConstantUnion(const TString*, const TSourceLoc&, bool literal = false) const;
|
||||
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) const;
|
||||
bool parseConstTree(TIntermNode*, TConstUnionArray, TOperator, const TType&, bool singleConstantParam = false);
|
||||
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&, TLoopControl = ELoopControlNone);
|
||||
TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&, TLoopControl = ELoopControlNone);
|
||||
TIntermLoop* addLoop(TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, const TSourceLoc&);
|
||||
TIntermAggregate* addForLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst,
|
||||
const TSourceLoc&, TIntermLoop*&);
|
||||
TIntermBranch* addBranch(TOperator, const TSourceLoc&);
|
||||
TIntermBranch* addBranch(TOperator, TIntermTyped*, const TSourceLoc&);
|
||||
template<typename selectorType> TIntermTyped* addSwizzle(TSwizzleSelectors<selectorType>&, const TSourceLoc&);
|
||||
|
3
3rdparty/glslang/glslang/Public/ShaderLang.h
vendored
3
3rdparty/glslang/glslang/Public/ShaderLang.h
vendored
@ -119,7 +119,8 @@ typedef enum {
|
||||
|
||||
typedef enum {
|
||||
EShTargetNone,
|
||||
EshTargetSpv,
|
||||
EShTargetSpv, // preferred spelling
|
||||
EshTargetSpv = EShTargetSpv, // legacy spelling
|
||||
} EShTargetLanguage;
|
||||
|
||||
struct TInputLanguage {
|
||||
|
2
3rdparty/glslang/gtests/Hlsl.FromFile.cpp
vendored
2
3rdparty/glslang/gtests/Hlsl.FromFile.cpp
vendored
@ -247,7 +247,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||
{"hlsl.matrixindex.frag", "main"},
|
||||
{"hlsl.nonstaticMemberFunction.frag", "main"},
|
||||
{"hlsl.numericsuffixes.frag", "main"},
|
||||
{"hlsl.numthreads.comp", "main_aux1"},
|
||||
{"hlsl.numthreads.comp", "main_aux2"},
|
||||
{"hlsl.overload.frag", "PixelShaderFunction"},
|
||||
{"hlsl.opaque-type-bug.frag", "main"},
|
||||
{"hlsl.params.default.frag", "main"},
|
||||
|
1
3rdparty/glslang/gtests/Spv.FromFile.cpp
vendored
1
3rdparty/glslang/gtests/Spv.FromFile.cpp
vendored
@ -235,6 +235,7 @@ INSTANTIATE_TEST_CASE_P(
|
||||
"spv.branch-return.vert",
|
||||
"spv.builtInXFB.vert",
|
||||
"spv.conditionalDiscard.frag",
|
||||
"spv.controlFlowAttributes.frag",
|
||||
"spv.conversion.frag",
|
||||
"spv.dataOut.frag",
|
||||
"spv.dataOutIndirect.frag",
|
||||
|
142
3rdparty/glslang/hlsl/hlslAttributes.cpp
vendored
142
3rdparty/glslang/hlsl/hlslAttributes.cpp
vendored
@ -34,157 +34,73 @@
|
||||
//
|
||||
|
||||
#include "hlslAttributes.h"
|
||||
#include <cstdlib>
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
#include "hlslParseHelper.h"
|
||||
|
||||
namespace glslang {
|
||||
// Map the given string to an attribute enum from TAttributeType,
|
||||
// or EatNone if invalid.
|
||||
TAttributeType TAttributeMap::attributeFromName(const TString& nameSpace, const TString& name)
|
||||
TAttributeType HlslParseContext::attributeFromName(const TString& nameSpace, const TString& name) const
|
||||
{
|
||||
// These are case insensitive.
|
||||
TString lowername(name);
|
||||
std::transform(lowername.begin(), lowername.end(), lowername.begin(), ::tolower);
|
||||
TString lowernameSpace(nameSpace);
|
||||
std::transform(lowernameSpace.begin(), lowernameSpace.end(), lowernameSpace.begin(), ::tolower);
|
||||
|
||||
// handle names within a namespace
|
||||
|
||||
if (lowernameSpace == "vk") {
|
||||
if (lowername == "input_attachment_index")
|
||||
if (nameSpace == "vk") {
|
||||
if (name == "input_attachment_index")
|
||||
return EatInputAttachment;
|
||||
else if (lowername == "location")
|
||||
else if (name == "location")
|
||||
return EatLocation;
|
||||
else if (lowername == "binding")
|
||||
else if (name == "binding")
|
||||
return EatBinding;
|
||||
else if (lowername == "global_cbuffer_binding")
|
||||
else if (name == "global_cbuffer_binding")
|
||||
return EatGlobalBinding;
|
||||
else if (lowername == "builtin")
|
||||
else if (name == "builtin")
|
||||
return EatBuiltIn;
|
||||
else if (lowername == "constant_id")
|
||||
else if (name == "constant_id")
|
||||
return EatConstantId;
|
||||
else if (lowername == "push_constant")
|
||||
else if (name == "push_constant")
|
||||
return EatPushConstant;
|
||||
} else if (lowernameSpace.size() > 0)
|
||||
} else if (nameSpace.size() > 0)
|
||||
return EatNone;
|
||||
|
||||
// handle names with no namespace
|
||||
|
||||
if (lowername == "allow_uav_condition")
|
||||
if (name == "allow_uav_condition")
|
||||
return EatAllow_uav_condition;
|
||||
else if (lowername == "branch")
|
||||
else if (name == "branch")
|
||||
return EatBranch;
|
||||
else if (lowername == "call")
|
||||
else if (name == "call")
|
||||
return EatCall;
|
||||
else if (lowername == "domain")
|
||||
else if (name == "domain")
|
||||
return EatDomain;
|
||||
else if (lowername == "earlydepthstencil")
|
||||
else if (name == "earlydepthstencil")
|
||||
return EatEarlyDepthStencil;
|
||||
else if (lowername == "fastopt")
|
||||
else if (name == "fastopt")
|
||||
return EatFastOpt;
|
||||
else if (lowername == "flatten")
|
||||
else if (name == "flatten")
|
||||
return EatFlatten;
|
||||
else if (lowername == "forcecase")
|
||||
else if (name == "forcecase")
|
||||
return EatForceCase;
|
||||
else if (lowername == "instance")
|
||||
else if (name == "instance")
|
||||
return EatInstance;
|
||||
else if (lowername == "maxtessfactor")
|
||||
else if (name == "maxtessfactor")
|
||||
return EatMaxTessFactor;
|
||||
else if (lowername == "maxvertexcount")
|
||||
else if (name == "maxvertexcount")
|
||||
return EatMaxVertexCount;
|
||||
else if (lowername == "numthreads")
|
||||
else if (name == "numthreads")
|
||||
return EatNumThreads;
|
||||
else if (lowername == "outputcontrolpoints")
|
||||
else if (name == "outputcontrolpoints")
|
||||
return EatOutputControlPoints;
|
||||
else if (lowername == "outputtopology")
|
||||
else if (name == "outputtopology")
|
||||
return EatOutputTopology;
|
||||
else if (lowername == "partitioning")
|
||||
else if (name == "partitioning")
|
||||
return EatPartitioning;
|
||||
else if (lowername == "patchconstantfunc")
|
||||
else if (name == "patchconstantfunc")
|
||||
return EatPatchConstantFunc;
|
||||
else if (lowername == "unroll")
|
||||
else if (name == "unroll")
|
||||
return EatUnroll;
|
||||
else if (lowername == "loop")
|
||||
else if (name == "loop")
|
||||
return EatLoop;
|
||||
else
|
||||
return EatNone;
|
||||
}
|
||||
|
||||
// Look up entry, inserting if it's not there, and if name is a valid attribute name
|
||||
// as known by attributeFromName.
|
||||
TAttributeType TAttributeMap::setAttribute(const TString& nameSpace, const TString* name, TIntermAggregate* value)
|
||||
{
|
||||
if (name == nullptr)
|
||||
return EatNone;
|
||||
|
||||
const TAttributeType attr = attributeFromName(nameSpace, *name);
|
||||
|
||||
if (attr != EatNone)
|
||||
attributes[attr] = value;
|
||||
|
||||
return attr;
|
||||
}
|
||||
|
||||
// Look up entry (const version), and return aggregate node. This cannot change the map.
|
||||
const TIntermAggregate* TAttributeMap::operator[](TAttributeType attr) const
|
||||
{
|
||||
const auto entry = attributes.find(attr);
|
||||
|
||||
return (entry == attributes.end()) ? nullptr : entry->second;
|
||||
}
|
||||
|
||||
// True if entry exists in map (even if value is nullptr)
|
||||
bool TAttributeMap::contains(TAttributeType attr) const
|
||||
{
|
||||
return attributes.find(attr) != attributes.end();
|
||||
}
|
||||
|
||||
// extract integers out of attribute arguments stored in attribute aggregate
|
||||
bool TAttributeMap::getInt(TAttributeType attr, int& value, int argNum) const
|
||||
{
|
||||
const TConstUnion* intConst = getConstUnion(attr, EbtInt, argNum);
|
||||
|
||||
if (intConst == nullptr)
|
||||
return false;
|
||||
|
||||
value = intConst->getIConst();
|
||||
return true;
|
||||
};
|
||||
|
||||
// extract strings out of attribute arguments stored in attribute aggregate.
|
||||
// convert to lower case if converToLower is true (for case-insensitive compare convenience)
|
||||
bool TAttributeMap::getString(TAttributeType attr, TString& value, int argNum, bool convertToLower) const
|
||||
{
|
||||
const TConstUnion* stringConst = getConstUnion(attr, EbtString, argNum);
|
||||
|
||||
if (stringConst == nullptr)
|
||||
return false;
|
||||
|
||||
value = *stringConst->getSConst();
|
||||
|
||||
// Convenience.
|
||||
if (convertToLower)
|
||||
std::transform(value.begin(), value.end(), value.begin(), ::tolower);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// Helper to get attribute const union. Returns nullptr on failure.
|
||||
const TConstUnion* TAttributeMap::getConstUnion(TAttributeType attr, TBasicType basicType, int argNum) const
|
||||
{
|
||||
const TIntermAggregate* attrAgg = (*this)[attr];
|
||||
if (attrAgg == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (argNum >= int(attrAgg->getSequence().size()))
|
||||
return nullptr;
|
||||
|
||||
const TConstUnion* constVal = &attrAgg->getSequence()[argNum]->getAsConstantUnion()->getConstArray()[0];
|
||||
if (constVal == nullptr || constVal->getType() != basicType)
|
||||
return nullptr;
|
||||
|
||||
return constVal;
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
||||
|
79
3rdparty/glslang/hlsl/hlslAttributes.h
vendored
79
3rdparty/glslang/hlsl/hlslAttributes.h
vendored
@ -38,93 +38,22 @@
|
||||
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
|
||||
#include "../glslang/MachineIndependent/attribute.h"
|
||||
#include "../glslang/MachineIndependent/SymbolTable.h"
|
||||
#include "hlslScanContext.h"
|
||||
#include "../glslang/Include/Common.h"
|
||||
|
||||
namespace glslang {
|
||||
enum TAttributeType {
|
||||
EatNone,
|
||||
EatAllow_uav_condition,
|
||||
EatBranch,
|
||||
EatCall,
|
||||
EatDomain,
|
||||
EatEarlyDepthStencil,
|
||||
EatFastOpt,
|
||||
EatFlatten,
|
||||
EatForceCase,
|
||||
EatInstance,
|
||||
EatMaxTessFactor,
|
||||
EatNumThreads,
|
||||
EatMaxVertexCount,
|
||||
EatOutputControlPoints,
|
||||
EatOutputTopology,
|
||||
EatPartitioning,
|
||||
EatPatchConstantFunc,
|
||||
EatPatchSize,
|
||||
EatUnroll,
|
||||
EatLoop,
|
||||
EatBinding,
|
||||
EatGlobalBinding,
|
||||
EatLocation,
|
||||
EatInputAttachment,
|
||||
EatBuiltIn,
|
||||
EatPushConstant,
|
||||
EatConstantId
|
||||
};
|
||||
}
|
||||
|
||||
namespace std {
|
||||
// Allow use of TAttributeType enum in hash_map without calling code having to cast.
|
||||
template <> struct hash<glslang::TAttributeType> {
|
||||
std::size_t operator()(glslang::TAttributeType attr) const {
|
||||
return std::hash<int>()(int(attr));
|
||||
}
|
||||
};
|
||||
} // end namespace std
|
||||
|
||||
namespace glslang {
|
||||
class TIntermAggregate;
|
||||
|
||||
class TAttributeMap {
|
||||
public:
|
||||
int size() const { return (int)attributes.size(); }
|
||||
|
||||
// Search for and potentially add the attribute into the map. Return the
|
||||
// attribute type enum for it, if found, else EatNone.
|
||||
TAttributeType setAttribute(const TString& nameSpace, const TString* name, TIntermAggregate* value);
|
||||
|
||||
// Const lookup: search for (but do not modify) the attribute in the map.
|
||||
const TIntermAggregate* operator[](TAttributeType) const;
|
||||
|
||||
// True if entry exists in map (even if value is nullptr)
|
||||
bool contains(TAttributeType) const;
|
||||
|
||||
// Obtain attribute as integer
|
||||
bool getInt(TAttributeType attr, int& value, int argNum = 0) const;
|
||||
|
||||
// Obtain attribute as string, with optional to-lower transform
|
||||
bool getString(TAttributeType attr, TString& value, int argNum = 0, bool convertToLower = true) const;
|
||||
|
||||
protected:
|
||||
// Helper to get attribute const union
|
||||
const TConstUnion* getConstUnion(TAttributeType attr, TBasicType, int argNum) const;
|
||||
|
||||
// Find an attribute enum given its name.
|
||||
static TAttributeType attributeFromName(const TString& nameSpace, const TString& name);
|
||||
|
||||
std::unordered_map<TAttributeType, TIntermAggregate*> attributes;
|
||||
};
|
||||
|
||||
class TFunctionDeclarator {
|
||||
public:
|
||||
TFunctionDeclarator() : function(nullptr), body(nullptr) { }
|
||||
TSourceLoc loc;
|
||||
TFunction* function;
|
||||
TAttributeMap attributes;
|
||||
TAttributes attributes;
|
||||
TVector<HlslToken>* body;
|
||||
};
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
|
||||
#endif // HLSLATTRIBUTES_H_
|
||||
|
91
3rdparty/glslang/hlsl/hlslGrammar.cpp
vendored
91
3rdparty/glslang/hlsl/hlslGrammar.cpp
vendored
@ -396,6 +396,9 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
|
||||
if (peekTokenClass(EHTokLeftParen)) {
|
||||
// looks like function parameters
|
||||
|
||||
// merge in the attributes into the return type
|
||||
parseContext.transferTypeAttributes(token.loc, declarator.attributes, declaredType, true);
|
||||
|
||||
// Potentially rename shader entry point function. No-op most of the time.
|
||||
parseContext.renameShaderFunction(fullName);
|
||||
|
||||
@ -423,7 +426,13 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
|
||||
parseContext.handleFunctionDeclarator(declarator.loc, *declarator.function, true);
|
||||
}
|
||||
} else {
|
||||
// A variable declaration. Fix the storage qualifier if it's a global.
|
||||
// A variable declaration.
|
||||
|
||||
// merge in the attributes, the first time around, into the shared type
|
||||
if (! declarator_list)
|
||||
parseContext.transferTypeAttributes(token.loc, declarator.attributes, declaredType);
|
||||
|
||||
// Fix the storage qualifier if it's a global.
|
||||
if (declaredType.getQualifier().storage == EvqTemporary && parseContext.symbolTable.atGlobalLevel())
|
||||
declaredType.getQualifier().storage = EvqUniform;
|
||||
|
||||
@ -536,13 +545,16 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& nodeList)
|
||||
bool HlslGrammar::acceptControlDeclaration(TIntermNode*& node)
|
||||
{
|
||||
node = nullptr;
|
||||
TAttributeMap attributes;
|
||||
TAttributes attributes;
|
||||
|
||||
// fully_specified_type
|
||||
TType type;
|
||||
if (! acceptFullySpecifiedType(type, attributes))
|
||||
return false;
|
||||
|
||||
if (attributes.size() > 0)
|
||||
parseContext.warn(token.loc, "attributes don't apply to control declaration", "", "");
|
||||
|
||||
// filter out type casts
|
||||
if (peekTokenClass(EHTokLeftParen)) {
|
||||
recedeToken();
|
||||
@ -578,12 +590,12 @@ bool HlslGrammar::acceptControlDeclaration(TIntermNode*& node)
|
||||
// : type_specifier
|
||||
// | type_qualifier type_specifier
|
||||
//
|
||||
bool HlslGrammar::acceptFullySpecifiedType(TType& type, const TAttributeMap& attributes)
|
||||
bool HlslGrammar::acceptFullySpecifiedType(TType& type, const TAttributes& attributes)
|
||||
{
|
||||
TIntermNode* nodeList = nullptr;
|
||||
return acceptFullySpecifiedType(type, nodeList, attributes);
|
||||
}
|
||||
bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList, const TAttributeMap& attributes, bool forbidDeclarators)
|
||||
bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList, const TAttributes& attributes, bool forbidDeclarators)
|
||||
{
|
||||
// type_qualifier
|
||||
TQualifier qualifier;
|
||||
@ -608,7 +620,7 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList,
|
||||
parseContext.mergeQualifiers(type.getQualifier(), qualifier);
|
||||
|
||||
// merge in the attributes
|
||||
parseContext.transferTypeAttributes(attributes, type);
|
||||
parseContext.transferTypeAttributes(token.loc, attributes, type);
|
||||
|
||||
// further, it can create an anonymous instance of the block
|
||||
// (cbuffer and tbuffer don't consume the next identifier, and
|
||||
@ -633,9 +645,6 @@ bool HlslGrammar::acceptFullySpecifiedType(TType& type, TIntermNode*& nodeList,
|
||||
qualifier.builtIn = type.getQualifier().builtIn;
|
||||
|
||||
type.getQualifier() = qualifier;
|
||||
|
||||
// merge in the attributes
|
||||
parseContext.transferTypeAttributes(attributes, type);
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -2335,7 +2344,7 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*
|
||||
// struct_declaration
|
||||
|
||||
// attributes
|
||||
TAttributeMap attributes;
|
||||
TAttributes attributes;
|
||||
acceptAttributes(attributes);
|
||||
|
||||
bool declarator_list = false;
|
||||
@ -2346,6 +2355,9 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList, TIntermNode*
|
||||
expected("member type");
|
||||
return false;
|
||||
}
|
||||
|
||||
// merge in the attributes
|
||||
parseContext.transferTypeAttributes(token.loc, attributes, memberType);
|
||||
|
||||
// struct_declarator COMMA struct_declarator ...
|
||||
bool functionDefinitionAccepted = false;
|
||||
@ -2542,7 +2554,7 @@ bool HlslGrammar::acceptDefaultParameterDeclaration(const TType& type, TIntermTy
|
||||
bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
|
||||
{
|
||||
// attributes
|
||||
TAttributeMap attributes;
|
||||
TAttributes attributes;
|
||||
acceptAttributes(attributes);
|
||||
|
||||
// fully_specified_type
|
||||
@ -2550,6 +2562,9 @@ bool HlslGrammar::acceptParameterDeclaration(TFunction& function)
|
||||
if (! acceptFullySpecifiedType(*type, attributes))
|
||||
return false;
|
||||
|
||||
// merge in the attributes
|
||||
parseContext.transferTypeAttributes(token.loc, attributes, *type);
|
||||
|
||||
// identifier
|
||||
HlslToken idToken;
|
||||
acceptIdentifier(idToken);
|
||||
@ -3386,7 +3401,7 @@ bool HlslGrammar::acceptStatement(TIntermNode*& statement)
|
||||
statement = nullptr;
|
||||
|
||||
// attributes
|
||||
TAttributeMap attributes;
|
||||
TAttributes attributes;
|
||||
acceptAttributes(attributes);
|
||||
|
||||
// attributed_statement
|
||||
@ -3458,7 +3473,7 @@ bool HlslGrammar::acceptStatement(TIntermNode*& statement)
|
||||
// | PATCHCONSTANTFUNC
|
||||
// | NUMTHREADS LEFT_PAREN x_size, y_size,z z_size RIGHT_PAREN
|
||||
//
|
||||
void HlslGrammar::acceptAttributes(TAttributeMap& attributes)
|
||||
void HlslGrammar::acceptAttributes(TAttributes& attributes)
|
||||
{
|
||||
// For now, accept the [ XXX(X) ] syntax, but drop all but
|
||||
// numthreads, which is used to set the CS local size.
|
||||
@ -3529,9 +3544,16 @@ void HlslGrammar::acceptAttributes(TAttributeMap& attributes)
|
||||
return;
|
||||
}
|
||||
|
||||
// Add any values we found into the attribute map. This accepts
|
||||
// (and ignores) values not mapping to a known TAttributeType;
|
||||
attributes.setAttribute(nameSpace, attributeToken.string, expressions);
|
||||
// Add any values we found into the attribute map.
|
||||
if (attributeToken.string != nullptr) {
|
||||
TAttributeType attributeType = parseContext.attributeFromName(nameSpace, *attributeToken.string);
|
||||
if (attributeType == EatNone)
|
||||
parseContext.warn(attributeToken.loc, "unrecognized attribute", attributeToken.string->c_str(), "");
|
||||
else {
|
||||
TAttributeArgs attributeArgs = { attributeType, expressions };
|
||||
attributes.push_back(attributeArgs);
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
||||
@ -3539,12 +3561,10 @@ void HlslGrammar::acceptAttributes(TAttributeMap& attributes)
|
||||
// : IF LEFT_PAREN expression RIGHT_PAREN statement
|
||||
// : IF LEFT_PAREN expression RIGHT_PAREN statement ELSE statement
|
||||
//
|
||||
bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement, const TAttributeMap& attributes)
|
||||
bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement, const TAttributes& attributes)
|
||||
{
|
||||
TSourceLoc loc = token.loc;
|
||||
|
||||
const TSelectionControl control = parseContext.handleSelectionControl(attributes);
|
||||
|
||||
// IF
|
||||
if (! acceptTokenClass(EHTokIf))
|
||||
return false;
|
||||
@ -3582,7 +3602,9 @@ bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement, const TAttri
|
||||
}
|
||||
|
||||
// Put the pieces together
|
||||
statement = intermediate.addSelection(condition, thenElse, loc, control);
|
||||
statement = intermediate.addSelection(condition, thenElse, loc);
|
||||
parseContext.handleSelectionAttributes(loc, statement->getAsSelectionNode(), attributes);
|
||||
|
||||
parseContext.popScope();
|
||||
--parseContext.controlFlowNestingLevel;
|
||||
|
||||
@ -3592,13 +3614,11 @@ bool HlslGrammar::acceptSelectionStatement(TIntermNode*& statement, const TAttri
|
||||
// switch_statement
|
||||
// : SWITCH LEFT_PAREN expression RIGHT_PAREN compound_statement
|
||||
//
|
||||
bool HlslGrammar::acceptSwitchStatement(TIntermNode*& statement, const TAttributeMap& attributes)
|
||||
bool HlslGrammar::acceptSwitchStatement(TIntermNode*& statement, const TAttributes& attributes)
|
||||
{
|
||||
// SWITCH
|
||||
TSourceLoc loc = token.loc;
|
||||
|
||||
const TSelectionControl control = parseContext.handleSelectionControl(attributes);
|
||||
|
||||
if (! acceptTokenClass(EHTokSwitch))
|
||||
return false;
|
||||
|
||||
@ -3618,7 +3638,8 @@ bool HlslGrammar::acceptSwitchStatement(TIntermNode*& statement, const TAttribut
|
||||
--parseContext.controlFlowNestingLevel;
|
||||
|
||||
if (statementOkay)
|
||||
statement = parseContext.addSwitch(loc, switchExpression, statement ? statement->getAsAggregate() : nullptr, control);
|
||||
statement = parseContext.addSwitch(loc, switchExpression, statement ? statement->getAsAggregate() : nullptr,
|
||||
attributes);
|
||||
|
||||
parseContext.popSwitchSequence();
|
||||
parseContext.popScope();
|
||||
@ -3632,7 +3653,7 @@ bool HlslGrammar::acceptSwitchStatement(TIntermNode*& statement, const TAttribut
|
||||
// | FOR LEFT_PAREN for_init_statement for_rest_statement RIGHT_PAREN statement
|
||||
//
|
||||
// Non-speculative, only call if it needs to be found; WHILE or DO or FOR already seen.
|
||||
bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttributeMap& attributes)
|
||||
bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttributes& attributes)
|
||||
{
|
||||
TSourceLoc loc = token.loc;
|
||||
TIntermTyped* condition = nullptr;
|
||||
@ -3642,9 +3663,8 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttri
|
||||
|
||||
// WHILE or DO or FOR
|
||||
advanceToken();
|
||||
|
||||
const TLoopControl control = parseContext.handleLoopControl(attributes);
|
||||
|
||||
TIntermLoop* loopNode = nullptr;
|
||||
switch (loop) {
|
||||
case EHTokWhile:
|
||||
// so that something declared in the condition is scoped to the lifetime
|
||||
@ -3670,9 +3690,9 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttri
|
||||
parseContext.popScope();
|
||||
--parseContext.controlFlowNestingLevel;
|
||||
|
||||
statement = intermediate.addLoop(statement, condition, nullptr, true, loc, control);
|
||||
|
||||
return true;
|
||||
loopNode = intermediate.addLoop(statement, condition, nullptr, true, loc);
|
||||
statement = loopNode;
|
||||
break;
|
||||
|
||||
case EHTokDo:
|
||||
parseContext.nestLooping(); // this only needs to work right if no errors
|
||||
@ -3703,9 +3723,9 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttri
|
||||
parseContext.unnestLooping();
|
||||
--parseContext.controlFlowNestingLevel;
|
||||
|
||||
statement = intermediate.addLoop(statement, condition, 0, false, loc, control);
|
||||
|
||||
return true;
|
||||
loopNode = intermediate.addLoop(statement, condition, 0, false, loc);
|
||||
statement = loopNode;
|
||||
break;
|
||||
|
||||
case EHTokFor:
|
||||
{
|
||||
@ -3747,18 +3767,21 @@ bool HlslGrammar::acceptIterationStatement(TIntermNode*& statement, const TAttri
|
||||
return false;
|
||||
}
|
||||
|
||||
statement = intermediate.addForLoop(statement, initNode, condition, iterator, true, loc, control);
|
||||
statement = intermediate.addForLoop(statement, initNode, condition, iterator, true, loc, loopNode);
|
||||
|
||||
parseContext.popScope();
|
||||
parseContext.unnestLooping();
|
||||
--parseContext.controlFlowNestingLevel;
|
||||
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
parseContext.handleLoopAttributes(loc, loopNode, attributes);
|
||||
return true;
|
||||
}
|
||||
|
||||
// jump_statement
|
||||
|
13
3rdparty/glslang/hlsl/hlslGrammar.h
vendored
13
3rdparty/glslang/hlsl/hlslGrammar.h
vendored
@ -43,7 +43,6 @@
|
||||
|
||||
namespace glslang {
|
||||
|
||||
class TAttributeMap;
|
||||
class TFunctionDeclarator;
|
||||
|
||||
// Should just be the grammar aspect of HLSL.
|
||||
@ -71,8 +70,8 @@ namespace glslang {
|
||||
bool acceptControlDeclaration(TIntermNode*& node);
|
||||
bool acceptSamplerDeclarationDX9(TType&);
|
||||
bool acceptSamplerState();
|
||||
bool acceptFullySpecifiedType(TType&, const TAttributeMap&);
|
||||
bool acceptFullySpecifiedType(TType&, TIntermNode*& nodeList, const TAttributeMap&, bool forbidDeclarators = false);
|
||||
bool acceptFullySpecifiedType(TType&, const TAttributes&);
|
||||
bool acceptFullySpecifiedType(TType&, TIntermNode*& nodeList, const TAttributes&, bool forbidDeclarators = false);
|
||||
bool acceptQualifier(TQualifier&);
|
||||
bool acceptLayoutQualifierList(TQualifier&);
|
||||
bool acceptType(TType&);
|
||||
@ -117,10 +116,10 @@ namespace glslang {
|
||||
bool acceptScopedCompoundStatement(TIntermNode*&);
|
||||
bool acceptStatement(TIntermNode*&);
|
||||
bool acceptNestedStatement(TIntermNode*&);
|
||||
void acceptAttributes(TAttributeMap&);
|
||||
bool acceptSelectionStatement(TIntermNode*&, const TAttributeMap&);
|
||||
bool acceptSwitchStatement(TIntermNode*&, const TAttributeMap&);
|
||||
bool acceptIterationStatement(TIntermNode*&, const TAttributeMap&);
|
||||
void acceptAttributes(TAttributes&);
|
||||
bool acceptSelectionStatement(TIntermNode*&, const TAttributes&);
|
||||
bool acceptSwitchStatement(TIntermNode*&, const TAttributes&);
|
||||
bool acceptIterationStatement(TIntermNode*&, const TAttributes&);
|
||||
bool acceptJumpStatement(TIntermNode*&);
|
||||
bool acceptCaseLabel(TIntermNode*&);
|
||||
bool acceptDefaultLabel(TIntermNode*&);
|
||||
|
422
3rdparty/glslang/hlsl/hlslParseHelper.cpp
vendored
422
3rdparty/glslang/hlsl/hlslParseHelper.cpp
vendored
@ -1620,7 +1620,7 @@ void HlslParseContext::addStructBufferHiddenCounterParam(const TSourceLoc& loc,
|
||||
// Returns an aggregate of parameter-symbol nodes.
|
||||
//
|
||||
TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& loc, TFunction& function,
|
||||
const TAttributeMap& attributes,
|
||||
const TAttributes& attributes,
|
||||
TIntermNode*& entryPointTree)
|
||||
{
|
||||
currentCaller = function.getMangledName();
|
||||
@ -1717,189 +1717,217 @@ TIntermAggregate* HlslParseContext::handleFunctionDefinition(const TSourceLoc& l
|
||||
}
|
||||
|
||||
// Handle all [attrib] attribute for the shader entry point
|
||||
void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const TAttributeMap& attributes)
|
||||
void HlslParseContext::handleEntryPointAttributes(const TSourceLoc& loc, const TAttributes& attributes)
|
||||
{
|
||||
// Handle entry-point function attributes
|
||||
const TIntermAggregate* numThreads = attributes[EatNumThreads];
|
||||
if (numThreads != nullptr) {
|
||||
const TIntermSequence& sequence = numThreads->getSequence();
|
||||
|
||||
for (int lid = 0; lid < int(sequence.size()); ++lid)
|
||||
intermediate.setLocalSize(lid, sequence[lid]->getAsConstantUnion()->getConstArray()[0].getIConst());
|
||||
}
|
||||
|
||||
// MaxVertexCount
|
||||
if (attributes.contains(EatMaxVertexCount)) {
|
||||
int maxVertexCount;
|
||||
|
||||
if (! attributes.getInt(EatMaxVertexCount, maxVertexCount)) {
|
||||
error(loc, "invalid maxvertexcount", "", "");
|
||||
} else {
|
||||
if (! intermediate.setVertices(maxVertexCount))
|
||||
error(loc, "cannot change previously set maxvertexcount attribute", "", "");
|
||||
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||
switch (it->name) {
|
||||
case EatNumThreads:
|
||||
{
|
||||
const TIntermSequence& sequence = it->args->getSequence();
|
||||
for (int lid = 0; lid < int(sequence.size()); ++lid)
|
||||
intermediate.setLocalSize(lid, sequence[lid]->getAsConstantUnion()->getConstArray()[0].getIConst());
|
||||
break;
|
||||
}
|
||||
}
|
||||
case EatMaxVertexCount:
|
||||
{
|
||||
int maxVertexCount;
|
||||
|
||||
// Handle [patchconstantfunction("...")]
|
||||
if (attributes.contains(EatPatchConstantFunc)) {
|
||||
TString pcfName;
|
||||
if (! attributes.getString(EatPatchConstantFunc, pcfName, 0, false)) {
|
||||
error(loc, "invalid patch constant function", "", "");
|
||||
} else {
|
||||
patchConstantFunctionName = pcfName;
|
||||
if (! it->getInt(maxVertexCount)) {
|
||||
error(loc, "invalid maxvertexcount", "", "");
|
||||
} else {
|
||||
if (! intermediate.setVertices(maxVertexCount))
|
||||
error(loc, "cannot change previously set maxvertexcount attribute", "", "");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle [domain("...")]
|
||||
if (attributes.contains(EatDomain)) {
|
||||
TString domainStr;
|
||||
if (! attributes.getString(EatDomain, domainStr)) {
|
||||
error(loc, "invalid domain", "", "");
|
||||
} else {
|
||||
TLayoutGeometry domain = ElgNone;
|
||||
|
||||
if (domainStr == "tri") {
|
||||
domain = ElgTriangles;
|
||||
} else if (domainStr == "quad") {
|
||||
domain = ElgQuads;
|
||||
} else if (domainStr == "isoline") {
|
||||
domain = ElgIsolines;
|
||||
case EatPatchConstantFunc:
|
||||
{
|
||||
TString pcfName;
|
||||
if (! it->getString(pcfName, 0, false)) {
|
||||
error(loc, "invalid patch constant function", "", "");
|
||||
} else {
|
||||
error(loc, "unsupported domain type", domainStr.c_str(), "");
|
||||
}
|
||||
|
||||
if (language == EShLangTessEvaluation) {
|
||||
if (! intermediate.setInputPrimitive(domain))
|
||||
error(loc, "cannot change previously set domain", TQualifier::getGeometryString(domain), "");
|
||||
} else {
|
||||
if (! intermediate.setOutputPrimitive(domain))
|
||||
error(loc, "cannot change previously set domain", TQualifier::getGeometryString(domain), "");
|
||||
patchConstantFunctionName = pcfName;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle [outputtopology("...")]
|
||||
if (attributes.contains(EatOutputTopology)) {
|
||||
TString topologyStr;
|
||||
if (! attributes.getString(EatOutputTopology, topologyStr)) {
|
||||
error(loc, "invalid outputtopology", "", "");
|
||||
} else {
|
||||
TVertexOrder vertexOrder = EvoNone;
|
||||
TLayoutGeometry primitive = ElgNone;
|
||||
|
||||
if (topologyStr == "point") {
|
||||
intermediate.setPointMode();
|
||||
} else if (topologyStr == "line") {
|
||||
primitive = ElgIsolines;
|
||||
} else if (topologyStr == "triangle_cw") {
|
||||
vertexOrder = EvoCw;
|
||||
primitive = ElgTriangles;
|
||||
} else if (topologyStr == "triangle_ccw") {
|
||||
vertexOrder = EvoCcw;
|
||||
primitive = ElgTriangles;
|
||||
case EatDomain:
|
||||
{
|
||||
// Handle [domain("...")]
|
||||
TString domainStr;
|
||||
if (! it->getString(domainStr)) {
|
||||
error(loc, "invalid domain", "", "");
|
||||
} else {
|
||||
error(loc, "unsupported outputtopology type", topologyStr.c_str(), "");
|
||||
}
|
||||
TLayoutGeometry domain = ElgNone;
|
||||
|
||||
if (vertexOrder != EvoNone) {
|
||||
if (! intermediate.setVertexOrder(vertexOrder)) {
|
||||
error(loc, "cannot change previously set outputtopology",
|
||||
TQualifier::getVertexOrderString(vertexOrder), "");
|
||||
if (domainStr == "tri") {
|
||||
domain = ElgTriangles;
|
||||
} else if (domainStr == "quad") {
|
||||
domain = ElgQuads;
|
||||
} else if (domainStr == "isoline") {
|
||||
domain = ElgIsolines;
|
||||
} else {
|
||||
error(loc, "unsupported domain type", domainStr.c_str(), "");
|
||||
}
|
||||
|
||||
if (language == EShLangTessEvaluation) {
|
||||
if (! intermediate.setInputPrimitive(domain))
|
||||
error(loc, "cannot change previously set domain", TQualifier::getGeometryString(domain), "");
|
||||
} else {
|
||||
if (! intermediate.setOutputPrimitive(domain))
|
||||
error(loc, "cannot change previously set domain", TQualifier::getGeometryString(domain), "");
|
||||
}
|
||||
}
|
||||
if (primitive != ElgNone)
|
||||
intermediate.setOutputPrimitive(primitive);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle [partitioning("...")]
|
||||
if (attributes.contains(EatPartitioning)) {
|
||||
TString partitionStr;
|
||||
if (! attributes.getString(EatPartitioning, partitionStr)) {
|
||||
error(loc, "invalid partitioning", "", "");
|
||||
} else {
|
||||
TVertexSpacing partitioning = EvsNone;
|
||||
|
||||
if (partitionStr == "integer") {
|
||||
partitioning = EvsEqual;
|
||||
} else if (partitionStr == "fractional_even") {
|
||||
partitioning = EvsFractionalEven;
|
||||
} else if (partitionStr == "fractional_odd") {
|
||||
partitioning = EvsFractionalOdd;
|
||||
//} else if (partition == "pow2") { // TODO: currently nothing to map this to.
|
||||
case EatOutputTopology:
|
||||
{
|
||||
// Handle [outputtopology("...")]
|
||||
TString topologyStr;
|
||||
if (! it->getString(topologyStr)) {
|
||||
error(loc, "invalid outputtopology", "", "");
|
||||
} else {
|
||||
error(loc, "unsupported partitioning type", partitionStr.c_str(), "");
|
||||
}
|
||||
TVertexOrder vertexOrder = EvoNone;
|
||||
TLayoutGeometry primitive = ElgNone;
|
||||
|
||||
if (! intermediate.setVertexSpacing(partitioning))
|
||||
error(loc, "cannot change previously set partitioning",
|
||||
TQualifier::getVertexSpacingString(partitioning), "");
|
||||
if (topologyStr == "point") {
|
||||
intermediate.setPointMode();
|
||||
} else if (topologyStr == "line") {
|
||||
primitive = ElgIsolines;
|
||||
} else if (topologyStr == "triangle_cw") {
|
||||
vertexOrder = EvoCw;
|
||||
primitive = ElgTriangles;
|
||||
} else if (topologyStr == "triangle_ccw") {
|
||||
vertexOrder = EvoCcw;
|
||||
primitive = ElgTriangles;
|
||||
} else {
|
||||
error(loc, "unsupported outputtopology type", topologyStr.c_str(), "");
|
||||
}
|
||||
|
||||
if (vertexOrder != EvoNone) {
|
||||
if (! intermediate.setVertexOrder(vertexOrder)) {
|
||||
error(loc, "cannot change previously set outputtopology",
|
||||
TQualifier::getVertexOrderString(vertexOrder), "");
|
||||
}
|
||||
}
|
||||
if (primitive != ElgNone)
|
||||
intermediate.setOutputPrimitive(primitive);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
case EatPartitioning:
|
||||
{
|
||||
// Handle [partitioning("...")]
|
||||
TString partitionStr;
|
||||
if (! it->getString(partitionStr)) {
|
||||
error(loc, "invalid partitioning", "", "");
|
||||
} else {
|
||||
TVertexSpacing partitioning = EvsNone;
|
||||
|
||||
if (partitionStr == "integer") {
|
||||
partitioning = EvsEqual;
|
||||
} else if (partitionStr == "fractional_even") {
|
||||
partitioning = EvsFractionalEven;
|
||||
} else if (partitionStr == "fractional_odd") {
|
||||
partitioning = EvsFractionalOdd;
|
||||
//} else if (partition == "pow2") { // TODO: currently nothing to map this to.
|
||||
} else {
|
||||
error(loc, "unsupported partitioning type", partitionStr.c_str(), "");
|
||||
}
|
||||
|
||||
// Handle [outputcontrolpoints("...")]
|
||||
if (attributes.contains(EatOutputControlPoints)) {
|
||||
int ctrlPoints;
|
||||
if (! attributes.getInt(EatOutputControlPoints, ctrlPoints)) {
|
||||
error(loc, "invalid outputcontrolpoints", "", "");
|
||||
} else {
|
||||
if (! intermediate.setVertices(ctrlPoints)) {
|
||||
error(loc, "cannot change previously set outputcontrolpoints attribute", "", "");
|
||||
if (! intermediate.setVertexSpacing(partitioning))
|
||||
error(loc, "cannot change previously set partitioning",
|
||||
TQualifier::getVertexSpacingString(partitioning), "");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EatOutputControlPoints:
|
||||
{
|
||||
// Handle [outputcontrolpoints("...")]
|
||||
int ctrlPoints;
|
||||
if (! it->getInt(ctrlPoints)) {
|
||||
error(loc, "invalid outputcontrolpoints", "", "");
|
||||
} else {
|
||||
if (! intermediate.setVertices(ctrlPoints)) {
|
||||
error(loc, "cannot change previously set outputcontrolpoints attribute", "", "");
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EatBuiltIn:
|
||||
case EatLocation:
|
||||
// tolerate these because of dual use of entrypoint and type attributes
|
||||
break;
|
||||
default:
|
||||
warn(loc, "attribute does not apply to entry point", "", "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update the given type with any type-like attribute information in the
|
||||
// attributes.
|
||||
void HlslParseContext::transferTypeAttributes(const TAttributeMap& attributes, TType& type)
|
||||
void HlslParseContext::transferTypeAttributes(const TSourceLoc& loc, const TAttributes& attributes, TType& type,
|
||||
bool allowEntry)
|
||||
{
|
||||
if (attributes.size() == 0)
|
||||
return;
|
||||
|
||||
// location
|
||||
int value;
|
||||
if (attributes.getInt(EatLocation, value))
|
||||
type.getQualifier().layoutLocation = value;
|
||||
|
||||
// binding
|
||||
if (attributes.getInt(EatBinding, value)) {
|
||||
type.getQualifier().layoutBinding = value;
|
||||
type.getQualifier().layoutSet = 0;
|
||||
}
|
||||
|
||||
// set
|
||||
if (attributes.getInt(EatBinding, value, 1))
|
||||
type.getQualifier().layoutSet = value;
|
||||
|
||||
// global cbuffer binding
|
||||
if (attributes.getInt(EatGlobalBinding, value))
|
||||
globalUniformBinding = value;
|
||||
|
||||
// global cbuffer binding
|
||||
if (attributes.getInt(EatGlobalBinding, value, 1))
|
||||
globalUniformSet = value;
|
||||
|
||||
// input attachment
|
||||
if (attributes.getInt(EatInputAttachment, value))
|
||||
type.getQualifier().layoutAttachment = value;
|
||||
|
||||
// PointSize built-in
|
||||
TString builtInString;
|
||||
if (attributes.getString(EatBuiltIn, builtInString, 0, false)) {
|
||||
if (builtInString == "PointSize")
|
||||
type.getQualifier().builtIn = EbvPointSize;
|
||||
}
|
||||
|
||||
// push_constant
|
||||
if (attributes.contains(EatPushConstant))
|
||||
type.getQualifier().layoutPushConstant = true;
|
||||
|
||||
// specialization constant
|
||||
if (attributes.getInt(EatConstantId, value)) {
|
||||
TSourceLoc loc;
|
||||
loc.init();
|
||||
setSpecConstantId(loc, type.getQualifier(), value);
|
||||
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||
switch (it->name) {
|
||||
case EatLocation:
|
||||
// location
|
||||
if (it->getInt(value))
|
||||
type.getQualifier().layoutLocation = value;
|
||||
break;
|
||||
case EatBinding:
|
||||
// binding
|
||||
if (it->getInt(value)) {
|
||||
type.getQualifier().layoutBinding = value;
|
||||
type.getQualifier().layoutSet = 0;
|
||||
}
|
||||
// set
|
||||
if (it->getInt(value, 1))
|
||||
type.getQualifier().layoutSet = value;
|
||||
break;
|
||||
case EatGlobalBinding:
|
||||
// global cbuffer binding
|
||||
if (it->getInt(value))
|
||||
globalUniformBinding = value;
|
||||
// global cbuffer binding
|
||||
if (it->getInt(value, 1))
|
||||
globalUniformSet = value;
|
||||
break;
|
||||
case EatInputAttachment:
|
||||
// input attachment
|
||||
if (it->getInt(value))
|
||||
type.getQualifier().layoutAttachment = value;
|
||||
break;
|
||||
case EatBuiltIn:
|
||||
// PointSize built-in
|
||||
if (it->getString(builtInString, 0, false)) {
|
||||
if (builtInString == "PointSize")
|
||||
type.getQualifier().builtIn = EbvPointSize;
|
||||
}
|
||||
break;
|
||||
case EatPushConstant:
|
||||
// push_constant
|
||||
type.getQualifier().layoutPushConstant = true;
|
||||
break;
|
||||
case EatConstantId:
|
||||
// specialization constant
|
||||
if (it->getInt(value)) {
|
||||
TSourceLoc loc;
|
||||
loc.init();
|
||||
setSpecConstantId(loc, type.getQualifier(), value);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (! allowEntry)
|
||||
warn(loc, "attribute does not apply to a type", "", "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1936,7 +1964,7 @@ void HlslParseContext::transferTypeAttributes(const TAttributeMap& attributes, T
|
||||
// a subtree that creates the entry point.
|
||||
//
|
||||
TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunction& userFunction,
|
||||
const TAttributeMap& attributes)
|
||||
const TAttributes& attributes)
|
||||
{
|
||||
// Return true if this is a tessellation patch constant function input to a domain shader.
|
||||
const auto isDsPcfInput = [this](const TType& type) {
|
||||
@ -8792,29 +8820,75 @@ bool HlslParseContext::handleOutputGeometry(const TSourceLoc& loc, const TLayout
|
||||
}
|
||||
|
||||
//
|
||||
// Selection hints
|
||||
// Selection attributes
|
||||
//
|
||||
TSelectionControl HlslParseContext::handleSelectionControl(const TAttributeMap& attributes) const
|
||||
void HlslParseContext::handleSelectionAttributes(const TSourceLoc& loc, TIntermSelection* selection,
|
||||
const TAttributes& attributes)
|
||||
{
|
||||
if (attributes.contains(EatFlatten))
|
||||
return ESelectionControlFlatten;
|
||||
else if (attributes.contains(EatBranch))
|
||||
return ESelectionControlDontFlatten;
|
||||
else
|
||||
return ESelectionControlNone;
|
||||
if (selection == nullptr)
|
||||
return;
|
||||
|
||||
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||
switch (it->name) {
|
||||
case EatFlatten:
|
||||
selection->setFlatten();
|
||||
break;
|
||||
case EatBranch:
|
||||
selection->setDontFlatten();
|
||||
break;
|
||||
default:
|
||||
warn(loc, "attribute does not apply to a selection", "", "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Loop hints
|
||||
// Switch attributes
|
||||
//
|
||||
TLoopControl HlslParseContext::handleLoopControl(const TAttributeMap& attributes) const
|
||||
void HlslParseContext::handleSwitchAttributes(const TSourceLoc& loc, TIntermSwitch* selection,
|
||||
const TAttributes& attributes)
|
||||
{
|
||||
if (attributes.contains(EatUnroll))
|
||||
return ELoopControlUnroll;
|
||||
else if (attributes.contains(EatLoop))
|
||||
return ELoopControlDontUnroll;
|
||||
else
|
||||
return ELoopControlNone;
|
||||
if (selection == nullptr)
|
||||
return;
|
||||
|
||||
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||
switch (it->name) {
|
||||
case EatFlatten:
|
||||
selection->setFlatten();
|
||||
break;
|
||||
case EatBranch:
|
||||
selection->setDontFlatten();
|
||||
break;
|
||||
default:
|
||||
warn(loc, "attribute does not apply to a switch", "", "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Loop attributes
|
||||
//
|
||||
void HlslParseContext::handleLoopAttributes(const TSourceLoc& loc, TIntermLoop* loop,
|
||||
const TAttributes& attributes)
|
||||
{
|
||||
if (loop == nullptr)
|
||||
return;
|
||||
|
||||
for (auto it = attributes.begin(); it != attributes.end(); ++it) {
|
||||
switch (it->name) {
|
||||
case EatUnroll:
|
||||
loop->setUnroll();
|
||||
break;
|
||||
case EatLoop:
|
||||
loop->setDontUnroll();
|
||||
break;
|
||||
default:
|
||||
warn(loc, "attribute does not apply to a loop", "", "");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
@ -8959,7 +9033,7 @@ void HlslParseContext::wrapupSwitchSubsequence(TIntermAggregate* statements, TIn
|
||||
// into a switch node.
|
||||
//
|
||||
TIntermNode* HlslParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* expression,
|
||||
TIntermAggregate* lastStatements, TSelectionControl control)
|
||||
TIntermAggregate* lastStatements, const TAttributes& attributes)
|
||||
{
|
||||
wrapupSwitchSubsequence(lastStatements, nullptr);
|
||||
|
||||
@ -8986,7 +9060,7 @@ TIntermNode* HlslParseContext::addSwitch(const TSourceLoc& loc, TIntermTyped* ex
|
||||
|
||||
TIntermSwitch* switchNode = new TIntermSwitch(expression, body);
|
||||
switchNode->setLoc(loc);
|
||||
switchNode->setSelectionControl(control);
|
||||
handleSwitchAttributes(loc, switchNode, attributes);
|
||||
|
||||
return switchNode;
|
||||
}
|
||||
|
19
3rdparty/glslang/hlsl/hlslParseHelper.h
vendored
19
3rdparty/glslang/hlsl/hlslParseHelper.h
vendored
@ -38,12 +38,12 @@
|
||||
|
||||
#include "../glslang/MachineIndependent/parseVersions.h"
|
||||
#include "../glslang/MachineIndependent/ParseHelper.h"
|
||||
#include "../glslang/MachineIndependent/attribute.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
namespace glslang {
|
||||
|
||||
class TAttributeMap; // forward declare
|
||||
class TFunctionDeclarator;
|
||||
|
||||
class HlslParseContext : public TParseContextBase {
|
||||
@ -80,10 +80,10 @@ public:
|
||||
bool isBuiltInMethod(const TSourceLoc&, TIntermTyped* base, const TString& field);
|
||||
void assignToInterface(TVariable& variable);
|
||||
void handleFunctionDeclarator(const TSourceLoc&, TFunction& function, bool prototype);
|
||||
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&, const TAttributeMap&, TIntermNode*& entryPointTree);
|
||||
TIntermNode* transformEntryPoint(const TSourceLoc&, TFunction&, const TAttributeMap&);
|
||||
void handleEntryPointAttributes(const TSourceLoc&, const TAttributeMap&);
|
||||
void transferTypeAttributes(const TAttributeMap&, TType&);
|
||||
TIntermAggregate* handleFunctionDefinition(const TSourceLoc&, TFunction&, const TAttributes&, TIntermNode*& entryPointTree);
|
||||
TIntermNode* transformEntryPoint(const TSourceLoc&, TFunction&, const TAttributes&);
|
||||
void handleEntryPointAttributes(const TSourceLoc&, const TAttributes&);
|
||||
void transferTypeAttributes(const TSourceLoc&, const TAttributes&, TType&, bool allowEntry = false);
|
||||
void handleFunctionBody(const TSourceLoc&, TFunction&, TIntermNode* functionBody, TIntermNode*& node);
|
||||
void remapEntryPointIO(TFunction& function, TVariable*& returnValue, TVector<TVariable*>& inputs, TVector<TVariable*>& outputs);
|
||||
void remapNonEntryPointIO(TFunction& function);
|
||||
@ -163,7 +163,7 @@ public:
|
||||
void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&);
|
||||
void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&);
|
||||
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
||||
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body, TSelectionControl control);
|
||||
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body, const TAttributes&);
|
||||
|
||||
void updateImplicitArraySize(const TSourceLoc&, TIntermNode*, int index);
|
||||
|
||||
@ -203,10 +203,11 @@ public:
|
||||
bool handleInputGeometry(const TSourceLoc&, const TLayoutGeometry& geometry);
|
||||
|
||||
// Determine selection control from attributes
|
||||
TSelectionControl handleSelectionControl(const TAttributeMap& attributes) const;
|
||||
void handleSelectionAttributes(const TSourceLoc& loc, TIntermSelection*, const TAttributes& attributes);
|
||||
void handleSwitchAttributes(const TSourceLoc& loc, TIntermSwitch*, const TAttributes& attributes);
|
||||
|
||||
// Determine loop control from attributes
|
||||
TLoopControl handleLoopControl(const TAttributeMap& attributes) const;
|
||||
void handleLoopAttributes(const TSourceLoc& loc, TIntermLoop*, const TAttributes& attributes);
|
||||
|
||||
// Share struct buffer deep types
|
||||
void shareStructBufferType(TType&);
|
||||
@ -217,6 +218,8 @@ public:
|
||||
// Obtain the sampler return type of the given sampler in retType.
|
||||
void getTextureReturnType(const TSampler& sampler, TType& retType) const;
|
||||
|
||||
TAttributeType attributeFromName(const TString& nameSpace, const TString& name) const;
|
||||
|
||||
protected:
|
||||
struct TFlattenData {
|
||||
TFlattenData() : nextBinding(TQualifier::layoutBindingEnd),
|
||||
|
Loading…
x
Reference in New Issue
Block a user