Updated glslang.

This commit is contained in:
Бранимир Караџић
2025-05-10 19:56:39 -07:00
parent 42062ba0b5
commit 8894a9df0f
42 changed files with 16401 additions and 15413 deletions

View File

@@ -65,5 +65,6 @@ static const char* const E_SPV_EXT_replicated_composites = "SPV_EXT_repli
static const char* const E_SPV_KHR_relaxed_extended_instruction = "SPV_KHR_relaxed_extended_instruction";
static const char* const E_SPV_KHR_integer_dot_product = "SPV_KHR_integer_dot_product";
static const char* const E_SPV_NV_cooperative_vector = "SPV_NV_cooperative_vector";
static const char* const E_SPV_KHR_bfloat16 = "SPV_KHR_bfloat16";
#endif // #ifndef GLSLextKHR_H

View File

@@ -27,10 +27,10 @@
#ifndef GLSLextNV_H
#define GLSLextNV_H
enum BuiltIn;
enum Decoration;
enum Op;
enum Capability;
enum class BuiltIn : unsigned;
enum class Decoration : unsigned;
enum class Op : unsigned;
enum class Capability : unsigned;
static const int GLSLextNVVersion = 100;
static const int GLSLextNVRevision = 11;

View File

@@ -27,10 +27,10 @@
#ifndef GLSLextQCOM_H
#define GLSLextQCOM_H
enum BuiltIn;
enum Decoration;
enum Op;
enum Capability;
enum class BuiltIn : unsigned;
enum class Decoration : unsigned;
enum class Op : unsigned;
enum class Capability : unsigned;
static const int GLSLextQCOMVersion = 100;
static const int GLSLextQCOMRevision = 1;

File diff suppressed because it is too large Load Diff

View File

@@ -85,7 +85,7 @@ public:
Id mergeId = mergeInst->getIdOperand(0);
mergeBlock = block->getParent().getParent().getInstruction(mergeId)->getBlock();
delayed_.insert(mergeBlock);
if (mergeInst->getOpCode() == spv::OpLoopMerge) {
if (mergeInst->getOpCode() == spv::Op::OpLoopMerge) {
Id continueId = mergeInst->getIdOperand(1);
continueBlock =
block->getParent().getParent().getInstruction(continueId)->getBlock();

View File

@@ -35,6 +35,7 @@
#include "SPVRemapper.h"
#include "doc.h"
#include "spvUtil.h"
#include <algorithm>
#include <cassert>
@@ -61,13 +62,13 @@ namespace spv {
std::uint32_t offset = 0;
switch (opCode) {
case spv::OpExtInst:
case spv::Op::OpExtInst:
offset += asId(word + 4); break;
default:
break;
}
return opCode * 19 + offset; // 19 = small prime
return ((unsigned)opCode) * 19 + offset; // 19 = small prime
}
spirvbin_t::range_t spirvbin_t::literalRange(spv::Op opCode) const
@@ -75,16 +76,16 @@ namespace spv {
static const int maxCount = 1<<30;
switch (opCode) {
case spv::OpTypeFloat: // fall through...
case spv::OpTypePointer: return range_t(2, 3);
case spv::OpTypeInt: return range_t(2, 4);
case spv::Op::OpTypeFloat: // fall through...
case spv::Op::OpTypePointer: return range_t(2, 3);
case spv::Op::OpTypeInt: return range_t(2, 4);
// TODO: case spv::OpTypeImage:
// TODO: case spv::OpTypeSampledImage:
case spv::OpTypeSampler: return range_t(3, 8);
case spv::OpTypeVector: // fall through
case spv::OpTypeMatrix: // ...
case spv::OpTypePipe: return range_t(3, 4);
case spv::OpConstant: return range_t(3, maxCount);
case spv::Op::OpTypeSampler: return range_t(3, 8);
case spv::Op::OpTypeVector: // fall through
case spv::Op::OpTypeMatrix: // ...
case spv::Op::OpTypePipe: return range_t(3, 4);
case spv::Op::OpConstant: return range_t(3, maxCount);
default: return range_t(0, 0);
}
}
@@ -97,15 +98,15 @@ namespace spv {
return range_t(1, 2);
switch (opCode) {
case spv::OpTypeVector: // fall through
case spv::OpTypeMatrix: // ...
case spv::OpTypeSampler: // ...
case spv::OpTypeArray: // ...
case spv::OpTypeRuntimeArray: // ...
case spv::OpTypePipe: return range_t(2, 3);
case spv::OpTypeStruct: // fall through
case spv::OpTypeFunction: return range_t(2, maxCount);
case spv::OpTypePointer: return range_t(3, 4);
case spv::Op::OpTypeVector: // fall through
case spv::Op::OpTypeMatrix: // ...
case spv::Op::OpTypeSampler: // ...
case spv::Op::OpTypeArray: // ...
case spv::Op::OpTypeRuntimeArray: // ...
case spv::Op::OpTypePipe: return range_t(2, 3);
case spv::Op::OpTypeStruct: // fall through
case spv::Op::OpTypeFunction: return range_t(2, maxCount);
case spv::Op::OpTypePointer: return range_t(3, 4);
default: return range_t(0, 0);
}
}
@@ -115,9 +116,9 @@ namespace spv {
static const int maxCount = 1<<30;
switch (opCode) {
case spv::OpTypeArray: // fall through...
case spv::OpTypeRuntimeArray: return range_t(3, 4);
case spv::OpConstantComposite: return range_t(3, maxCount);
case spv::Op::OpTypeArray: // fall through...
case spv::Op::OpTypeRuntimeArray: return range_t(3, 4);
case spv::Op::OpConstantComposite: return range_t(3, maxCount);
default: return range_t(0, 0);
}
}
@@ -134,8 +135,8 @@ namespace spv {
return 0;
switch (opCode) {
case spv::OpTypeInt: // fall through...
case spv::OpTypeFloat: return (spv[typeStart+2]+31)/32;
case spv::Op::OpTypeInt: // fall through...
case spv::Op::OpTypeFloat: return (spv[typeStart + 2] + 31) / 32;
default:
return 0;
}
@@ -158,11 +159,11 @@ namespace spv {
bool spirvbin_t::isStripOp(spv::Op opCode, unsigned start) const
{
switch (opCode) {
case spv::OpSource:
case spv::OpSourceExtension:
case spv::OpName:
case spv::OpMemberName:
case spv::OpLine :
case spv::Op::OpSource:
case spv::Op::OpSourceExtension:
case spv::Op::OpName:
case spv::Op::OpMemberName:
case spv::Op::OpLine:
{
const std::string name = literalString(start + 2);
@@ -185,15 +186,15 @@ namespace spv {
bool spirvbin_t::isFlowCtrl(spv::Op opCode) const
{
switch (opCode) {
case spv::OpBranchConditional:
case spv::OpBranch:
case spv::OpSwitch:
case spv::OpLoopMerge:
case spv::OpSelectionMerge:
case spv::OpLabel:
case spv::OpFunction:
case spv::OpFunctionEnd: return true;
default: return false;
case spv::Op::OpBranchConditional:
case spv::Op::OpBranch:
case spv::Op::OpSwitch:
case spv::Op::OpLoopMerge:
case spv::Op::OpSelectionMerge:
case spv::Op::OpLabel:
case spv::Op::OpFunction:
case spv::Op::OpFunctionEnd: return true;
default: return false;
}
}
@@ -201,27 +202,27 @@ namespace spv {
bool spirvbin_t::isTypeOp(spv::Op opCode) const
{
switch (opCode) {
case spv::OpTypeVoid:
case spv::OpTypeBool:
case spv::OpTypeInt:
case spv::OpTypeFloat:
case spv::OpTypeVector:
case spv::OpTypeMatrix:
case spv::OpTypeImage:
case spv::OpTypeSampler:
case spv::OpTypeArray:
case spv::OpTypeRuntimeArray:
case spv::OpTypeStruct:
case spv::OpTypeOpaque:
case spv::OpTypePointer:
case spv::OpTypeFunction:
case spv::OpTypeEvent:
case spv::OpTypeDeviceEvent:
case spv::OpTypeReserveId:
case spv::OpTypeQueue:
case spv::OpTypeSampledImage:
case spv::OpTypePipe: return true;
default: return false;
case spv::Op::OpTypeVoid:
case spv::Op::OpTypeBool:
case spv::Op::OpTypeInt:
case spv::Op::OpTypeFloat:
case spv::Op::OpTypeVector:
case spv::Op::OpTypeMatrix:
case spv::Op::OpTypeImage:
case spv::Op::OpTypeSampler:
case spv::Op::OpTypeArray:
case spv::Op::OpTypeRuntimeArray:
case spv::Op::OpTypeStruct:
case spv::Op::OpTypeOpaque:
case spv::Op::OpTypePointer:
case spv::Op::OpTypeFunction:
case spv::Op::OpTypeEvent:
case spv::Op::OpTypeDeviceEvent:
case spv::Op::OpTypeReserveId:
case spv::Op::OpTypeQueue:
case spv::Op::OpTypeSampledImage:
case spv::Op::OpTypePipe: return true;
default: return false;
}
}
@@ -229,15 +230,15 @@ namespace spv {
bool spirvbin_t::isConstOp(spv::Op opCode) const
{
switch (opCode) {
case spv::OpConstantSampler:
case spv::Op::OpConstantSampler:
error("unimplemented constant type");
return true;
case spv::OpConstantNull:
case spv::OpConstantTrue:
case spv::OpConstantFalse:
case spv::OpConstantComposite:
case spv::OpConstant:
case spv::Op::OpConstantNull:
case spv::Op::OpConstantTrue:
case spv::Op::OpConstantFalse:
case spv::Op::OpConstantComposite:
case spv::Op::OpConstant:
return true;
default:
@@ -395,10 +396,10 @@ namespace spv {
[&](spv::Op opCode, unsigned start) {
// strip opcodes pointing to removed data
switch (opCode) {
case spv::OpName:
case spv::OpMemberName:
case spv::OpDecorate:
case spv::OpMemberDecorate:
case spv::Op::OpName:
case spv::Op::OpMemberName:
case spv::Op::OpDecorate:
case spv::Op::OpMemberDecorate:
if (idPosR.find(asId(start+1)) == idPosR.end())
stripInst(start);
break;
@@ -439,11 +440,11 @@ namespace spv {
unsigned word = start+1;
spv::Id typeId = spv::NoResult;
if (spv::InstructionDesc[opCode].hasType())
if (spv::InstructionDesc[enumCast(opCode)].hasType())
typeId = asId(word++);
// If there's a result ID, remember the size of its type
if (spv::InstructionDesc[opCode].hasResult()) {
if (spv::InstructionDesc[enumCast(opCode)].hasResult()) {
const spv::Id resultId = asId(word++);
idPosR[resultId] = start;
@@ -546,19 +547,19 @@ namespace spv {
return nextInst;
// Read type and result ID from instruction desc table
if (spv::InstructionDesc[opCode].hasType()) {
if (spv::InstructionDesc[enumCast(opCode)].hasType()) {
idFn(asId(word++));
--numOperands;
}
if (spv::InstructionDesc[opCode].hasResult()) {
if (spv::InstructionDesc[enumCast(opCode)].hasResult()) {
idFn(asId(word++));
--numOperands;
}
// Extended instructions: currently, assume everything is an ID.
// TODO: add whatever data we need for exceptions to that
if (opCode == spv::OpExtInst) {
if (opCode == spv::Op::OpExtInst) {
idFn(asId(word)); // Instruction set is an ID that also needs to be mapped
@@ -583,14 +584,14 @@ namespace spv {
// opcode being processed is the literal opcode value of the SpecConstantOp. See the
// SPIRV spec for details. This way we will handle IDs and literals as appropriate for
// the embedded op.
if (opCode == spv::OpSpecConstantOp) {
if (opCode == spv::Op::OpSpecConstantOp) {
if (op == 0) {
opCode = asOpCode(word++); // this is the opcode embedded in the SpecConstantOp.
--numOperands;
}
}
switch (spv::InstructionDesc[opCode].operands.getClass(op)) {
switch (spv::InstructionDesc[enumCast(opCode)].operands.getClass(op)) {
case spv::OperandId:
case spv::OperandScope:
case spv::OperandMemorySemantics:
@@ -614,7 +615,7 @@ namespace spv {
return nextInst;
case spv::OperandVariableLiteralId: {
if (opCode == OpSwitch) {
if (opCode == Op::OpSwitch) {
// word-2 is the position of the selector ID. OpSwitch Literals match its type.
// In case the IDs are currently being remapped, we get the word[-2] ID from
// the circular idBuffer.
@@ -653,12 +654,12 @@ namespace spv {
case spv::OperandMemoryAccess:
{
uint32_t mask = spv[word];
if (mask & uint32_t(spv::MemoryAccessMask::MemoryAccessAlignedMask)) {
if (mask & uint32_t(spv::MemoryAccessMask::Aligned)) {
++word;
--numOperands;
}
if (mask & uint32_t(spv::MemoryAccessMask::MemoryAccessMakePointerAvailableMask |
spv::MemoryAccessMask::MemoryAccessMakePointerVisibleMask)) {
if (mask & uint32_t(spv::MemoryAccessMask::MakePointerAvailable |
spv::MemoryAccessMask::MakePointerVisible)) {
idFn(asId(word+1));
++word;
--numOperands;
@@ -670,12 +671,12 @@ namespace spv {
case spv::OperandTensorAddressingOperands:
{
uint32_t mask = spv[word];
if (mask & uint32_t(spv::TensorAddressingOperandsMask::TensorAddressingOperandsTensorViewMask)) {
if (mask & uint32_t(spv::TensorAddressingOperandsMask::TensorView)) {
idFn(asId(word+1));
++word;
--numOperands;
}
if (mask & uint32_t(spv::TensorAddressingOperandsMask::TensorAddressingOperandsDecodeFuncMask)) {
if (mask & uint32_t(spv::TensorAddressingOperandsMask::DecodeFunc)) {
idFn(asId(word+1));
++word;
--numOperands;
@@ -686,6 +687,7 @@ namespace spv {
// Single word operands we simply ignore, as they hold no IDs
case spv::OperandLiteralNumber:
case spv::OperandOptionalLiteral:
case spv::OperandSource:
case spv::OperandExecutionModel:
case spv::OperandAddressing:
@@ -799,26 +801,26 @@ namespace spv {
const unsigned start = instPos[entry];
const spv::Op opCode = asOpCode(start);
if (opCode == spv::OpFunction)
if (opCode == spv::Op::OpFunction)
fnId = asId(start + 2);
if (opCode == spv::OpFunctionEnd)
if (opCode == spv::Op::OpFunctionEnd)
fnId = spv::NoResult;
if (fnId != spv::NoResult) { // if inside a function
if (spv::InstructionDesc[opCode].hasResult()) {
const unsigned word = start + (spv::InstructionDesc[opCode].hasType() ? 2 : 1);
if (spv::InstructionDesc[enumCast(opCode)].hasResult()) {
const unsigned word = start + (spv::InstructionDesc[enumCast(opCode)].hasType() ? 2 : 1);
const spv::Id resId = asId(word);
std::uint32_t hashval = fnId * 17; // small prime
for (unsigned i = entry-1; i >= entry-windowSize; --i) {
if (asOpCode(instPos[i]) == spv::OpFunction)
if (asOpCode(instPos[i]) == spv::Op::OpFunction)
break;
hashval = hashval * 30103 + asOpCodeHash(instPos[i]); // 30103 = semiarbitrary prime
}
for (unsigned i = entry; i <= entry + windowSize; ++i) {
if (asOpCode(instPos[i]) == spv::OpFunctionEnd)
if (asOpCode(instPos[i]) == spv::Op::OpFunctionEnd)
break;
hashval = hashval * 30103 + asOpCodeHash(instPos[i]); // 30103 = semiarbitrary prime
}
@@ -833,7 +835,7 @@ namespace spv {
}
}
spv::Op thisOpCode(spv::OpNop);
spv::Op thisOpCode(spv::Op::OpNop);
std::unordered_map<int, int> opCounter;
int idCounter(0);
fnId = spv::NoResult;
@@ -841,53 +843,53 @@ namespace spv {
process(
[&](spv::Op opCode, unsigned start) {
switch (opCode) {
case spv::OpFunction:
case spv::Op::OpFunction:
// Reset counters at each function
idCounter = 0;
opCounter.clear();
fnId = asId(start + 2);
break;
case spv::OpImageSampleImplicitLod:
case spv::OpImageSampleExplicitLod:
case spv::OpImageSampleDrefImplicitLod:
case spv::OpImageSampleDrefExplicitLod:
case spv::OpImageSampleProjImplicitLod:
case spv::OpImageSampleProjExplicitLod:
case spv::OpImageSampleProjDrefImplicitLod:
case spv::OpImageSampleProjDrefExplicitLod:
case spv::OpDot:
case spv::OpCompositeExtract:
case spv::OpCompositeInsert:
case spv::OpVectorShuffle:
case spv::OpLabel:
case spv::OpVariable:
case spv::Op::OpImageSampleImplicitLod:
case spv::Op::OpImageSampleExplicitLod:
case spv::Op::OpImageSampleDrefImplicitLod:
case spv::Op::OpImageSampleDrefExplicitLod:
case spv::Op::OpImageSampleProjImplicitLod:
case spv::Op::OpImageSampleProjExplicitLod:
case spv::Op::OpImageSampleProjDrefImplicitLod:
case spv::Op::OpImageSampleProjDrefExplicitLod:
case spv::Op::OpDot:
case spv::Op::OpCompositeExtract:
case spv::Op::OpCompositeInsert:
case spv::Op::OpVectorShuffle:
case spv::Op::OpLabel:
case spv::Op::OpVariable:
case spv::OpAccessChain:
case spv::OpLoad:
case spv::OpStore:
case spv::OpCompositeConstruct:
case spv::OpFunctionCall:
++opCounter[opCode];
case spv::Op::OpAccessChain:
case spv::Op::OpLoad:
case spv::Op::OpStore:
case spv::Op::OpCompositeConstruct:
case spv::Op::OpFunctionCall:
++opCounter[enumCast(opCode)];
idCounter = 0;
thisOpCode = opCode;
break;
default:
thisOpCode = spv::OpNop;
thisOpCode = spv::Op::OpNop;
}
return false;
},
[&](spv::Id& id) {
if (thisOpCode != spv::OpNop) {
if (thisOpCode != spv::Op::OpNop) {
++idCounter;
const std::uint32_t hashval =
// Explicitly cast operands to unsigned int to avoid integer
// promotion to signed int followed by integer overflow,
// which would result in undefined behavior.
static_cast<unsigned int>(opCounter[thisOpCode])
* thisOpCode
static_cast<unsigned int>(opCounter[enumCast(thisOpCode)])
* enumCast(thisOpCode)
* 50047
+ idCounter
+ static_cast<unsigned int>(fnId) * 117;
@@ -909,16 +911,16 @@ namespace spv {
process(
[&](spv::Op opCode, unsigned start) {
// Add inputs and uniforms to the map
if ((opCode == spv::OpVariable && asWordCount(start) == 4) &&
(spv[start+3] == spv::StorageClassUniform ||
spv[start+3] == spv::StorageClassUniformConstant ||
spv[start+3] == spv::StorageClassInput))
if ((opCode == spv::Op::OpVariable && asWordCount(start) == 4) &&
(spv[start+3] == (unsigned)spv::StorageClass::Uniform ||
spv[start+3] == (unsigned)spv::StorageClass::UniformConstant ||
spv[start+3] == (unsigned)spv::StorageClass::Input))
fnLocalVars.insert(asId(start+2));
if (opCode == spv::OpAccessChain && fnLocalVars.count(asId(start+3)) > 0)
if (opCode == spv::Op::OpAccessChain && fnLocalVars.count(asId(start+3)) > 0)
fnLocalVars.insert(asId(start+2));
if (opCode == spv::OpLoad && fnLocalVars.count(asId(start+3)) > 0) {
if (opCode == spv::Op::OpLoad && fnLocalVars.count(asId(start+3)) > 0) {
idMap[asId(start+2)] = asId(start+3);
stripInst(start);
}
@@ -939,11 +941,11 @@ namespace spv {
process(
[&](spv::Op opCode, unsigned start) {
// Add inputs and uniforms to the map
if ((opCode == spv::OpVariable && asWordCount(start) == 4) &&
(spv[start+3] == spv::StorageClassOutput))
if ((opCode == spv::Op::OpVariable && asWordCount(start) == 4) &&
(spv[start+3] == (int)spv::StorageClass::Output))
fnLocalVars.insert(asId(start+2));
if (opCode == spv::OpStore && fnLocalVars.count(asId(start+1)) > 0) {
if (opCode == spv::Op::OpStore && fnLocalVars.count(asId(start+1)) > 0) {
idMap[asId(start+2)] = asId(start+1);
stripInst(start);
}
@@ -984,19 +986,19 @@ namespace spv {
++blockNum;
// Add local variables to the map
if ((opCode == spv::OpVariable && spv[start+3] == spv::StorageClassFunction && asWordCount(start) == 4)) {
if ((opCode == spv::Op::OpVariable && spv[start+3] == (unsigned)spv::StorageClass::Function && asWordCount(start) == 4)) {
fnLocalVars.insert(asId(start+2));
return true;
}
// Ignore process vars referenced via access chain
if ((opCode == spv::OpAccessChain || opCode == spv::OpInBoundsAccessChain) && fnLocalVars.count(asId(start+3)) > 0) {
if ((opCode == spv::Op::OpAccessChain || opCode == spv::Op::OpInBoundsAccessChain) && fnLocalVars.count(asId(start+3)) > 0) {
fnLocalVars.erase(asId(start+3));
idMap.erase(asId(start+3));
return true;
}
if (opCode == spv::OpLoad && fnLocalVars.count(asId(start+3)) > 0) {
if (opCode == spv::Op::OpLoad && fnLocalVars.count(asId(start + 3)) > 0) {
const spv::Id varId = asId(start+3);
// Avoid loads before stores
@@ -1006,7 +1008,7 @@ namespace spv {
}
// don't do for volatile references
if (wordCount > 4 && (spv[start+4] & spv::MemoryAccessVolatileMask)) {
if (wordCount > 4 && (spv[start+4] & spv::MemoryAccessMask::Volatile)) {
fnLocalVars.erase(varId);
idMap.erase(varId);
}
@@ -1022,7 +1024,7 @@ namespace spv {
return true;
}
if (opCode == spv::OpStore && fnLocalVars.count(asId(start+1)) > 0) {
if (opCode == spv::Op::OpStore && fnLocalVars.count(asId(start+1)) > 0) {
const spv::Id varId = asId(start+1);
if (idMap.find(varId) == idMap.end()) {
@@ -1034,7 +1036,7 @@ namespace spv {
}
// don't do for volatile references
if (wordCount > 3 && (spv[start+3] & spv::MemoryAccessVolatileMask)) {
if (wordCount > 3 && (spv[start+3] & spv::MemoryAccessMask::Volatile)) {
fnLocalVars.erase(asId(start+3));
idMap.erase(asId(start+3));
}
@@ -1067,7 +1069,7 @@ namespace spv {
process(
[&](spv::Op opCode, unsigned start) {
if (opCode == spv::OpLoad && fnLocalVars.count(asId(start+3)) > 0)
if (opCode == spv::Op::OpLoad && fnLocalVars.count(asId(start+3)) > 0)
idMap[asId(start+2)] = idMap[asId(start+3)];
return false;
},
@@ -1093,9 +1095,9 @@ namespace spv {
// Remove the load/store/variables for the ones we've discovered
process(
[&](spv::Op opCode, unsigned start) {
if ((opCode == spv::OpLoad && fnLocalVars.count(asId(start+3)) > 0) ||
(opCode == spv::OpStore && fnLocalVars.count(asId(start+1)) > 0) ||
(opCode == spv::OpVariable && fnLocalVars.count(asId(start+2)) > 0)) {
if ((opCode == spv::Op::OpLoad && fnLocalVars.count(asId(start+3)) > 0) ||
(opCode == spv::Op::OpStore && fnLocalVars.count(asId(start+1)) > 0) ||
(opCode == spv::Op::OpVariable && fnLocalVars.count(asId(start+2)) > 0)) {
stripInst(start);
return true;
@@ -1174,10 +1176,10 @@ namespace spv {
// Count function variable use
process(
[&](spv::Op opCode, unsigned start) {
if (opCode == spv::OpVariable) {
if (opCode == spv::Op::OpVariable) {
++varUseCount[asId(start+2)];
return true;
} else if (opCode == spv::OpEntryPoint) {
} else if (opCode == spv::Op::OpEntryPoint) {
const int wordCount = asWordCount(start);
for (int i = 4; i < wordCount; i++) {
++varUseCount[asId(start+i)];
@@ -1197,9 +1199,9 @@ namespace spv {
process(
[&](spv::Op opCode, unsigned start) {
spv::Id id = spv::NoResult;
if (opCode == spv::OpVariable)
if (opCode == spv::Op::OpVariable)
id = asId(start+2);
if (opCode == spv::OpDecorate || opCode == spv::OpName)
if (opCode == spv::Op::OpDecorate || opCode == spv::Op::OpName)
id = asId(start+1);
if (id != spv::NoResult && varUseCount[id] == 1)
@@ -1343,30 +1345,30 @@ namespace spv {
const spv::Op opCode = asOpCode(typeStart);
switch (opCode) {
case spv::OpTypeVoid: return 0;
case spv::OpTypeBool: return 1;
case spv::OpTypeInt: return 3 + (spv[typeStart+3]);
case spv::OpTypeFloat: return 5;
case spv::OpTypeVector:
case spv::Op::OpTypeVoid: return 0;
case spv::Op::OpTypeBool: return 1;
case spv::Op::OpTypeInt: return 3 + (spv[typeStart+3]);
case spv::Op::OpTypeFloat: return 5;
case spv::Op::OpTypeVector:
return 6 + hashType(idPos(spv[typeStart+2])) * (spv[typeStart+3] - 1);
case spv::OpTypeMatrix:
case spv::Op::OpTypeMatrix:
return 30 + hashType(idPos(spv[typeStart+2])) * (spv[typeStart+3] - 1);
case spv::OpTypeImage:
case spv::Op::OpTypeImage:
return 120 + hashType(idPos(spv[typeStart+2])) +
spv[typeStart+3] + // dimensionality
spv[typeStart+4] * 8 * 16 + // depth
spv[typeStart+5] * 4 * 16 + // arrayed
spv[typeStart+6] * 2 * 16 + // multisampled
spv[typeStart+7] * 1 * 16; // format
case spv::OpTypeSampler:
case spv::Op::OpTypeSampler:
return 500;
case spv::OpTypeSampledImage:
case spv::Op::OpTypeSampledImage:
return 502;
case spv::OpTypeArray:
case spv::Op::OpTypeArray:
return 501 + hashType(idPos(spv[typeStart+2])) * spv[typeStart+3];
case spv::OpTypeRuntimeArray:
case spv::Op::OpTypeRuntimeArray:
return 5000 + hashType(idPos(spv[typeStart+2]));
case spv::OpTypeStruct:
case spv::Op::OpTypeStruct:
{
std::uint32_t hash = 10000;
for (unsigned w=2; w < wordCount; ++w)
@@ -1374,9 +1376,9 @@ namespace spv {
return hash;
}
case spv::OpTypeOpaque: return 6000 + spv[typeStart+2];
case spv::OpTypePointer: return 100000 + hashType(idPos(spv[typeStart+3]));
case spv::OpTypeFunction:
case spv::Op::OpTypeOpaque: return 6000 + spv[typeStart+2];
case spv::Op::OpTypePointer: return 100000 + hashType(idPos(spv[typeStart+3]));
case spv::Op::OpTypeFunction:
{
std::uint32_t hash = 200000;
for (unsigned w=2; w < wordCount; ++w)
@@ -1384,35 +1386,35 @@ namespace spv {
return hash;
}
case spv::OpTypeEvent: return 300000;
case spv::OpTypeDeviceEvent: return 300001;
case spv::OpTypeReserveId: return 300002;
case spv::OpTypeQueue: return 300003;
case spv::OpTypePipe: return 300004;
case spv::OpConstantTrue: return 300007;
case spv::OpConstantFalse: return 300008;
case spv::OpTypeRayQueryKHR: return 300009;
case spv::OpTypeAccelerationStructureKHR: return 300010;
case spv::OpConstantComposite:
case spv::Op::OpTypeEvent: return 300000;
case spv::Op::OpTypeDeviceEvent: return 300001;
case spv::Op::OpTypeReserveId: return 300002;
case spv::Op::OpTypeQueue: return 300003;
case spv::Op::OpTypePipe: return 300004;
case spv::Op::OpConstantTrue: return 300007;
case spv::Op::OpConstantFalse: return 300008;
case spv::Op::OpTypeRayQueryKHR: return 300009;
case spv::Op::OpTypeAccelerationStructureKHR: return 300010;
case spv::Op::OpConstantComposite:
{
std::uint32_t hash = 300011 + hashType(idPos(spv[typeStart+1]));
for (unsigned w=3; w < wordCount; ++w)
hash += w * hashType(idPos(spv[typeStart+w]));
return hash;
}
case spv::OpConstant:
case spv::Op::OpConstant:
{
std::uint32_t hash = 400011 + hashType(idPos(spv[typeStart+1]));
for (unsigned w=3; w < wordCount; ++w)
hash += w * spv[typeStart+w];
return hash;
}
case spv::OpConstantNull:
case spv::Op::OpConstantNull:
{
std::uint32_t hash = 500009 + hashType(idPos(spv[typeStart+1]));
return hash;
}
case spv::OpConstantSampler:
case spv::Op::OpConstantSampler:
{
std::uint32_t hash = 600011 + hashType(idPos(spv[typeStart+1]));
for (unsigned w=3; w < wordCount; ++w)

View File

@@ -91,7 +91,7 @@ public:
#include <set>
#include <cassert>
#include "spirv.hpp"
#include "spirv.hpp11"
namespace spv {

File diff suppressed because it is too large Load Diff

View File

@@ -49,10 +49,13 @@
#include "Logger.h"
#define SPV_ENABLE_UTILITY_CODE
#include "spirv.hpp"
#include "spirv.hpp11"
#include "spvIR.h"
#include "spvUtil.h"
namespace spv {
#include "GLSL.ext.KHR.h"
#include "GLSL.ext.EXT.h"
#include "NonSemanticShaderDebugInfo100.h"
}
@@ -64,6 +67,7 @@ namespace spv {
#include <sstream>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <map>
namespace spv {
@@ -98,7 +102,7 @@ public:
if (sItr != stringIds.end())
return sItr->second;
spv::Id strId = getUniqueId();
Instruction* fileString = new Instruction(strId, NoType, OpString);
Instruction* fileString = new Instruction(strId, NoType, Op::OpString);
const char* file_c_str = str.c_str();
fileString->addStringOperand(file_c_str);
strings.push_back(std::unique_ptr<Instruction>(fileString));
@@ -204,6 +208,7 @@ public:
Id makeIntType(int width) { return makeIntegerType(width, true); }
Id makeUintType(int width) { return makeIntegerType(width, false); }
Id makeFloatType(int width);
Id makeBFloat16Type();
Id makeStructType(const std::vector<Id>& members, const char* name, bool const compilerGenerated = true);
Id makeStructResultType(Id type0, Id type1);
Id makeVectorType(Id component, int size);
@@ -295,46 +300,46 @@ public:
bool isTensorView(Id resultId)const { return isTensorViewType(getTypeId(resultId)); }
bool isBoolType(Id typeId)
{ return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
{ return groupedTypes[enumCast(Op::OpTypeBool)].size() > 0 && typeId == groupedTypes[enumCast(Op::OpTypeBool)].back()->getResultId(); }
bool isIntType(Id typeId) const
{ return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
{ return getTypeClass(typeId) == Op::OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
bool isUintType(Id typeId) const
{ return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
bool isFloatType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat; }
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; }
{ return getTypeClass(typeId) == Op::OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
bool isFloatType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeFloat; }
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypePointer; }
bool isScalarType(Id typeId) const
{ return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt ||
getTypeClass(typeId) == OpTypeBool; }
bool isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; }
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
bool isArrayType(Id typeId) const { return getTypeClass(typeId) == OpTypeArray; }
{ return getTypeClass(typeId) == Op::OpTypeFloat || getTypeClass(typeId) == Op::OpTypeInt ||
getTypeClass(typeId) == Op::OpTypeBool; }
bool isVectorType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeVector; }
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeMatrix; }
bool isStructType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeStruct; }
bool isArrayType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeArray; }
bool isCooperativeMatrixType(Id typeId)const
{
return getTypeClass(typeId) == OpTypeCooperativeMatrixKHR || getTypeClass(typeId) == OpTypeCooperativeMatrixNV;
return getTypeClass(typeId) == Op::OpTypeCooperativeMatrixKHR || getTypeClass(typeId) == Op::OpTypeCooperativeMatrixNV;
}
bool isTensorViewType(Id typeId) const { return getTypeClass(typeId) == OpTypeTensorViewNV; }
bool isCooperativeVectorType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeVectorNV; }
bool isTensorViewType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeTensorViewNV; }
bool isCooperativeVectorType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeCooperativeVectorNV; }
bool isAggregateType(Id typeId) const
{ return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
bool isImageType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeImage; }
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeSampler; }
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == Op::OpTypeSampledImage; }
bool containsType(Id typeId, Op typeOp, unsigned int width) const;
bool containsPhysicalStorageBufferOrArray(Id typeId) const;
bool isConstantOpCode(Op opcode) const;
bool isSpecConstantOpCode(Op opcode) const;
bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }
bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; }
bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == Op::OpConstant; }
bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); }
unsigned int getConstantScalar(Id resultId) const
{ return module.getInstruction(resultId)->getImmediateOperand(0); }
StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); }
bool isVariableOpCode(Op opcode) const { return opcode == OpVariable; }
bool isVariableOpCode(Op opcode) const { return opcode == Op::OpVariable; }
bool isVariable(Id resultId) const { return isVariableOpCode(getOpCode(resultId)); }
bool isGlobalStorage(Id resultId) const { return getStorageClass(resultId) != StorageClassFunction; }
bool isGlobalStorage(Id resultId) const { return getStorageClass(resultId) != StorageClass::Function; }
bool isGlobalVariable(Id resultId) const { return isVariable(resultId) && isGlobalStorage(resultId); }
// See if a resultId is valid for use as an initializer.
bool isValidInitializer(Id resultId) const { return isConstant(resultId) || isGlobalVariable(resultId); }
@@ -342,7 +347,7 @@ public:
int getScalarTypeWidth(Id typeId) const
{
Id scalarTypeId = getScalarTypeId(typeId);
assert(getTypeClass(scalarTypeId) == OpTypeInt || getTypeClass(scalarTypeId) == OpTypeFloat);
assert(getTypeClass(scalarTypeId) == Op::OpTypeInt || getTypeClass(scalarTypeId) == Op::OpTypeFloat);
return module.getInstruction(scalarTypeId)->getImmediateOperand(0);
}
@@ -393,6 +398,14 @@ public:
{ return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
Id makeUintConstant(unsigned u, bool specConstant = false)
{ return makeIntConstant(makeUintType(32), u, specConstant); }
Id makeUintConstant(Scope u, bool specConstant = false)
{ return makeUintConstant((unsigned)u, specConstant); }
Id makeUintConstant(StorageClass u, bool specConstant = false)
{ return makeUintConstant((unsigned)u, specConstant); }
Id makeUintConstant(MemorySemanticsMask u, bool specConstant = false)
{ return makeUintConstant((unsigned)u, specConstant); }
Id makeUintConstant(SourceLanguage u, bool specConstant = false)
{ return makeUintConstant((unsigned)u, specConstant); }
Id makeInt64Constant(long long i, bool specConstant = false)
{ return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); }
Id makeUint64Constant(unsigned long long u, bool specConstant = false)
@@ -400,6 +413,7 @@ public:
Id makeFloatConstant(float f, bool specConstant = false);
Id makeDoubleConstant(double d, bool specConstant = false);
Id makeFloat16Constant(float f16, bool specConstant = false);
Id makeBFloat16Constant(float bf16, bool specConstant = false);
Id makeFpConstant(Id type, double d, bool specConstant = false);
Id importNonSemanticShaderDebugInfoInstructions();
@@ -487,13 +501,13 @@ public:
Id createUndefined(Id type);
// Store into an Id and return the l-value
void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMask::MaskNone,
spv::Scope scope = spv::Scope::Max, unsigned int alignment = 0);
// Load from an Id and return it
Id createLoad(Id lValue, spv::Decoration precision,
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMask::MaskNone,
spv::Scope scope = spv::Scope::Max, unsigned int alignment = 0);
// Create an OpAccessChain instruction
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
@@ -520,7 +534,7 @@ public:
void createNoResultOp(Op, const std::vector<Id>& operands);
void createNoResultOp(Op, const std::vector<IdImmediate>& operands);
void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask);
void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
void createMemoryBarrier(Scope executionScope, MemorySemanticsMask memorySemantics);
Id createUnaryOp(Op, Id typeId, Id operand);
Id createBinOp(Op, Id typeId, Id operand1, Id operand2);
Id createTriOp(Op, Id typeId, Id operand1, Id operand2, Id operand3);
@@ -627,7 +641,7 @@ public:
// Helper to use for building nested control flow with if-then-else.
class If {
public:
If(Id condition, unsigned int ctrl, Builder& builder);
If(Id condition, SelectionControlMask ctrl, Builder& builder);
~If() {}
void makeBeginElse();
@@ -639,7 +653,7 @@ public:
Builder& builder;
Id condition;
unsigned int control;
SelectionControlMask control;
Function* function;
Block* headerBlock;
Block* thenBlock;
@@ -659,7 +673,7 @@ public:
// Returns the right set of basic blocks to start each code segment with, so that the caller's
// recursion stack can hold the memory for it.
//
void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector<int>& caseValues,
void makeSwitch(Id condition, SelectionControlMask control, int numSegments, const std::vector<int>& caseValues,
const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB);
// Add a branch to the innermost switch's merge block.
@@ -850,12 +864,12 @@ public:
// use accessChain and swizzle to store value
void accessChainStore(Id rvalue, Decoration nonUniform,
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone,
spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMask::MaskNone,
spv::Scope scope = spv::Scope::Max, unsigned int alignment = 0);
// use accessChain and swizzle to load an r-value
Id accessChainLoad(Decoration precision, Decoration l_nonUniform, Decoration r_nonUniform, Id ResultType,
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax,
spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMask::MaskNone, spv::Scope scope = spv::Scope::Max,
unsigned int alignment = 0);
// Return whether or not the access chain can be represented in SPIR-V
@@ -892,7 +906,7 @@ public:
// If set implicit, the branch instruction shouldn't have debug source location.
void createBranch(bool implicit, 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, LoopControlMask control,
const std::vector<unsigned int>& operands);
// Sets to generate opcode for specialization constants.
@@ -914,7 +928,7 @@ public:
void transferAccessChainSwizzle(bool dynamic);
void simplifyAccessChainSwizzle();
void createAndSetNoPredecessorBlock(const char*);
void createSelectionMerge(Block* mergeBlock, unsigned int control);
void createSelectionMerge(Block* mergeBlock, SelectionControlMask control);
void dumpSourceInstructions(std::vector<unsigned int>&) const;
void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector<unsigned int>&) const;
template <class Range> void dumpInstructions(std::vector<unsigned int>& out, const Range& instructions) const;
@@ -998,6 +1012,10 @@ public:
// list of OpConstantNull instructions
std::vector<Instruction*> nullConstants;
// Track which types have explicit layouts, to avoid reusing in storage classes without layout.
// Currently only tracks array types.
std::unordered_set<unsigned int> explicitlyLaidOut;
// stack of switches
std::stack<Block*> switchMerges;

View File

@@ -44,7 +44,8 @@
#include <algorithm>
#include "SpvBuilder.h"
#include "spirv.hpp"
#include "spirv.hpp11"
#include "spvUtil.h"
namespace spv {
#include "GLSL.std.450.h"
@@ -64,137 +65,137 @@ namespace spv {
void Builder::postProcessType(const Instruction& inst, Id typeId)
{
// Characterize the type being questioned
Id basicTypeOp = getMostBasicTypeClass(typeId);
Op basicTypeOp = getMostBasicTypeClass(typeId);
int width = 0;
if (basicTypeOp == OpTypeFloat || basicTypeOp == OpTypeInt)
if (basicTypeOp == Op::OpTypeFloat || basicTypeOp == Op::OpTypeInt)
width = getScalarTypeWidth(typeId);
// Do opcode-specific checks
switch (inst.getOpCode()) {
case OpLoad:
case OpStore:
if (basicTypeOp == OpTypeStruct) {
if (containsType(typeId, OpTypeInt, 8))
addCapability(CapabilityInt8);
if (containsType(typeId, OpTypeInt, 16))
addCapability(CapabilityInt16);
if (containsType(typeId, OpTypeFloat, 16))
addCapability(CapabilityFloat16);
case Op::OpLoad:
case Op::OpStore:
if (basicTypeOp == Op::OpTypeStruct) {
if (containsType(typeId, Op::OpTypeInt, 8))
addCapability(Capability::Int8);
if (containsType(typeId, Op::OpTypeInt, 16))
addCapability(Capability::Int16);
if (containsType(typeId, Op::OpTypeFloat, 16))
addCapability(Capability::Float16);
} else {
StorageClass storageClass = getStorageClass(inst.getIdOperand(0));
if (width == 8) {
switch (storageClass) {
case StorageClassPhysicalStorageBufferEXT:
case StorageClassUniform:
case StorageClassStorageBuffer:
case StorageClassPushConstant:
case StorageClass::PhysicalStorageBufferEXT:
case StorageClass::Uniform:
case StorageClass::StorageBuffer:
case StorageClass::PushConstant:
break;
default:
addCapability(CapabilityInt8);
addCapability(Capability::Int8);
break;
}
} else if (width == 16) {
switch (storageClass) {
case StorageClassPhysicalStorageBufferEXT:
case StorageClassUniform:
case StorageClassStorageBuffer:
case StorageClassPushConstant:
case StorageClassInput:
case StorageClassOutput:
case StorageClass::PhysicalStorageBufferEXT:
case StorageClass::Uniform:
case StorageClass::StorageBuffer:
case StorageClass::PushConstant:
case StorageClass::Input:
case StorageClass::Output:
break;
default:
if (basicTypeOp == OpTypeInt)
addCapability(CapabilityInt16);
if (basicTypeOp == OpTypeFloat)
addCapability(CapabilityFloat16);
if (basicTypeOp == Op::OpTypeInt)
addCapability(Capability::Int16);
if (basicTypeOp == Op::OpTypeFloat)
addCapability(Capability::Float16);
break;
}
}
}
break;
case OpCopyObject:
case Op::OpCopyObject:
break;
case OpFConvert:
case OpSConvert:
case OpUConvert:
case Op::OpFConvert:
case Op::OpSConvert:
case Op::OpUConvert:
// Look for any 8/16-bit storage capabilities. If there are none, assume that
// the convert instruction requires the Float16/Int8/16 capability.
if (containsType(typeId, OpTypeFloat, 16) || containsType(typeId, OpTypeInt, 16)) {
if (containsType(typeId, Op::OpTypeFloat, 16) || containsType(typeId, Op::OpTypeInt, 16)) {
bool foundStorage = false;
for (auto it = capabilities.begin(); it != capabilities.end(); ++it) {
spv::Capability cap = *it;
if (cap == spv::CapabilityStorageInputOutput16 ||
cap == spv::CapabilityStoragePushConstant16 ||
cap == spv::CapabilityStorageUniformBufferBlock16 ||
cap == spv::CapabilityStorageUniform16) {
if (cap == spv::Capability::StorageInputOutput16 ||
cap == spv::Capability::StoragePushConstant16 ||
cap == spv::Capability::StorageUniformBufferBlock16 ||
cap == spv::Capability::StorageUniform16) {
foundStorage = true;
break;
}
}
if (!foundStorage) {
if (containsType(typeId, OpTypeFloat, 16))
addCapability(CapabilityFloat16);
if (containsType(typeId, OpTypeInt, 16))
addCapability(CapabilityInt16);
if (containsType(typeId, Op::OpTypeFloat, 16))
addCapability(Capability::Float16);
if (containsType(typeId, Op::OpTypeInt, 16))
addCapability(Capability::Int16);
}
}
if (containsType(typeId, OpTypeInt, 8)) {
if (containsType(typeId, Op::OpTypeInt, 8)) {
bool foundStorage = false;
for (auto it = capabilities.begin(); it != capabilities.end(); ++it) {
spv::Capability cap = *it;
if (cap == spv::CapabilityStoragePushConstant8 ||
cap == spv::CapabilityUniformAndStorageBuffer8BitAccess ||
cap == spv::CapabilityStorageBuffer8BitAccess) {
if (cap == spv::Capability::StoragePushConstant8 ||
cap == spv::Capability::UniformAndStorageBuffer8BitAccess ||
cap == spv::Capability::StorageBuffer8BitAccess) {
foundStorage = true;
break;
}
}
if (!foundStorage) {
addCapability(CapabilityInt8);
addCapability(Capability::Int8);
}
}
break;
case OpExtInst:
case Op::OpExtInst:
switch (inst.getImmediateOperand(1)) {
case GLSLstd450Frexp:
case GLSLstd450FrexpStruct:
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, OpTypeInt, 16))
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, Op::OpTypeInt, 16))
addExtension(spv::E_SPV_AMD_gpu_shader_int16);
break;
case GLSLstd450InterpolateAtCentroid:
case GLSLstd450InterpolateAtSample:
case GLSLstd450InterpolateAtOffset:
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, OpTypeFloat, 16))
if (getSpvVersion() < spv::Spv_1_3 && containsType(typeId, Op::OpTypeFloat, 16))
addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
break;
default:
break;
}
break;
case OpAccessChain:
case OpPtrAccessChain:
case Op::OpAccessChain:
case Op::OpPtrAccessChain:
if (isPointerType(typeId))
break;
if (basicTypeOp == OpTypeInt) {
if (basicTypeOp == Op::OpTypeInt) {
if (width == 16)
addCapability(CapabilityInt16);
addCapability(Capability::Int16);
else if (width == 8)
addCapability(CapabilityInt8);
addCapability(Capability::Int8);
}
break;
default:
if (basicTypeOp == OpTypeInt) {
if (basicTypeOp == Op::OpTypeInt) {
if (width == 16)
addCapability(CapabilityInt16);
addCapability(Capability::Int16);
else if (width == 8)
addCapability(CapabilityInt8);
addCapability(Capability::Int8);
else if (width == 64)
addCapability(CapabilityInt64);
} else if (basicTypeOp == OpTypeFloat) {
addCapability(Capability::Int64);
} else if (basicTypeOp == Op::OpTypeFloat) {
if (width == 16)
addCapability(CapabilityFloat16);
addCapability(Capability::Float16);
else if (width == 64)
addCapability(CapabilityFloat64);
addCapability(Capability::Float64);
}
break;
}
@@ -205,41 +206,41 @@ void Builder::postProcess(Instruction& inst)
{
// Add capabilities based simply on the opcode.
switch (inst.getOpCode()) {
case OpExtInst:
case Op::OpExtInst:
switch (inst.getImmediateOperand(1)) {
case GLSLstd450InterpolateAtCentroid:
case GLSLstd450InterpolateAtSample:
case GLSLstd450InterpolateAtOffset:
addCapability(CapabilityInterpolationFunction);
addCapability(Capability::InterpolationFunction);
break;
default:
break;
}
break;
case OpDPdxFine:
case OpDPdyFine:
case OpFwidthFine:
case OpDPdxCoarse:
case OpDPdyCoarse:
case OpFwidthCoarse:
addCapability(CapabilityDerivativeControl);
case Op::OpDPdxFine:
case Op::OpDPdyFine:
case Op::OpFwidthFine:
case Op::OpDPdxCoarse:
case Op::OpDPdyCoarse:
case Op::OpFwidthCoarse:
addCapability(Capability::DerivativeControl);
break;
case OpImageQueryLod:
case OpImageQuerySize:
case OpImageQuerySizeLod:
case OpImageQuerySamples:
case OpImageQueryLevels:
addCapability(CapabilityImageQuery);
case Op::OpImageQueryLod:
case Op::OpImageQuerySize:
case Op::OpImageQuerySizeLod:
case Op::OpImageQuerySamples:
case Op::OpImageQueryLevels:
addCapability(Capability::ImageQuery);
break;
case OpGroupNonUniformPartitionNV:
case Op::OpGroupNonUniformPartitionNV:
addExtension(E_SPV_NV_shader_subgroup_partitioned);
addCapability(CapabilityGroupNonUniformPartitionedNV);
addCapability(Capability::GroupNonUniformPartitionedNV);
break;
case OpLoad:
case OpStore:
case Op::OpLoad:
case Op::OpStore:
{
// For any load/store to a PhysicalStorageBufferEXT, walk the accesschain
// index list to compute the misalignment. The pre-existing alignment value
@@ -247,13 +248,13 @@ void Builder::postProcess(Instruction& inst)
// the reference type and any scalar component selection in the accesschain,
// and this function computes the rest from the SPIR-V Offset decorations.
Instruction *accessChain = module.getInstruction(inst.getIdOperand(0));
if (accessChain->getOpCode() == OpAccessChain) {
if (accessChain->getOpCode() == Op::OpAccessChain) {
Instruction *base = module.getInstruction(accessChain->getIdOperand(0));
// Get the type of the base of the access chain. It must be a pointer type.
Id typeId = base->getTypeId();
Instruction *type = module.getInstruction(typeId);
assert(type->getOpCode() == OpTypePointer);
if (type->getImmediateOperand(0) != StorageClassPhysicalStorageBufferEXT) {
assert(type->getOpCode() == Op::OpTypePointer);
if (type->getImmediateOperand(0) != StorageClass::PhysicalStorageBufferEXT) {
break;
}
// Get the pointee type.
@@ -266,16 +267,16 @@ void Builder::postProcess(Instruction& inst)
int alignment = 0;
for (int i = 1; i < accessChain->getNumOperands(); ++i) {
Instruction *idx = module.getInstruction(accessChain->getIdOperand(i));
if (type->getOpCode() == OpTypeStruct) {
assert(idx->getOpCode() == OpConstant);
if (type->getOpCode() == Op::OpTypeStruct) {
assert(idx->getOpCode() == Op::OpConstant);
unsigned int c = idx->getImmediateOperand(0);
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
if (decoration.get()->getOpCode() == OpMemberDecorate &&
if (decoration.get()->getOpCode() == Op::OpMemberDecorate &&
decoration.get()->getIdOperand(0) == typeId &&
decoration.get()->getImmediateOperand(1) == c &&
(decoration.get()->getImmediateOperand(2) == DecorationOffset ||
decoration.get()->getImmediateOperand(2) == DecorationMatrixStride)) {
(decoration.get()->getImmediateOperand(2) == Decoration::Offset ||
decoration.get()->getImmediateOperand(2) == Decoration::MatrixStride)) {
alignment |= decoration.get()->getImmediateOperand(3);
}
};
@@ -283,12 +284,12 @@ void Builder::postProcess(Instruction& inst)
// get the next member type
typeId = type->getIdOperand(c);
type = module.getInstruction(typeId);
} else if (type->getOpCode() == OpTypeArray ||
type->getOpCode() == OpTypeRuntimeArray) {
} else if (type->getOpCode() == Op::OpTypeArray ||
type->getOpCode() == Op::OpTypeRuntimeArray) {
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
if (decoration.get()->getOpCode() == OpDecorate &&
if (decoration.get()->getOpCode() == Op::OpDecorate &&
decoration.get()->getIdOperand(0) == typeId &&
decoration.get()->getImmediateOperand(1) == DecorationArrayStride) {
decoration.get()->getImmediateOperand(1) == Decoration::ArrayStride) {
alignment |= decoration.get()->getImmediateOperand(2);
}
};
@@ -302,12 +303,12 @@ void Builder::postProcess(Instruction& inst)
}
}
assert(inst.getNumOperands() >= 3);
unsigned int memoryAccess = inst.getImmediateOperand((inst.getOpCode() == OpStore) ? 2 : 1);
assert(memoryAccess & MemoryAccessAlignedMask);
auto const memoryAccess = (MemoryAccessMask)inst.getImmediateOperand((inst.getOpCode() == Op::OpStore) ? 2 : 1);
assert(anySet(memoryAccess, MemoryAccessMask::Aligned));
static_cast<void>(memoryAccess);
// Compute the index of the alignment operand.
int alignmentIdx = 2;
if (inst.getOpCode() == OpStore)
if (inst.getOpCode() == Op::OpStore)
alignmentIdx++;
// Merge new and old (mis)alignment
alignment |= inst.getImmediateOperand(alignmentIdx);
@@ -404,17 +405,17 @@ void Builder::postProcessFeatures() {
// Look for any 8/16 bit type in physical storage buffer class, and set the
// appropriate capability. This happens in createSpvVariable for other storage
// classes, but there isn't always a variable for physical storage buffer.
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
Instruction* type = groupedTypes[OpTypePointer][t];
if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) {
if (containsType(type->getIdOperand(1), OpTypeInt, 8)) {
for (int t = 0; t < (int)groupedTypes[enumCast(Op::OpTypePointer)].size(); ++t) {
Instruction* type = groupedTypes[enumCast(Op::OpTypePointer)][t];
if (type->getImmediateOperand(0) == (unsigned)StorageClass::PhysicalStorageBufferEXT) {
if (containsType(type->getIdOperand(1), Op::OpTypeInt, 8)) {
addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
addCapability(spv::CapabilityStorageBuffer8BitAccess);
addCapability(spv::Capability::StorageBuffer8BitAccess);
}
if (containsType(type->getIdOperand(1), OpTypeInt, 16) ||
containsType(type->getIdOperand(1), OpTypeFloat, 16)) {
if (containsType(type->getIdOperand(1), Op::OpTypeInt, 16) ||
containsType(type->getIdOperand(1), Op::OpTypeFloat, 16)) {
addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3);
addCapability(spv::CapabilityStorageBuffer16BitAccess);
addCapability(spv::Capability::StorageBuffer16BitAccess);
}
}
}
@@ -437,15 +438,15 @@ void Builder::postProcessFeatures() {
bool foundDecoration = false;
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
if (decoration.get()->getIdOperand(0) == resultId &&
decoration.get()->getOpCode() == OpDecorate &&
(decoration.get()->getImmediateOperand(1) == spv::DecorationAliasedPointerEXT ||
decoration.get()->getImmediateOperand(1) == spv::DecorationRestrictPointerEXT)) {
decoration.get()->getOpCode() == Op::OpDecorate &&
(decoration.get()->getImmediateOperand(1) == spv::Decoration::AliasedPointerEXT ||
decoration.get()->getImmediateOperand(1) == spv::Decoration::RestrictPointerEXT)) {
foundDecoration = true;
}
};
std::for_each(decorations.begin(), decorations.end(), function);
if (!foundDecoration) {
addDecoration(resultId, spv::DecorationAliasedPointerEXT);
addDecoration(resultId, spv::Decoration::AliasedPointerEXT);
}
}
}
@@ -454,13 +455,13 @@ void Builder::postProcessFeatures() {
// If any Vulkan memory model-specific functionality is used, update the
// OpMemoryModel to match.
if (capabilities.find(spv::CapabilityVulkanMemoryModelKHR) != capabilities.end()) {
memoryModel = spv::MemoryModelVulkanKHR;
if (capabilities.find(spv::Capability::VulkanMemoryModelKHR) != capabilities.end()) {
memoryModel = spv::MemoryModel::VulkanKHR;
addIncorporatedExtension(spv::E_SPV_KHR_vulkan_memory_model, spv::Spv_1_5);
}
// Add Aliased decoration if there's more than one Workgroup Block variable.
if (capabilities.find(spv::CapabilityWorkgroupMemoryExplicitLayoutKHR) != capabilities.end()) {
if (capabilities.find(spv::Capability::WorkgroupMemoryExplicitLayoutKHR) != capabilities.end()) {
assert(entryPoints.size() == 1);
auto &ep = entryPoints[0];
@@ -471,16 +472,16 @@ void Builder::postProcessFeatures() {
const Id id = ep->getIdOperand(i);
const Instruction *instr = module.getInstruction(id);
if (instr->getOpCode() != spv::OpVariable)
if (instr->getOpCode() != spv::Op::OpVariable)
continue;
if (instr->getImmediateOperand(0) == spv::StorageClassWorkgroup)
if (instr->getImmediateOperand(0) == spv::StorageClass::Workgroup)
workgroup_variables.push_back(id);
}
if (workgroup_variables.size() > 1) {
for (size_t i = 0; i < workgroup_variables.size(); i++)
addDecoration(workgroup_variables[i], spv::DecorationAliased);
addDecoration(workgroup_variables[i], spv::Decoration::Aliased);
}
}
}
@@ -497,7 +498,7 @@ void Builder::postProcessSamplers()
for (auto f: module.getFunctions()) {
for (auto b: f->getBlocks()) {
for (auto &i: b->getInstructions()) {
if (i->getOpCode() == spv::OpSampledImage) {
if (i->getOpCode() == spv::Op::OpSampledImage) {
sampledImageInstrs[i->getResultId()] = i.get();
}
}
@@ -518,7 +519,7 @@ void Builder::postProcessSamplers()
if (i->getBlock() != opSampImg->getBlock()) {
Instruction *newInstr = new Instruction(getUniqueId(),
opSampImg->getTypeId(),
spv::OpSampledImage);
spv::Op::OpSampledImage);
newInstr->addIdOperand(opSampImg->getIdOperand(0));
newInstr->addIdOperand(opSampImg->getIdOperand(1));
newInstr->setBlock(b);

View File

@@ -48,6 +48,7 @@
#include "disassemble.h"
#include "doc.h"
#include "spvUtil.h"
namespace spv {
extern "C" {
@@ -97,7 +98,7 @@ public:
protected:
SpirvStream(const SpirvStream&);
SpirvStream& operator=(const SpirvStream&);
Op getOpCode(int id) const { return idInstruction[id] ? (Op)(stream[idInstruction[id]] & OpCodeMask) : OpNop; }
Op getOpCode(int id) const { return idInstruction[id] ? (Op)(stream[idInstruction[id]] & OpCodeMask) : Op::OpNop; }
// Output methods
void outputIndent();
@@ -187,14 +188,14 @@ void SpirvStream::processInstructions()
// Type <id>
Id typeId = 0;
if (InstructionDesc[opCode].hasType()) {
if (InstructionDesc[enumCast(opCode)].hasType()) {
typeId = stream[word++];
--numOperands;
}
// Result <id>
Id resultId = 0;
if (InstructionDesc[opCode].hasResult()) {
if (InstructionDesc[enumCast(opCode)].hasResult()) {
resultId = stream[word++];
--numOperands;
@@ -355,22 +356,22 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
{
// Process the opcode
out << (OpcodeString(opCode) + 2); // leave out the "Op"
out << (OpcodeString((int)opCode) + 2); // leave out the "Op"
if (opCode == OpLoopMerge || opCode == OpSelectionMerge)
if (opCode == Op::OpLoopMerge || opCode == Op::OpSelectionMerge)
nextNestedControl = stream[word];
else if (opCode == OpBranchConditional || opCode == OpSwitch) {
else if (opCode == Op::OpBranchConditional || opCode == Op::OpSwitch) {
if (nextNestedControl) {
nestedControl.push(nextNestedControl);
nextNestedControl = 0;
}
} else if (opCode == OpExtInstImport) {
} else if (opCode == Op::OpExtInstImport) {
idDescriptor[resultId] = decodeString().second;
}
else {
if (resultId != 0 && idDescriptor[resultId].size() == 0) {
switch (opCode) {
case OpTypeInt:
case Op::OpTypeInt:
switch (stream[word]) {
case 8: idDescriptor[resultId] = "int8_t"; break;
case 16: idDescriptor[resultId] = "int16_t"; break;
@@ -379,26 +380,36 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
case 64: idDescriptor[resultId] = "int64_t"; break;
}
break;
case OpTypeFloat:
case Op::OpTypeFloat:
switch (stream[word]) {
case 16: idDescriptor[resultId] = "float16_t"; break;
case 16:
if (numOperands > 1 && stream[word+1] == spv::FPEncoding::BFloat16KHR) {
idDescriptor[resultId] = "bfloat16_t";
} else {
idDescriptor[resultId] = "float16_t";
}
break;
default: assert(0); [[fallthrough]];
case 32: idDescriptor[resultId] = "float"; break;
case 64: idDescriptor[resultId] = "float64_t"; break;
}
break;
case OpTypeBool:
case Op::OpTypeBool:
idDescriptor[resultId] = "bool";
break;
case OpTypeStruct:
case Op::OpTypeStruct:
idDescriptor[resultId] = "struct";
break;
case OpTypePointer:
case Op::OpTypePointer:
idDescriptor[resultId] = "ptr";
break;
case OpTypeVector:
case Op::OpTypeVector:
if (idDescriptor[stream[word]].size() > 0) {
idDescriptor[resultId].append(idDescriptor[stream[word]].begin(), idDescriptor[stream[word]].begin() + 1);
if (idDescriptor[stream[word]].substr(0,2) == "bf") {
idDescriptor[resultId].append(idDescriptor[stream[word]].begin(), idDescriptor[stream[word]].begin() + 2);
} else {
idDescriptor[resultId].append(idDescriptor[stream[word]].begin(), idDescriptor[stream[word]].begin() + 1);
}
if (strstr(idDescriptor[stream[word]].c_str(), "8")) {
idDescriptor[resultId].append("8");
}
@@ -430,10 +441,10 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
// swapped in mid-traversal.
// Handle images specially, so can put out helpful strings.
if (opCode == OpTypeImage) {
if (opCode == Op::OpTypeImage) {
out << " ";
disassembleIds(1);
out << " " << DimensionString((Dim)stream[word++]);
out << " " << DimensionString((int)(Dim)stream[word++]);
out << (stream[word++] != 0 ? " depth" : "");
out << (stream[word++] != 0 ? " array" : "");
out << (stream[word++] != 0 ? " multi-sampled" : "");
@@ -442,7 +453,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
case 1: out << " sampled"; break;
case 2: out << " nonsampled"; break;
}
out << " format:" << ImageFormatString((ImageFormat)stream[word++]);
out << " format:" << ImageFormatString((int)(ImageFormat)stream[word++]);
if (numOperands == 8) {
out << " " << AccessQualifierString(stream[word++]);
@@ -451,9 +462,9 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
}
// Handle all the parameterized operands
for (int op = 0; op < InstructionDesc[opCode].operands.getNum() && numOperands > 0; ++op) {
for (int op = 0; op < InstructionDesc[enumCast(opCode)].operands.getNum() && numOperands > 0; ++op) {
out << " ";
OperandClass operandClass = InstructionDesc[opCode].operands.getClass(op);
OperandClass operandClass = InstructionDesc[enumCast(opCode)].operands.getClass(op);
switch (operandClass) {
case OperandId:
case OperandScope:
@@ -461,7 +472,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
disassembleIds(1);
--numOperands;
// Get names for printing "(XXX)" for readability, *after* this id
if (opCode == OpName)
if (opCode == Op::OpName)
idDescriptor[stream[word - 1]] = decodeString().second;
break;
case OperandVariableIds:
@@ -474,8 +485,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
return;
case OperandOptionalLiteral:
case OperandVariableLiterals:
if ((opCode == OpDecorate && stream[word - 1] == DecorationBuiltIn) ||
(opCode == OpMemberDecorate && stream[word - 1] == DecorationBuiltIn)) {
if ((opCode == Op::OpDecorate && stream[word - 1] == Decoration::BuiltIn) ||
(opCode == Op::OpMemberDecorate && stream[word - 1] == Decoration::BuiltIn)) {
out << BuiltInString(stream[word++]);
--numOperands;
++op;
@@ -511,7 +522,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
case OperandLiteralNumber:
disassembleImmediates(1);
--numOperands;
if (opCode == OpExtInst) {
if (opCode == Op::OpExtInst) {
ExtInstSet extInstSet = GLSL450Inst;
const char* name = idDescriptor[stream[word - 2]].c_str();
if (strcmp("OpenCL.std", name) == 0) {
@@ -575,14 +586,14 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
uint32_t mask = stream[word-1];
// Aligned is the only memory access operand that uses an immediate
// value, and it is also the first operand that uses a value at all.
if (mask & MemoryAccessAlignedMask) {
if (mask & (uint32_t)MemoryAccessMask::Aligned) {
disassembleImmediates(1);
numOperands--;
if (numOperands)
out << " ";
}
uint32_t bitCount = popcount(mask & (MemoryAccessMakePointerAvailableMask | MemoryAccessMakePointerVisibleMask));
uint32_t bitCount = popcount(mask & (uint32_t)(MemoryAccessMask::MakePointerAvailable | MemoryAccessMask::MakePointerVisible));
disassembleIds(bitCount);
numOperands -= bitCount;
}
@@ -757,41 +768,41 @@ static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
strcmp(name, spv::E_SPV_NV_shader_image_footprint) == 0) {
switch (entrypoint) {
// NV builtins
case BuiltInViewportMaskNV: return "ViewportMaskNV";
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
case BuiltInBaryCoordNV: return "BaryCoordNV";
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
case BuiltInTaskCountNV: return "TaskCountNV";
case BuiltInPrimitiveCountNV: return "PrimitiveCountNV";
case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV";
case BuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV";
case BuiltInCullDistancePerViewNV: return "CullDistancePerViewNV";
case BuiltInLayerPerViewNV: return "LayerPerViewNV";
case BuiltInMeshViewCountNV: return "MeshViewCountNV";
case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV";
case (unsigned)BuiltIn::ViewportMaskNV: return "ViewportMaskNV";
case (unsigned)BuiltIn::SecondaryPositionNV: return "SecondaryPositionNV";
case (unsigned)BuiltIn::SecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
case (unsigned)BuiltIn::PositionPerViewNV: return "PositionPerViewNV";
case (unsigned)BuiltIn::ViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
case (unsigned)BuiltIn::BaryCoordNV: return "BaryCoordNV";
case (unsigned)BuiltIn::BaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
case (unsigned)BuiltIn::TaskCountNV: return "TaskCountNV";
case (unsigned)BuiltIn::PrimitiveCountNV: return "PrimitiveCountNV";
case (unsigned)BuiltIn::PrimitiveIndicesNV: return "PrimitiveIndicesNV";
case (unsigned)BuiltIn::ClipDistancePerViewNV: return "ClipDistancePerViewNV";
case (unsigned)BuiltIn::CullDistancePerViewNV: return "CullDistancePerViewNV";
case (unsigned)BuiltIn::LayerPerViewNV: return "LayerPerViewNV";
case (unsigned)BuiltIn::MeshViewCountNV: return "MeshViewCountNV";
case (unsigned)BuiltIn::MeshViewIndicesNV: return "MeshViewIndicesNV";
// NV Capabilities
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV";
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
case CapabilityMeshShadingNV: return "MeshShadingNV";
case CapabilityImageFootprintNV: return "ImageFootprintNV";
case CapabilitySampleMaskOverrideCoverageNV:return "SampleMaskOverrideCoverageNV";
case (unsigned)Capability::GeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
case (unsigned)Capability::ShaderViewportMaskNV: return "ShaderViewportMaskNV";
case (unsigned)Capability::ShaderStereoViewNV: return "ShaderStereoViewNV";
case (unsigned)Capability::PerViewAttributesNV: return "PerViewAttributesNV";
case (unsigned)Capability::FragmentBarycentricNV: return "FragmentBarycentricNV";
case (unsigned)Capability::MeshShadingNV: return "MeshShadingNV";
case (unsigned)Capability::ImageFootprintNV: return "ImageFootprintNV";
case (unsigned)Capability::SampleMaskOverrideCoverageNV:return "SampleMaskOverrideCoverageNV";
// NV Decorations
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
case DecorationPassthroughNV: return "PassthroughNV";
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
case DecorationPerVertexNV: return "PerVertexNV";
case DecorationPerPrimitiveNV: return "PerPrimitiveNV";
case DecorationPerViewNV: return "PerViewNV";
case DecorationPerTaskNV: return "PerTaskNV";
case (unsigned)Decoration::OverrideCoverageNV: return "OverrideCoverageNV";
case (unsigned)Decoration::PassthroughNV: return "PassthroughNV";
case (unsigned)Decoration::ViewportRelativeNV: return "ViewportRelativeNV";
case (unsigned)Decoration::SecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
case (unsigned)Decoration::PerVertexNV: return "PerVertexNV";
case (unsigned)Decoration::PerPrimitiveNV: return "PerPrimitiveNV";
case (unsigned)Decoration::PerViewNV: return "PerViewNV";
case (unsigned)Decoration::PerTaskNV: return "PerTaskNV";
default: return "Bad";
}

File diff suppressed because it is too large Load Diff

View File

@@ -38,7 +38,7 @@
#pragma once
#include "spirv.hpp"
#include "spirv.hpp11"
#include <vector>

File diff suppressed because it is too large Load Diff

5162
3rdparty/glslang/SPIRV/spirv.hpp11 vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -47,7 +47,7 @@
#ifndef spvIR_H
#define spvIR_H
#include "spirv.hpp"
#include "spirv.hpp11"
#include <algorithm>
#include <cassert>
@@ -67,7 +67,7 @@ class Module;
const Id NoResult = 0;
const Id NoType = 0;
const Decoration NoPrecision = DecorationMax;
const Decoration NoPrecision = Decoration::Max;
#ifdef __GNUC__
# define POTENTIALLY_UNUSED __attribute__((unused))
@@ -77,15 +77,19 @@ const Decoration NoPrecision = DecorationMax;
POTENTIALLY_UNUSED
const MemorySemanticsMask MemorySemanticsAllMemory =
(MemorySemanticsMask)(MemorySemanticsUniformMemoryMask |
MemorySemanticsWorkgroupMemoryMask |
MemorySemanticsAtomicCounterMemoryMask |
MemorySemanticsImageMemoryMask);
(MemorySemanticsMask)(MemorySemanticsMask::UniformMemory |
MemorySemanticsMask::WorkgroupMemory |
MemorySemanticsMask::AtomicCounterMemory |
MemorySemanticsMask::ImageMemory);
struct IdImmediate {
bool isId; // true if word is an Id, false if word is an immediate
unsigned word;
IdImmediate(bool i, unsigned w) : isId(i), word(w) {}
IdImmediate(bool i, spv::MemoryAccessMask w) : isId(i), word((unsigned)w) {}
IdImmediate(bool i, spv::TensorAddressingOperandsMask w) : isId(i), word((unsigned)w) {}
IdImmediate(bool i, spv::ImageOperandsMask w) : isId(i), word((unsigned)w) {}
IdImmediate(bool i, spv::CooperativeMatrixOperandsMask w) : isId(i), word((unsigned)w) {}
};
//
@@ -119,6 +123,67 @@ public:
operands.push_back(immediate);
idOperand.push_back(false);
}
void addImmediateOperand(spv::StorageClass immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::ExecutionMode immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::ExecutionModel immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::Decoration immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::LinkageType immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::MemoryAccessMask immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::Capability immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::AddressingModel immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::MemoryModel immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::FPEncoding immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::SourceLanguage immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::Dim immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::FunctionControlMask immediate){
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::SelectionControlMask immediate) {
addImmediateOperand((unsigned)immediate);
}
void addImmediateOperand(spv::LoopControlMask immediate) {
addImmediateOperand((unsigned)immediate);
}
void setImmediateOperand(unsigned idx, unsigned int immediate) {
assert(!idOperand[idx]);
operands[idx] = immediate;
@@ -128,7 +193,7 @@ public:
{
unsigned int word = 0;
unsigned int shiftAmount = 0;
char c;
unsigned char c;
do {
c = *(str++);
@@ -178,7 +243,7 @@ public:
wordCount += (unsigned int)operands.size();
// Write out the beginning of the instruction
out.push_back(((wordCount) << WordCountShift) | opCode);
out.push_back(((wordCount) << WordCountShift) | (unsigned)opCode);
if (typeId)
out.push_back(typeId);
if (resultId)
@@ -190,10 +255,10 @@ public:
}
const char *getNameString() const {
if (opCode == OpString) {
if (opCode == Op::OpString) {
return (const char *)&operands[0];
} else {
assert(opCode == OpName);
assert(opCode == Op::OpName);
return (const char *)&operands[1];
}
}
@@ -266,8 +331,8 @@ public:
if (instructions.size() < 2) return nullptr;
const Instruction* nextToLast = (instructions.cend() - 2)->get();
switch (nextToLast->getOpCode()) {
case OpSelectionMerge:
case OpLoopMerge:
case Op::OpSelectionMerge:
case Op::OpLoopMerge:
return nextToLast;
default:
return nullptr;
@@ -284,7 +349,7 @@ public:
assert(instructions.size() > 0);
instructions.resize(1);
successors.clear();
addInstruction(std::unique_ptr<Instruction>(new Instruction(OpUnreachable)));
addInstruction(std::unique_ptr<Instruction>(new Instruction(Op::OpUnreachable)));
}
// Change this block into a canonical dead continue target branching to the
// given header ID. Delete instructions as necessary. A canonical dead continue
@@ -298,7 +363,7 @@ public:
successors.clear();
// Add OpBranch back to the header.
assert(header != nullptr);
Instruction* branch = new Instruction(OpBranch);
Instruction* branch = new Instruction(Op::OpBranch);
branch->addIdOperand(header->getId());
addInstruction(std::unique_ptr<Instruction>(branch));
successors.push_back(header);
@@ -307,14 +372,14 @@ public:
bool isTerminated() const
{
switch (instructions.back()->getOpCode()) {
case OpBranch:
case OpBranchConditional:
case OpSwitch:
case OpKill:
case OpTerminateInvocation:
case OpReturn:
case OpReturnValue:
case OpUnreachable:
case Op::OpBranch:
case Op::OpBranchConditional:
case Op::OpSwitch:
case Op::OpKill:
case Op::OpTerminateInvocation:
case Op::OpReturn:
case Op::OpReturnValue:
case Op::OpUnreachable:
return true;
default:
return false;
@@ -411,14 +476,14 @@ public:
Id getFuncTypeId() const { return functionInstruction.getIdOperand(1); }
void setReturnPrecision(Decoration precision)
{
if (precision == DecorationRelaxedPrecision)
if (precision == Decoration::RelaxedPrecision)
reducedPrecisionReturn = true;
}
Decoration getReturnPrecision() const
{ return reducedPrecisionReturn ? DecorationRelaxedPrecision : NoPrecision; }
{ return reducedPrecisionReturn ? Decoration::RelaxedPrecision : NoPrecision; }
void setDebugLineInfo(Id fileName, int line, int column) {
lineInstruction = std::unique_ptr<Instruction>{new Instruction(OpLine)};
lineInstruction = std::unique_ptr<Instruction>{new Instruction(Op::OpLine)};
lineInstruction->reserveOperands(3);
lineInstruction->addIdOperand(fileName);
lineInstruction->addImmediateOperand(line);
@@ -431,13 +496,13 @@ public:
void addParamPrecision(unsigned param, Decoration precision)
{
if (precision == DecorationRelaxedPrecision)
if (precision == Decoration::RelaxedPrecision)
reducedPrecisionParams.insert(param);
}
Decoration getParamPrecision(unsigned param) const
{
return reducedPrecisionParams.find(param) != reducedPrecisionParams.end() ?
DecorationRelaxedPrecision : NoPrecision;
Decoration::RelaxedPrecision : NoPrecision;
}
void dump(std::vector<unsigned int>& out) const
@@ -456,7 +521,7 @@ public:
// Blocks
inReadableOrder(blocks[0], [&out](const Block* b, ReachReason, Block*) { b->dump(out); });
Instruction end(0, 0, OpFunctionEnd);
Instruction end(0, 0, Op::OpFunctionEnd);
end.dump(out);
}
@@ -509,7 +574,7 @@ public:
}
StorageClass getStorageClass(Id typeId) const
{
assert(idToInstruction[typeId]->getOpCode() == spv::OpTypePointer);
assert(idToInstruction[typeId]->getOpCode() == spv::Op::OpTypePointer);
return (StorageClass)idToInstruction[typeId]->getImmediateOperand(0);
}
@@ -538,13 +603,13 @@ protected:
// - all the OpFunctionParameter instructions
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, LinkageType linkage, const std::string& name, Module& parent)
: parent(parent), lineInstruction(nullptr),
functionInstruction(id, resultType, OpFunction), implicitThis(false),
functionInstruction(id, resultType, Op::OpFunction), implicitThis(false),
reducedPrecisionReturn(false),
linkType(linkage)
{
// OpFunction
functionInstruction.reserveOperands(2);
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
functionInstruction.addImmediateOperand(FunctionControlMask::MaskNone);
functionInstruction.addIdOperand(functionType);
parent.mapInstruction(&functionInstruction);
parent.addFunction(this);
@@ -553,13 +618,13 @@ __inline Function::Function(Id id, Id resultType, Id functionType, Id firstParam
Instruction* typeInst = parent.getInstruction(functionType);
int numParams = typeInst->getNumOperands() - 1;
for (int p = 0; p < numParams; ++p) {
Instruction* param = new Instruction(firstParamId + p, typeInst->getIdOperand(p + 1), OpFunctionParameter);
Instruction* param = new Instruction(firstParamId + p, typeInst->getIdOperand(p + 1), Op::OpFunctionParameter);
parent.mapInstruction(param);
parameterInstructions.push_back(param);
}
// If importing/exporting, save the function name (without the mangled parameters) for the linkage decoration
if (linkType != LinkageTypeMax) {
if (linkType != LinkageType::Max) {
exportName = name.substr(0, name.find_first_of('('));
}
}
@@ -573,7 +638,7 @@ __inline void Function::addLocalVariable(std::unique_ptr<Instruction> inst)
__inline Block::Block(Id id, Function& parent) : parent(parent), unreachable(false)
{
instructions.push_back(std::unique_ptr<Instruction>(new Instruction(id, NoType, OpLabel)));
instructions.push_back(std::unique_ptr<Instruction>(new Instruction(id, NoType, Op::OpLabel)));
instructions.back()->setBlock(this);
parent.getParent().mapInstruction(instructions.back().get());
}

88
3rdparty/glslang/SPIRV/spvUtil.h vendored Normal file
View File

@@ -0,0 +1,88 @@
//
// Copyright (C) 2025 Jan Kelemen
//
// 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.
//
#pragma once
#ifndef spvUtil_H
#define spvUtil_H
#include <cstdint>
#include <type_traits>
#include "spirv.hpp11"
namespace spv {
__inline uint32_t operator&(uint32_t value, spv::MemoryAccessMask mask) { return value & (unsigned)mask; }
__inline bool operator==(uint32_t word, spv::FPEncoding encoding) { return word == (unsigned)encoding; }
__inline bool operator!=(uint32_t word, spv::FPEncoding encoding) { return !(word == encoding); }
__inline bool operator==(uint32_t word, spv::Decoration decoration) { return word == (unsigned)decoration; }
__inline bool operator!=(uint32_t word, spv::Decoration decoration) { return !(word == decoration); }
__inline bool operator==(uint32_t word, spv::Op op) { return word == (unsigned)op; }
__inline bool operator!=(uint32_t word, spv::Op op) { return !(word == op); }
__inline bool operator==(uint32_t word, spv::StorageClass storage) { return word == (unsigned)storage; }
__inline bool operator!=(uint32_t word, spv::StorageClass storage) { return !(word == storage); }
__inline bool anySet(spv::MemoryAccessMask value, spv::MemoryAccessMask mask)
{
return (value & mask) != spv::MemoryAccessMask::MaskNone;
}
__inline bool anySet(spv::ImageOperandsMask value, spv::ImageOperandsMask mask)
{
return (value & mask) != spv::ImageOperandsMask::MaskNone;
}
__inline bool anySet(spv::MemorySemanticsMask value, spv::MemorySemanticsMask mask)
{
return (value & mask) != spv::MemorySemanticsMask::MaskNone;
}
__inline void addMask(uint32_t& word, spv::TensorAddressingOperandsMask mask) { word |= (unsigned)mask; }
__inline void addMask(spv::CooperativeMatrixOperandsMask& word, spv::CooperativeMatrixOperandsMask mask)
{
word = word | mask;
}
template<typename Enum, typename To = std::underlying_type_t<Enum>>
__inline To enumCast(Enum value)
{
return static_cast<To>(value);
}
}
#endif // spvUtil_H

View File

@@ -112,6 +112,7 @@ enum TOptions : uint64_t {
EOptionCompileOnly = (1ull << 32),
EOptionDisplayErrorColumn = (1ull << 33),
EOptionLinkTimeOptimization = (1ull << 34),
EOptionValidateCrossStageIO = (1ull << 35),
};
bool targetHlslFunctionality1 = false;
bool SpvToolsDisassembler = false;
@@ -907,6 +908,8 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
Options |= EOptionDisplayErrorColumn;
} else if (lowerword == "lto") {
Options |= EOptionLinkTimeOptimization;
} else if (lowerword == "validate-io") {
Options |= EOptionValidateCrossStageIO;
} else if (lowerword == "help") {
usage();
break;
@@ -1095,6 +1098,10 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
if ((Options & EOptionLinkTimeOptimization) && !(Options & EOptionLinkProgram))
Error("link time optimization requires -l for linking");
// cross stage IO validation makes no sense unless linking
if ((Options & EOptionValidateCrossStageIO) && !(Options & EOptionLinkProgram))
Error("cross stage IO validation requires -l for linking");
// -o or -x makes no sense if there is no target binary
if (binaryFileName && (Options & EOptionSpv) == 0)
Error("no binary generation requested (e.g., -V)");
@@ -1185,6 +1192,8 @@ void SetMessageOptions(EShMessages& messages)
messages = (EShMessages)(messages | EShMsgDisplayErrorColumn);
if (Options & EOptionLinkTimeOptimization)
messages = (EShMessages)(messages | EShMsgLinkTimeOptimization);
if (Options & EOptionValidateCrossStageIO)
messages = (EShMessages)(messages | EShMsgValidateCrossStageIO);
}
//
@@ -2154,7 +2163,8 @@ void usage()
" --no-link Only compile shader; do not link (GLSL-only)\n"
" NOTE: this option will set the export linkage\n"
" attribute on all functions\n"
" --lto perform link time optimization\n");
" --lto perform link time optimization\n"
" --validate-io validate cross stage IO\n");
exit(EFailUsage);
}

View File

@@ -35,7 +35,7 @@
#define GLSLANG_BUILD_INFO
#define GLSLANG_VERSION_MAJOR 15
#define GLSLANG_VERSION_MINOR 2
#define GLSLANG_VERSION_MINOR 3
#define GLSLANG_VERSION_PATCH 0
#define GLSLANG_VERSION_FLAVOR ""

View File

@@ -49,6 +49,7 @@ enum TBasicType {
EbtFloat,
EbtDouble,
EbtFloat16,
EbtBFloat16,
EbtInt8,
EbtUint8,
EbtInt16,
@@ -602,6 +603,7 @@ __inline bool isTypeFloat(TBasicType type)
case EbtFloat:
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
return true;
default:
return false;
@@ -614,6 +616,7 @@ __inline uint32_t GetNumBits(TBasicType type)
case EbtInt8:
case EbtUint8:
return 8;
case EbtBFloat16:
case EbtFloat16:
case EbtInt16:
case EbtUint16:

View File

@@ -61,6 +61,8 @@
// class as the allocator (second) template argument.
//
#include "visibility.h"
#include <cstddef>
#include <cstring>
#include <vector>
@@ -179,6 +181,7 @@ public:
// Call allocate() to actually acquire memory. Returns nullptr if no memory
// available, otherwise a properly aligned pointer to 'numBytes' of memory.
//
GLSLANG_EXPORT_FOR_TESTS
void* allocate(size_t numBytes);
//
@@ -255,6 +258,7 @@ private:
// different times. But a simple use is to have a global pop
// with everyone using the same global allocator.
//
GLSLANG_EXPORT_FOR_TESTS
extern TPoolAllocator& GetThreadPoolAllocator();
void SetThreadPoolAllocator(TPoolAllocator* poolAllocator);
@@ -289,6 +293,7 @@ public:
template<class Other>
pool_allocator(const pool_allocator<Other>& p) : allocator(p.getAllocator()) { }
GLSLANG_EXPORT_FOR_TESTS
pointer allocate(size_type n) {
return reinterpret_cast<pointer>(getAllocator().allocate(n * sizeof(T))); }
pointer allocate(size_type n, const void*) {

View File

@@ -246,6 +246,7 @@ struct TSampler { // misnomer now; includes images, textures without sampler,
case EbtInt: s.append("i"); break;
case EbtUint: s.append("u"); break;
case EbtFloat16: s.append("f16"); break;
case EbtBFloat16: s.append("bf16"); break;
case EbtInt8: s.append("i8"); break;
case EbtUint16: s.append("u8"); break;
case EbtInt16: s.append("i16"); break;
@@ -1854,7 +1855,7 @@ public:
virtual void updateImplicitArraySize(int size) { assert(isArray()); arraySizes->updateImplicitSize(size); }
virtual void setImplicitlySized(bool isImplicitSized) { arraySizes->setImplicitlySized(isImplicitSized); }
virtual bool isStruct() const { return basicType == EbtStruct || basicType == EbtBlock; }
virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16; }
virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16 || basicType == EbtBFloat16; }
virtual bool isIntegerDomain() const
{
switch (basicType) {
@@ -1960,6 +1961,7 @@ public:
case EbtFloat:
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
case EbtInt8:
case EbtUint8:
case EbtInt16:
@@ -1992,6 +1994,10 @@ public:
{
return containsBasicType(EbtFloat16);
}
bool containsBFloat16() const
{
return containsBasicType(EbtBFloat16);
}
bool contains64BitInt() const
{
return containsBasicType(EbtInt64) || containsBasicType(EbtUint64);
@@ -2113,6 +2119,7 @@ public:
case EbtVoid: return "void";
case EbtDouble: return "double";
case EbtFloat16: return "float16_t";
case EbtBFloat16: return "bfloat16_t";
case EbtInt8: return "int8_t";
case EbtUint8: return "uint8_t";
case EbtInt16: return "int16_t";
@@ -2791,8 +2798,8 @@ public:
else
rv = false;
} else if (isCoopMatKHR() && right.isCoopMatKHR()) {
if (getBasicType() == EbtFloat || getBasicType() == EbtFloat16)
rv = right.getBasicType() == EbtFloat || right.getBasicType() == EbtFloat16 || right.getBasicType() == EbtCoopmat;
if (getBasicType() == EbtFloat || getBasicType() == EbtFloat16 || getBasicType() == EbtBFloat16)
rv = right.getBasicType() == EbtFloat || right.getBasicType() == EbtFloat16 || right.getBasicType() == EbtBFloat16 || right.getBasicType() == EbtCoopmat;
else if (getBasicType() == EbtUint || getBasicType() == EbtUint8 || getBasicType() == EbtUint16)
rv = right.getBasicType() == EbtUint || right.getBasicType() == EbtUint8 || right.getBasicType() == EbtUint16 || right.getBasicType() == EbtCoopmat;
else if (getBasicType() == EbtInt || getBasicType() == EbtInt8 || getBasicType() == EbtInt16)

View File

@@ -178,6 +178,7 @@ typedef enum {
GLSLANG_MSG_ABSOLUTE_PATH = (1 << 16),
GLSLANG_MSG_DISPLAY_ERROR_COLUMN = (1 << 17),
GLSLANG_MSG_LINK_TIME_OPTIMIZATION_BIT = (1 << 18),
GLSLANG_MSG_VALIDATE_CROSS_STAGE_IO_BIT = (1 << 19),
LAST_ELEMENT_MARKER(GLSLANG_MSG_COUNT),
} glslang_messages_t;

View File

@@ -611,6 +611,10 @@ enum TOperator {
EOpConstructF16Mat4x2,
EOpConstructF16Mat4x3,
EOpConstructF16Mat4x4,
EOpConstructBFloat16,
EOpConstructBF16Vec2,
EOpConstructBF16Vec3,
EOpConstructBF16Vec4,
EOpConstructStruct,
EOpConstructTextureSampler,
EOpConstructNonuniform, // expected to be transformed away, not present in final AST

View File

@@ -151,6 +151,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
case EbtDouble:
case EbtFloat:
case EbtFloat16:
case EbtBFloat16:
if (rightUnionArray[i].getDConst() != 0.0)
newConstArray[i].setDConst(leftUnionArray[i].getDConst() / rightUnionArray[i].getDConst());
else if (leftUnionArray[i].getDConst() > 0.0)
@@ -503,6 +504,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
switch (getType().getBasicType()) {
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
case EbtFloat:
valf = unionArray[i].getDConst();
srcType = CONV_FLOAT;
@@ -551,6 +553,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
switch (returnType.getBasicType()) {
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
case EbtFloat:
dstType = CONV_FLOAT;
break;
@@ -621,6 +624,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
switch (returnType.getBasicType()) {
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
case EbtFloat:
newConstArray[i].setDConst(valf); break;
case EbtInt8:
@@ -652,6 +656,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
switch (getType().getBasicType()) {
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
// Note: avoid UBSAN error regarding negating 0x80000000
case EbtInt: newConstArray[i].setIConst(
@@ -944,6 +949,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
case EOpMin:
switch(children[0]->getAsTyped()->getBasicType()) {
case EbtFloat16:
case EbtBFloat16:
case EbtFloat:
case EbtDouble:
newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
@@ -978,6 +984,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
case EOpMax:
switch(children[0]->getAsTyped()->getBasicType()) {
case EbtFloat16:
case EbtBFloat16:
case EbtFloat:
case EbtDouble:
newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
@@ -1012,6 +1019,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
case EOpClamp:
switch(children[0]->getAsTyped()->getBasicType()) {
case EbtFloat16:
case EbtBFloat16:
case EbtFloat:
case EbtDouble:
newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()),

View File

@@ -3866,6 +3866,31 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"bvec3 notEqual(f16vec3, f16vec3);"
"bvec4 notEqual(f16vec4, f16vec4);"
"bfloat16_t dot(bfloat16_t, bfloat16_t);"
"bfloat16_t dot(bf16vec2, bf16vec2);"
"bfloat16_t dot(bf16vec3, bf16vec3);"
"bfloat16_t dot(bf16vec4, bf16vec4);"
"int16_t bfloat16BitsToIntEXT(bfloat16_t value);"
"i16vec2 bfloat16BitsToIntEXT(bf16vec2 value);"
"i16vec3 bfloat16BitsToIntEXT(bf16vec3 value);"
"i16vec4 bfloat16BitsToIntEXT(bf16vec4 value);"
"uint16_t bfloat16BitsToUintEXT(bfloat16_t value);"
"u16vec2 bfloat16BitsToUintEXT(bf16vec2 value);"
"u16vec3 bfloat16BitsToUintEXT(bf16vec3 value);"
"u16vec4 bfloat16BitsToUintEXT(bf16vec4 value);"
"bfloat16_t intBitsToBFloat16EXT(int16_t value);"
"bf16vec2 intBitsToBFloat16EXT(i16vec2 value);"
"bf16vec3 intBitsToBFloat16EXT(i16vec3 value);"
"bf16vec4 intBitsToBFloat16EXT(i16vec4 value);"
"bfloat16_t uintBitsToBFloat16EXT(uint16_t value);"
"bf16vec2 uintBitsToBFloat16EXT(u16vec2 value);"
"bf16vec3 uintBitsToBFloat16EXT(u16vec3 value);"
"bf16vec4 uintBitsToBFloat16EXT(u16vec4 value);"
"\n");
}
@@ -4618,6 +4643,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
{
"float", "vec2", "vec4",
"float16_t", "f16vec2", "f16vec4",
"bfloat16_t", "bf16vec2", "bf16vec4",
"double", "dvec2", "dvec4",
"int8_t", "i8vec2", "i8vec4",
"int16_t", "i16vec2", "i16vec4",
@@ -9498,6 +9524,14 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("dotAccSatEXT", 1, &E_GL_EXT_integer_dot_product);
symbolTable.setFunctionExtensions("dotPacked4x8AccSatEXT", 1, &E_GL_EXT_integer_dot_product);
}
{
symbolTable.setFunctionExtensions("bfloat16BitsToIntEXT", 1, &E_GL_EXT_bfloat16);
symbolTable.setFunctionExtensions("bfloat16BitsToUintEXT", 1, &E_GL_EXT_bfloat16);
symbolTable.setFunctionExtensions("intBitsToBFloat16EXT", 1, &E_GL_EXT_bfloat16);
symbolTable.setFunctionExtensions("uintBitsToBFloat16EXT", 1, &E_GL_EXT_bfloat16);
}
break;
case EShLangRayGen:
@@ -10466,6 +10500,15 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.relateToOperator("dotPacked4x8AccSatEXT", EOpDotPackedAccSatEXT);
}
// GL_EXT_bfloat16
if ((profile == EEsProfile && version >= 320) ||
(profile != EEsProfile && version >= 450)) {
symbolTable.relateToOperator("bfloat16BitsToIntEXT", EOpFloatBitsToInt);
symbolTable.relateToOperator("bfloat16BitsToUintEXT", EOpFloatBitsToUint);
symbolTable.relateToOperator("intBitsToBFloat16EXT", EOpIntBitsToFloat);
symbolTable.relateToOperator("uintBitsToBFloat16EXT", EOpUintBitsToFloat);
}
// GL_KHR_shader_subgroup
if ((profile == EEsProfile && version >= 310) ||
(profile != EEsProfile && version >= 140)) {

View File

@@ -399,6 +399,7 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
case EOpConstructUint64: newType = EbtUint64; break;
case EOpConstructDouble: newType = EbtDouble; break;
case EOpConstructFloat16: newType = EbtFloat16; break;
case EOpConstructBFloat16: newType = EbtBFloat16; break;
default: break; // some compilers want this
}
@@ -428,7 +429,8 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child,
case EOpConstructBool:
case EOpConstructFloat:
case EOpConstructDouble:
case EOpConstructFloat16: {
case EOpConstructFloat16:
case EOpConstructBFloat16: {
TIntermUnary* unary_node = child->getAsUnaryNode();
if (unary_node != nullptr)
unary_node->updatePrecision();
@@ -569,6 +571,12 @@ bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const
bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& newOp) const
{
// bfloat16_t <-> bool not supported
if ((src == EbtBFloat16 && dst == EbtBool) ||
(dst == EbtBFloat16 && src == EbtBool)) {
return false;
}
if ((isTypeInt(dst) || isTypeFloat(dst) || dst == EbtBool) &&
(isTypeInt(src) || isTypeFloat(src) || src == EbtBool)) {
newOp = EOpConvNumeric;
@@ -596,9 +604,10 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped
node->getBasicType() == EbtInt || node->getBasicType() == EbtUint ||
node->getBasicType() == EbtInt64 || node->getBasicType() == EbtUint64);
bool convertToFloatTypes = (convertTo == EbtFloat16 || convertTo == EbtFloat || convertTo == EbtDouble);
bool convertToFloatTypes = (convertTo == EbtFloat16 || convertTo == EbtBFloat16 || convertTo == EbtFloat || convertTo == EbtDouble);
bool convertFromFloatTypes = (node->getBasicType() == EbtFloat16 ||
node->getBasicType() == EbtBFloat16 ||
node->getBasicType() == EbtFloat ||
node->getBasicType() == EbtDouble);
@@ -848,6 +857,7 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
case EOpConstructUint:
case EOpConstructDouble:
case EOpConstructFloat16:
case EOpConstructBFloat16:
case EOpConstructInt8:
case EOpConstructUint8:
case EOpConstructInt16:
@@ -954,6 +964,9 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt
// changing language sementics on the fly by asking what extensions are in use
// - at the time of this writing (14-Aug-2020), no test results are changed by this.
switch (op) {
case EOpConstructBFloat16:
canPromoteConstant = true;
break;
case EOpConstructFloat16:
canPromoteConstant = numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) ||
numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_float16);
@@ -1256,6 +1269,7 @@ bool TIntermediate::isFPPromotion(TBasicType from, TBasicType to) const
// floating-point promotions
if (to == EbtDouble) {
switch(from) {
case EbtBFloat16:
case EbtFloat16:
case EbtFloat:
return true;
@@ -1348,7 +1362,7 @@ bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const
bool TIntermediate::isFPConversion(TBasicType from, TBasicType to) const
{
if (to == EbtFloat && from == EbtFloat16) {
if (to == EbtFloat && (from == EbtFloat16 || from == EbtBFloat16)) {
return true;
} else {
return false;
@@ -1500,6 +1514,8 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
case EbtFloat16:
return (version >= 400 || numericFeatures.contains(TNumericFeatures::gpu_shader_fp64)) &&
numericFeatures.contains(TNumericFeatures::gpu_shader_half_float);
case EbtBFloat16:
return true;
default:
return false;
}
@@ -1516,6 +1532,8 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat
case EbtFloat16:
return numericFeatures.contains(TNumericFeatures::gpu_shader_half_float) ||
getSource() == EShSourceHlsl;
case EbtBFloat16:
return true;
default:
return false;
}
@@ -1724,6 +1742,10 @@ std::tuple<TBasicType, TBasicType> TIntermediate::getConversionDestinationType(T
(type1 == EbtFloat16 && canImplicitlyPromote(type0, EbtFloat16, op)) ) {
res0 = EbtFloat16;
res1 = EbtFloat16;
} else if ((type0 == EbtBFloat16 && canImplicitlyPromote(type1, EbtBFloat16, op)) ||
(type1 == EbtBFloat16 && canImplicitlyPromote(type0, EbtBFloat16, op)) ) {
res0 = EbtBFloat16;
res1 = EbtBFloat16;
} else if (isTypeInt(type0) && isTypeInt(type1) &&
(canImplicitlyPromote(type0, type1, op) || canImplicitlyPromote(type1, type0, op))) {
if ((isTypeSignedInt(type0) && isTypeSignedInt(type1)) ||
@@ -2020,6 +2042,15 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const
}
}
break;
case EbtBFloat16:
switch (type.getVectorSize()) {
case 1: op = EOpConstructBFloat16; break;
case 2: op = EOpConstructBF16Vec2; break;
case 3: op = EOpConstructBF16Vec3; break;
case 4: op = EOpConstructBF16Vec4; break;
default: break; // some compilers want this
}
break;
case EbtInt8:
switch(type.getVectorSize()) {
case 1: op = EOpConstructInt8; break;
@@ -2429,7 +2460,7 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(bool b, const TSourceLoc&
TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseType, const TSourceLoc& loc, bool literal) const
{
assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16);
assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16 || baseType == EbtBFloat16);
if (isEsProfile() && (baseType == EbtFloat || baseType == EbtFloat16)) {
int exponent = 0;
@@ -3683,6 +3714,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
#define TO_ALL(Get) \
switch (promoteTo) { \
case EbtBFloat16: PROMOTE(setDConst, double, Get); break; \
case EbtFloat16: PROMOTE(setDConst, double, Get); break; \
case EbtFloat: PROMOTE(setDConst, double, Get); break; \
case EbtDouble: PROMOTE(setDConst, double, Get); break; \
@@ -3704,6 +3736,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
case EbtUint: TO_ALL(getUConst); break;
case EbtBool: TO_ALL(getBConst); break;
case EbtFloat16: TO_ALL(getDConst); break;
case EbtBFloat16: TO_ALL(getDConst); break;
case EbtDouble: TO_ALL(getDConst); break;
case EbtInt8: TO_ALL(getI8Const); break;
case EbtInt16: TO_ALL(getI16Const); break;

View File

@@ -132,6 +132,47 @@ protected:
return true; // traverse the whole subtree
}
// To prune semantically dead paths in switch statements with constant expressions.
virtual bool visitSwitch(TVisit /* visit */, TIntermSwitch* node)
{
if (traverseAll)
return true; // traverse all code
TIntermConstantUnion* constant = node->getCondition()->getAsConstantUnion();
if (constant) {
TConstUnion switchValue = constant->getConstArray()[0];
int liveBranch = -1;
const auto& body = node->getBody()->getSequence();
for (unsigned int i = 0; i < body.size(); ++i) {
if (body[i]->getAsBranchNode()) {
if (body[i]->getAsBranchNode()->getFlowOp() == glslang::EOpCase) {
TConstUnion caseValue =
body[i]->getAsBranchNode()->getExpression()->getAsConstantUnion()->getConstArray()[0];
if (switchValue == caseValue.getIConst()) {
liveBranch = (int)i;
break;
}
} else if (body[i]->getAsBranchNode()->getFlowOp() == glslang::EOpDefault) {
liveBranch = (int)i;
}
}
}
if (liveBranch != -1) {
for (int i = liveBranch; i < (int)body.size(); ++i) {
if (body[i]->getAsAggregate()) {
for (auto* inst : body[i]->getAsAggregate()->getSequence()) {
if (inst->getAsBranchNode() && (inst->getAsBranchNode()->getFlowOp() == glslang::EOpBreak))
return false; // found and traversed the live case(s)
inst->traverse(this);
}
}
}
}
return false; // finished traversing all cases
} else
return true; // traverse the whole subtree
}
// Track live functions as well as uniforms, so that we don't visit dead functions
// and only visit each function once.
void addFunctionCall(TIntermAggregate* call)

View File

@@ -906,7 +906,8 @@ TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char*
if (((left->getType().contains16BitFloat() || right->getType().contains16BitFloat()) && !float16Arithmetic()) ||
((left->getType().contains16BitInt() || right->getType().contains16BitInt()) && !int16Arithmetic()) ||
((left->getType().contains8BitInt() || right->getType().contains8BitInt()) && !int8Arithmetic())) {
((left->getType().contains8BitInt() || right->getType().contains8BitInt()) && !int8Arithmetic()) ||
(left->getType().containsBFloat16() || right->getType().containsBFloat16())) {
allowed = false;
}
@@ -933,7 +934,8 @@ TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char*
bool allowed = true;
if ((childNode->getType().contains16BitFloat() && !float16Arithmetic()) ||
(childNode->getType().contains16BitInt() && !int16Arithmetic()) ||
(childNode->getType().contains8BitInt() && !int8Arithmetic())) {
(childNode->getType().contains8BitInt() && !int8Arithmetic()) ||
(childNode->getType().containsBFloat16())) {
allowed = false;
}
@@ -7102,6 +7104,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
case EbtFloat:
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
break;
default:
error(loc, "cannot be applied to this type", "constant_id", "");
@@ -7809,6 +7812,7 @@ void TParseContext::typeParametersCheck(const TSourceLoc& loc, const TPublicType
switch (publicType.typeParameters->basicType) {
case EbtFloat:
case EbtFloat16:
case EbtBFloat16:
case EbtInt:
case EbtInt8:
case EbtInt16:
@@ -8319,6 +8323,9 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
if (type.contains8BitInt())
requireInt8Arithmetic(loc, "qualifier", "(u)int8 types can only be in uniform block or buffer storage");
}
if (type.getBasicType() == EbtBFloat16 &&
(type.getQualifier().storage == EvqVaryingIn || type.getQualifier().storage == EvqVaryingOut))
error(loc, "qualifier", "bfloat16 types not allowed as input/output", "");
if (type.getQualifier().storage == EvqtaskPayloadSharedEXT)
intermediate.addTaskPayloadEXTCount();
@@ -8989,6 +8996,13 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T
}
break;
case EOpConstructBF16Vec2:
case EOpConstructBF16Vec3:
case EOpConstructBF16Vec4:
case EOpConstructBFloat16:
basicOp = EOpConstructBFloat16;
break;
case EOpConstructI8Vec2:
case EOpConstructI8Vec3:
case EOpConstructI8Vec4:

View File

@@ -537,6 +537,11 @@ const std::unordered_map<const char*, int, str_hash, str_eq> KeywordMap {
{"f16mat4x3",F16MAT4X3},
{"f16mat4x4",F16MAT4X4},
{"bfloat16_t",BFLOAT16_T},
{"bf16vec2",BF16VEC2},
{"bf16vec3",BF16VEC3},
{"bf16vec4",BF16VEC4},
{"float32_t",FLOAT32_T},
{"f32vec2",F32VEC2},
{"f32vec3",F32VEC3},
@@ -1454,6 +1459,17 @@ int TScanContext::tokenizeIdentifier()
return identifierOrType();
case BFLOAT16_T:
case BF16VEC2:
case BF16VEC3:
case BF16VEC4:
afterType = true;
if (parseContext.symbolTable.atBuiltInLevel() ||
parseContext.extensionTurnedOn(E_GL_EXT_bfloat16))
return keyword;
return identifierOrType();
case SAMPLERCUBEARRAY:
case SAMPLERCUBEARRAYSHADOW:
case ISAMPLERCUBEARRAY:

View File

@@ -1979,6 +1979,14 @@ bool TProgram::link(EShMessages messages)
error = true;
}
if (messages & EShMsgAST) {
for (int s = 0; s < EShLangCount; ++s) {
if (intermediate[s] == nullptr)
continue;
intermediate[s]->output(*infoSink, true);
}
}
return ! error;
}
@@ -2044,9 +2052,6 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
}
intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0);
if (messages & EShMsgAST)
intermediate[stage]->output(*infoSink, true);
return intermediate[stage]->getNumErrors() == 0;
}
@@ -2070,9 +2075,27 @@ bool TProgram::crossStageCheck(EShMessages messages) {
activeStages.push_back(intermediate[s]);
}
class TFinalLinkTraverser : public TIntermTraverser {
public:
TFinalLinkTraverser() { }
virtual ~TFinalLinkTraverser() { }
virtual void visitSymbol(TIntermSymbol* symbol)
{
// Implicitly size arrays.
// If an unsized array is left as unsized, it effectively
// becomes run-time sized.
symbol->getWritableType().adoptImplicitArraySizes(false);
}
} finalLinkTraverser;
// no extra linking if there is only one stage
if (! (activeStages.size() > 1))
if (! (activeStages.size() > 1)) {
if (activeStages.size() == 1 && activeStages[0]->getTreeRoot()) {
activeStages[0]->getTreeRoot()->traverse(&finalLinkTraverser);
}
return true;
}
// setup temporary tree to hold unfirom objects from different stages
TIntermediate* firstIntermediate = activeStages.front();
@@ -2094,6 +2117,12 @@ bool TProgram::crossStageCheck(EShMessages messages) {
}
error |= uniforms.getNumErrors() != 0;
// update implicit array sizes across shader stages
for (unsigned int i = 0; i < activeStages.size(); ++i) {
activeStages[i]->mergeImplicitArraySizes(*infoSink, uniforms);
activeStages[i]->getTreeRoot()->traverse(&finalLinkTraverser);
}
// copy final definition of global block back into each stage
for (unsigned int i = 0; i < activeStages.size(); ++i) {
// We only want to merge into already existing global uniform blocks.
@@ -2106,8 +2135,8 @@ bool TProgram::crossStageCheck(EShMessages messages) {
// compare cross stage symbols for each stage boundary
for (unsigned int i = 1; i < activeStages.size(); ++i) {
activeStages[i - 1]->checkStageIO(*infoSink, *activeStages[i]);
error |= (activeStages[i - 1]->getNumErrors() != 0);
activeStages[i - 1]->checkStageIO(*infoSink, *activeStages[i], messages);
error |= (activeStages[i - 1]->getNumErrors() != 0 || activeStages[i]->getNumErrors() != 0);
}
// if requested, optimize cross stage IO

View File

@@ -70,6 +70,7 @@ void TType::buildMangledName(TString& mangledName) const
case EbtBool: mangledName += 'b'; break;
case EbtDouble: mangledName += 'd'; break;
case EbtFloat16: mangledName += "f16"; break;
case EbtBFloat16: mangledName += "bf16"; break;
case EbtInt8: mangledName += "i8"; break;
case EbtUint8: mangledName += "u8"; break;
case EbtInt16: mangledName += "i16"; break;

View File

@@ -378,6 +378,7 @@ void TParseVersions::initializeExtensionBehavior()
extensionBehavior[E_GL_EXT_texture_array] = EBhDisable;
extensionBehavior[E_GL_EXT_texture_offset_non_const] = EBhDisable;
extensionBehavior[E_GL_EXT_nontemporal_keyword] = EBhDisable;
extensionBehavior[E_GL_EXT_bfloat16] = EBhDisable;
// OVR extensions
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
@@ -612,6 +613,7 @@ void TParseVersions::getPreamble(std::string& preamble)
"#define GL_EXT_control_flow_attributes2 1\n"
"#define GL_EXT_integer_dot_product 1\n"
"#define GL_EXT_bfloat16 1\n"
;
if (spvVersion.spv == 0) {
@@ -1276,6 +1278,16 @@ void TParseVersions::float16ScalarVectorCheck(const TSourceLoc& loc, const char*
}
}
void TParseVersions::bfloat16ScalarVectorCheck(const TSourceLoc& loc, const char* op, bool builtIn)
{
if (!builtIn) {
const char* const extensions[] = {
E_GL_EXT_bfloat16,
};
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
}
}
// Call for any operation needing GLSL float32 data-type support.
void TParseVersions::explicitFloat32Check(const TSourceLoc& loc, const char* op, bool builtIn)
{

View File

@@ -356,6 +356,8 @@ const char* const E_GL_EXT_texture_shadow_lod = "GL_EXT_texture_shadow_lod";
const char* const E_GL_EXT_integer_dot_product = "GL_EXT_integer_dot_product";
const char* const E_GL_EXT_bfloat16 = "GL_EXT_bfloat16";
// Arrays of extensions for the above AEP duplications
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };

View File

@@ -146,7 +146,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> UTEXTURE2D UTEXTURE3D UTEXTURECUBE UTEXTURE2DARRAY
%token <lex> ATTRIBUTE VARYING
%token <lex> FLOAT16_T FLOAT32_T DOUBLE FLOAT64_T
%token <lex> BFLOAT16_T FLOAT16_T FLOAT32_T DOUBLE FLOAT64_T
%token <lex> INT64_T UINT64_T INT32_T UINT32_T INT16_T UINT16_T INT8_T UINT8_T
%token <lex> I64VEC2 I64VEC3 I64VEC4
%token <lex> U64VEC2 U64VEC3 U64VEC4
@@ -157,6 +157,7 @@ extern int yylex(YYSTYPE*, TParseContext&);
%token <lex> I8VEC2 I8VEC3 I8VEC4
%token <lex> U8VEC2 U8VEC3 U8VEC4
%token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4
%token <lex> BF16VEC2 BF16VEC3 BF16VEC4
%token <lex> F16VEC2 F16VEC3 F16VEC4 F16MAT2 F16MAT3 F16MAT4
%token <lex> F32VEC2 F32VEC3 F32VEC4 F32MAT2 F32MAT3 F32MAT4
%token <lex> F64VEC2 F64VEC3 F64VEC4 F64MAT2 F64MAT3 F64MAT4
@@ -1937,6 +1938,11 @@ type_specifier_nonarray
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtDouble;
}
| BFLOAT16_T {
parseContext.bfloat16ScalarVectorCheck($1.loc, "bfloat16_t", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtBFloat16;
}
| FLOAT16_T {
parseContext.float16ScalarVectorCheck($1.loc, "float16_t", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
@@ -2016,6 +2022,24 @@ type_specifier_nonarray
$$.basicType = EbtDouble;
$$.setVector(4);
}
| BF16VEC2 {
parseContext.bfloat16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtBFloat16;
$$.setVector(2);
}
| BF16VEC3 {
parseContext.bfloat16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtBFloat16;
$$.setVector(3);
}
| BF16VEC4 {
parseContext.bfloat16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());
$$.basicType = EbtBFloat16;
$$.setVector(4);
}
| F16VEC2 {
parseContext.float16ScalarVectorCheck($1.loc, "half float vector", parseContext.symbolTable.atBuiltInLevel());
$$.init($1.loc, parseContext.symbolTable.atGlobalLevel());

File diff suppressed because it is too large Load Diff

View File

@@ -114,413 +114,417 @@ extern int yydebug;
UTEXTURE2DARRAY = 315, /* UTEXTURE2DARRAY */
ATTRIBUTE = 316, /* ATTRIBUTE */
VARYING = 317, /* VARYING */
FLOAT16_T = 318, /* FLOAT16_T */
FLOAT32_T = 319, /* FLOAT32_T */
DOUBLE = 320, /* DOUBLE */
FLOAT64_T = 321, /* FLOAT64_T */
INT64_T = 322, /* INT64_T */
UINT64_T = 323, /* UINT64_T */
INT32_T = 324, /* INT32_T */
UINT32_T = 325, /* UINT32_T */
INT16_T = 326, /* INT16_T */
UINT16_T = 327, /* UINT16_T */
INT8_T = 328, /* INT8_T */
UINT8_T = 329, /* UINT8_T */
I64VEC2 = 330, /* I64VEC2 */
I64VEC3 = 331, /* I64VEC3 */
I64VEC4 = 332, /* I64VEC4 */
U64VEC2 = 333, /* U64VEC2 */
U64VEC3 = 334, /* U64VEC3 */
U64VEC4 = 335, /* U64VEC4 */
I32VEC2 = 336, /* I32VEC2 */
I32VEC3 = 337, /* I32VEC3 */
I32VEC4 = 338, /* I32VEC4 */
U32VEC2 = 339, /* U32VEC2 */
U32VEC3 = 340, /* U32VEC3 */
U32VEC4 = 341, /* U32VEC4 */
I16VEC2 = 342, /* I16VEC2 */
I16VEC3 = 343, /* I16VEC3 */
I16VEC4 = 344, /* I16VEC4 */
U16VEC2 = 345, /* U16VEC2 */
U16VEC3 = 346, /* U16VEC3 */
U16VEC4 = 347, /* U16VEC4 */
I8VEC2 = 348, /* I8VEC2 */
I8VEC3 = 349, /* I8VEC3 */
I8VEC4 = 350, /* I8VEC4 */
U8VEC2 = 351, /* U8VEC2 */
U8VEC3 = 352, /* U8VEC3 */
U8VEC4 = 353, /* U8VEC4 */
DVEC2 = 354, /* DVEC2 */
DVEC3 = 355, /* DVEC3 */
DVEC4 = 356, /* DVEC4 */
DMAT2 = 357, /* DMAT2 */
DMAT3 = 358, /* DMAT3 */
DMAT4 = 359, /* DMAT4 */
F16VEC2 = 360, /* F16VEC2 */
F16VEC3 = 361, /* F16VEC3 */
F16VEC4 = 362, /* F16VEC4 */
F16MAT2 = 363, /* F16MAT2 */
F16MAT3 = 364, /* F16MAT3 */
F16MAT4 = 365, /* F16MAT4 */
F32VEC2 = 366, /* F32VEC2 */
F32VEC3 = 367, /* F32VEC3 */
F32VEC4 = 368, /* F32VEC4 */
F32MAT2 = 369, /* F32MAT2 */
F32MAT3 = 370, /* F32MAT3 */
F32MAT4 = 371, /* F32MAT4 */
F64VEC2 = 372, /* F64VEC2 */
F64VEC3 = 373, /* F64VEC3 */
F64VEC4 = 374, /* F64VEC4 */
F64MAT2 = 375, /* F64MAT2 */
F64MAT3 = 376, /* F64MAT3 */
F64MAT4 = 377, /* F64MAT4 */
DMAT2X2 = 378, /* DMAT2X2 */
DMAT2X3 = 379, /* DMAT2X3 */
DMAT2X4 = 380, /* DMAT2X4 */
DMAT3X2 = 381, /* DMAT3X2 */
DMAT3X3 = 382, /* DMAT3X3 */
DMAT3X4 = 383, /* DMAT3X4 */
DMAT4X2 = 384, /* DMAT4X2 */
DMAT4X3 = 385, /* DMAT4X3 */
DMAT4X4 = 386, /* DMAT4X4 */
F16MAT2X2 = 387, /* F16MAT2X2 */
F16MAT2X3 = 388, /* F16MAT2X3 */
F16MAT2X4 = 389, /* F16MAT2X4 */
F16MAT3X2 = 390, /* F16MAT3X2 */
F16MAT3X3 = 391, /* F16MAT3X3 */
F16MAT3X4 = 392, /* F16MAT3X4 */
F16MAT4X2 = 393, /* F16MAT4X2 */
F16MAT4X3 = 394, /* F16MAT4X3 */
F16MAT4X4 = 395, /* F16MAT4X4 */
F32MAT2X2 = 396, /* F32MAT2X2 */
F32MAT2X3 = 397, /* F32MAT2X3 */
F32MAT2X4 = 398, /* F32MAT2X4 */
F32MAT3X2 = 399, /* F32MAT3X2 */
F32MAT3X3 = 400, /* F32MAT3X3 */
F32MAT3X4 = 401, /* F32MAT3X4 */
F32MAT4X2 = 402, /* F32MAT4X2 */
F32MAT4X3 = 403, /* F32MAT4X3 */
F32MAT4X4 = 404, /* F32MAT4X4 */
F64MAT2X2 = 405, /* F64MAT2X2 */
F64MAT2X3 = 406, /* F64MAT2X3 */
F64MAT2X4 = 407, /* F64MAT2X4 */
F64MAT3X2 = 408, /* F64MAT3X2 */
F64MAT3X3 = 409, /* F64MAT3X3 */
F64MAT3X4 = 410, /* F64MAT3X4 */
F64MAT4X2 = 411, /* F64MAT4X2 */
F64MAT4X3 = 412, /* F64MAT4X3 */
F64MAT4X4 = 413, /* F64MAT4X4 */
ATOMIC_UINT = 414, /* ATOMIC_UINT */
ACCSTRUCTNV = 415, /* ACCSTRUCTNV */
ACCSTRUCTEXT = 416, /* ACCSTRUCTEXT */
RAYQUERYEXT = 417, /* RAYQUERYEXT */
FCOOPMATNV = 418, /* FCOOPMATNV */
ICOOPMATNV = 419, /* ICOOPMATNV */
UCOOPMATNV = 420, /* UCOOPMATNV */
COOPMAT = 421, /* COOPMAT */
COOPVECNV = 422, /* COOPVECNV */
HITOBJECTNV = 423, /* HITOBJECTNV */
HITOBJECTATTRNV = 424, /* HITOBJECTATTRNV */
TENSORLAYOUTNV = 425, /* TENSORLAYOUTNV */
TENSORVIEWNV = 426, /* TENSORVIEWNV */
SAMPLERCUBEARRAY = 427, /* SAMPLERCUBEARRAY */
SAMPLERCUBEARRAYSHADOW = 428, /* SAMPLERCUBEARRAYSHADOW */
ISAMPLERCUBEARRAY = 429, /* ISAMPLERCUBEARRAY */
USAMPLERCUBEARRAY = 430, /* USAMPLERCUBEARRAY */
SAMPLER1D = 431, /* SAMPLER1D */
SAMPLER1DARRAY = 432, /* SAMPLER1DARRAY */
SAMPLER1DARRAYSHADOW = 433, /* SAMPLER1DARRAYSHADOW */
ISAMPLER1D = 434, /* ISAMPLER1D */
SAMPLER1DSHADOW = 435, /* SAMPLER1DSHADOW */
SAMPLER2DRECT = 436, /* SAMPLER2DRECT */
SAMPLER2DRECTSHADOW = 437, /* SAMPLER2DRECTSHADOW */
ISAMPLER2DRECT = 438, /* ISAMPLER2DRECT */
USAMPLER2DRECT = 439, /* USAMPLER2DRECT */
SAMPLERBUFFER = 440, /* SAMPLERBUFFER */
ISAMPLERBUFFER = 441, /* ISAMPLERBUFFER */
USAMPLERBUFFER = 442, /* USAMPLERBUFFER */
SAMPLER2DMS = 443, /* SAMPLER2DMS */
ISAMPLER2DMS = 444, /* ISAMPLER2DMS */
USAMPLER2DMS = 445, /* USAMPLER2DMS */
SAMPLER2DMSARRAY = 446, /* SAMPLER2DMSARRAY */
ISAMPLER2DMSARRAY = 447, /* ISAMPLER2DMSARRAY */
USAMPLER2DMSARRAY = 448, /* USAMPLER2DMSARRAY */
SAMPLEREXTERNALOES = 449, /* SAMPLEREXTERNALOES */
SAMPLEREXTERNAL2DY2YEXT = 450, /* SAMPLEREXTERNAL2DY2YEXT */
ISAMPLER1DARRAY = 451, /* ISAMPLER1DARRAY */
USAMPLER1D = 452, /* USAMPLER1D */
USAMPLER1DARRAY = 453, /* USAMPLER1DARRAY */
F16SAMPLER1D = 454, /* F16SAMPLER1D */
F16SAMPLER2D = 455, /* F16SAMPLER2D */
F16SAMPLER3D = 456, /* F16SAMPLER3D */
F16SAMPLER2DRECT = 457, /* F16SAMPLER2DRECT */
F16SAMPLERCUBE = 458, /* F16SAMPLERCUBE */
F16SAMPLER1DARRAY = 459, /* F16SAMPLER1DARRAY */
F16SAMPLER2DARRAY = 460, /* F16SAMPLER2DARRAY */
F16SAMPLERCUBEARRAY = 461, /* F16SAMPLERCUBEARRAY */
F16SAMPLERBUFFER = 462, /* F16SAMPLERBUFFER */
F16SAMPLER2DMS = 463, /* F16SAMPLER2DMS */
F16SAMPLER2DMSARRAY = 464, /* F16SAMPLER2DMSARRAY */
F16SAMPLER1DSHADOW = 465, /* F16SAMPLER1DSHADOW */
F16SAMPLER2DSHADOW = 466, /* F16SAMPLER2DSHADOW */
F16SAMPLER1DARRAYSHADOW = 467, /* F16SAMPLER1DARRAYSHADOW */
F16SAMPLER2DARRAYSHADOW = 468, /* F16SAMPLER2DARRAYSHADOW */
F16SAMPLER2DRECTSHADOW = 469, /* F16SAMPLER2DRECTSHADOW */
F16SAMPLERCUBESHADOW = 470, /* F16SAMPLERCUBESHADOW */
F16SAMPLERCUBEARRAYSHADOW = 471, /* F16SAMPLERCUBEARRAYSHADOW */
IMAGE1D = 472, /* IMAGE1D */
IIMAGE1D = 473, /* IIMAGE1D */
UIMAGE1D = 474, /* UIMAGE1D */
IMAGE2D = 475, /* IMAGE2D */
IIMAGE2D = 476, /* IIMAGE2D */
UIMAGE2D = 477, /* UIMAGE2D */
IMAGE3D = 478, /* IMAGE3D */
IIMAGE3D = 479, /* IIMAGE3D */
UIMAGE3D = 480, /* UIMAGE3D */
IMAGE2DRECT = 481, /* IMAGE2DRECT */
IIMAGE2DRECT = 482, /* IIMAGE2DRECT */
UIMAGE2DRECT = 483, /* UIMAGE2DRECT */
IMAGECUBE = 484, /* IMAGECUBE */
IIMAGECUBE = 485, /* IIMAGECUBE */
UIMAGECUBE = 486, /* UIMAGECUBE */
IMAGEBUFFER = 487, /* IMAGEBUFFER */
IIMAGEBUFFER = 488, /* IIMAGEBUFFER */
UIMAGEBUFFER = 489, /* UIMAGEBUFFER */
IMAGE1DARRAY = 490, /* IMAGE1DARRAY */
IIMAGE1DARRAY = 491, /* IIMAGE1DARRAY */
UIMAGE1DARRAY = 492, /* UIMAGE1DARRAY */
IMAGE2DARRAY = 493, /* IMAGE2DARRAY */
IIMAGE2DARRAY = 494, /* IIMAGE2DARRAY */
UIMAGE2DARRAY = 495, /* UIMAGE2DARRAY */
IMAGECUBEARRAY = 496, /* IMAGECUBEARRAY */
IIMAGECUBEARRAY = 497, /* IIMAGECUBEARRAY */
UIMAGECUBEARRAY = 498, /* UIMAGECUBEARRAY */
IMAGE2DMS = 499, /* IMAGE2DMS */
IIMAGE2DMS = 500, /* IIMAGE2DMS */
UIMAGE2DMS = 501, /* UIMAGE2DMS */
IMAGE2DMSARRAY = 502, /* IMAGE2DMSARRAY */
IIMAGE2DMSARRAY = 503, /* IIMAGE2DMSARRAY */
UIMAGE2DMSARRAY = 504, /* UIMAGE2DMSARRAY */
F16IMAGE1D = 505, /* F16IMAGE1D */
F16IMAGE2D = 506, /* F16IMAGE2D */
F16IMAGE3D = 507, /* F16IMAGE3D */
F16IMAGE2DRECT = 508, /* F16IMAGE2DRECT */
F16IMAGECUBE = 509, /* F16IMAGECUBE */
F16IMAGE1DARRAY = 510, /* F16IMAGE1DARRAY */
F16IMAGE2DARRAY = 511, /* F16IMAGE2DARRAY */
F16IMAGECUBEARRAY = 512, /* F16IMAGECUBEARRAY */
F16IMAGEBUFFER = 513, /* F16IMAGEBUFFER */
F16IMAGE2DMS = 514, /* F16IMAGE2DMS */
F16IMAGE2DMSARRAY = 515, /* F16IMAGE2DMSARRAY */
I64IMAGE1D = 516, /* I64IMAGE1D */
U64IMAGE1D = 517, /* U64IMAGE1D */
I64IMAGE2D = 518, /* I64IMAGE2D */
U64IMAGE2D = 519, /* U64IMAGE2D */
I64IMAGE3D = 520, /* I64IMAGE3D */
U64IMAGE3D = 521, /* U64IMAGE3D */
I64IMAGE2DRECT = 522, /* I64IMAGE2DRECT */
U64IMAGE2DRECT = 523, /* U64IMAGE2DRECT */
I64IMAGECUBE = 524, /* I64IMAGECUBE */
U64IMAGECUBE = 525, /* U64IMAGECUBE */
I64IMAGEBUFFER = 526, /* I64IMAGEBUFFER */
U64IMAGEBUFFER = 527, /* U64IMAGEBUFFER */
I64IMAGE1DARRAY = 528, /* I64IMAGE1DARRAY */
U64IMAGE1DARRAY = 529, /* U64IMAGE1DARRAY */
I64IMAGE2DARRAY = 530, /* I64IMAGE2DARRAY */
U64IMAGE2DARRAY = 531, /* U64IMAGE2DARRAY */
I64IMAGECUBEARRAY = 532, /* I64IMAGECUBEARRAY */
U64IMAGECUBEARRAY = 533, /* U64IMAGECUBEARRAY */
I64IMAGE2DMS = 534, /* I64IMAGE2DMS */
U64IMAGE2DMS = 535, /* U64IMAGE2DMS */
I64IMAGE2DMSARRAY = 536, /* I64IMAGE2DMSARRAY */
U64IMAGE2DMSARRAY = 537, /* U64IMAGE2DMSARRAY */
TEXTURECUBEARRAY = 538, /* TEXTURECUBEARRAY */
ITEXTURECUBEARRAY = 539, /* ITEXTURECUBEARRAY */
UTEXTURECUBEARRAY = 540, /* UTEXTURECUBEARRAY */
TEXTURE1D = 541, /* TEXTURE1D */
ITEXTURE1D = 542, /* ITEXTURE1D */
UTEXTURE1D = 543, /* UTEXTURE1D */
TEXTURE1DARRAY = 544, /* TEXTURE1DARRAY */
ITEXTURE1DARRAY = 545, /* ITEXTURE1DARRAY */
UTEXTURE1DARRAY = 546, /* UTEXTURE1DARRAY */
TEXTURE2DRECT = 547, /* TEXTURE2DRECT */
ITEXTURE2DRECT = 548, /* ITEXTURE2DRECT */
UTEXTURE2DRECT = 549, /* UTEXTURE2DRECT */
TEXTUREBUFFER = 550, /* TEXTUREBUFFER */
ITEXTUREBUFFER = 551, /* ITEXTUREBUFFER */
UTEXTUREBUFFER = 552, /* UTEXTUREBUFFER */
TEXTURE2DMS = 553, /* TEXTURE2DMS */
ITEXTURE2DMS = 554, /* ITEXTURE2DMS */
UTEXTURE2DMS = 555, /* UTEXTURE2DMS */
TEXTURE2DMSARRAY = 556, /* TEXTURE2DMSARRAY */
ITEXTURE2DMSARRAY = 557, /* ITEXTURE2DMSARRAY */
UTEXTURE2DMSARRAY = 558, /* UTEXTURE2DMSARRAY */
F16TEXTURE1D = 559, /* F16TEXTURE1D */
F16TEXTURE2D = 560, /* F16TEXTURE2D */
F16TEXTURE3D = 561, /* F16TEXTURE3D */
F16TEXTURE2DRECT = 562, /* F16TEXTURE2DRECT */
F16TEXTURECUBE = 563, /* F16TEXTURECUBE */
F16TEXTURE1DARRAY = 564, /* F16TEXTURE1DARRAY */
F16TEXTURE2DARRAY = 565, /* F16TEXTURE2DARRAY */
F16TEXTURECUBEARRAY = 566, /* F16TEXTURECUBEARRAY */
F16TEXTUREBUFFER = 567, /* F16TEXTUREBUFFER */
F16TEXTURE2DMS = 568, /* F16TEXTURE2DMS */
F16TEXTURE2DMSARRAY = 569, /* F16TEXTURE2DMSARRAY */
SUBPASSINPUT = 570, /* SUBPASSINPUT */
SUBPASSINPUTMS = 571, /* SUBPASSINPUTMS */
ISUBPASSINPUT = 572, /* ISUBPASSINPUT */
ISUBPASSINPUTMS = 573, /* ISUBPASSINPUTMS */
USUBPASSINPUT = 574, /* USUBPASSINPUT */
USUBPASSINPUTMS = 575, /* USUBPASSINPUTMS */
F16SUBPASSINPUT = 576, /* F16SUBPASSINPUT */
F16SUBPASSINPUTMS = 577, /* F16SUBPASSINPUTMS */
SPIRV_INSTRUCTION = 578, /* SPIRV_INSTRUCTION */
SPIRV_EXECUTION_MODE = 579, /* SPIRV_EXECUTION_MODE */
SPIRV_EXECUTION_MODE_ID = 580, /* SPIRV_EXECUTION_MODE_ID */
SPIRV_DECORATE = 581, /* SPIRV_DECORATE */
SPIRV_DECORATE_ID = 582, /* SPIRV_DECORATE_ID */
SPIRV_DECORATE_STRING = 583, /* SPIRV_DECORATE_STRING */
SPIRV_TYPE = 584, /* SPIRV_TYPE */
SPIRV_STORAGE_CLASS = 585, /* SPIRV_STORAGE_CLASS */
SPIRV_BY_REFERENCE = 586, /* SPIRV_BY_REFERENCE */
SPIRV_LITERAL = 587, /* SPIRV_LITERAL */
ATTACHMENTEXT = 588, /* ATTACHMENTEXT */
IATTACHMENTEXT = 589, /* IATTACHMENTEXT */
UATTACHMENTEXT = 590, /* UATTACHMENTEXT */
LEFT_OP = 591, /* LEFT_OP */
RIGHT_OP = 592, /* RIGHT_OP */
INC_OP = 593, /* INC_OP */
DEC_OP = 594, /* DEC_OP */
LE_OP = 595, /* LE_OP */
GE_OP = 596, /* GE_OP */
EQ_OP = 597, /* EQ_OP */
NE_OP = 598, /* NE_OP */
AND_OP = 599, /* AND_OP */
OR_OP = 600, /* OR_OP */
XOR_OP = 601, /* XOR_OP */
MUL_ASSIGN = 602, /* MUL_ASSIGN */
DIV_ASSIGN = 603, /* DIV_ASSIGN */
ADD_ASSIGN = 604, /* ADD_ASSIGN */
MOD_ASSIGN = 605, /* MOD_ASSIGN */
LEFT_ASSIGN = 606, /* LEFT_ASSIGN */
RIGHT_ASSIGN = 607, /* RIGHT_ASSIGN */
AND_ASSIGN = 608, /* AND_ASSIGN */
XOR_ASSIGN = 609, /* XOR_ASSIGN */
OR_ASSIGN = 610, /* OR_ASSIGN */
SUB_ASSIGN = 611, /* SUB_ASSIGN */
STRING_LITERAL = 612, /* STRING_LITERAL */
LEFT_PAREN = 613, /* LEFT_PAREN */
RIGHT_PAREN = 614, /* RIGHT_PAREN */
LEFT_BRACKET = 615, /* LEFT_BRACKET */
RIGHT_BRACKET = 616, /* RIGHT_BRACKET */
LEFT_BRACE = 617, /* LEFT_BRACE */
RIGHT_BRACE = 618, /* RIGHT_BRACE */
DOT = 619, /* DOT */
COMMA = 620, /* COMMA */
COLON = 621, /* COLON */
EQUAL = 622, /* EQUAL */
SEMICOLON = 623, /* SEMICOLON */
BANG = 624, /* BANG */
DASH = 625, /* DASH */
TILDE = 626, /* TILDE */
PLUS = 627, /* PLUS */
STAR = 628, /* STAR */
SLASH = 629, /* SLASH */
PERCENT = 630, /* PERCENT */
LEFT_ANGLE = 631, /* LEFT_ANGLE */
RIGHT_ANGLE = 632, /* RIGHT_ANGLE */
VERTICAL_BAR = 633, /* VERTICAL_BAR */
CARET = 634, /* CARET */
AMPERSAND = 635, /* AMPERSAND */
QUESTION = 636, /* QUESTION */
INVARIANT = 637, /* INVARIANT */
HIGH_PRECISION = 638, /* HIGH_PRECISION */
MEDIUM_PRECISION = 639, /* MEDIUM_PRECISION */
LOW_PRECISION = 640, /* LOW_PRECISION */
PRECISION = 641, /* PRECISION */
PACKED = 642, /* PACKED */
RESOURCE = 643, /* RESOURCE */
SUPERP = 644, /* SUPERP */
FLOATCONSTANT = 645, /* FLOATCONSTANT */
INTCONSTANT = 646, /* INTCONSTANT */
UINTCONSTANT = 647, /* UINTCONSTANT */
BOOLCONSTANT = 648, /* BOOLCONSTANT */
IDENTIFIER = 649, /* IDENTIFIER */
TYPE_NAME = 650, /* TYPE_NAME */
CENTROID = 651, /* CENTROID */
IN = 652, /* IN */
OUT = 653, /* OUT */
INOUT = 654, /* INOUT */
STRUCT = 655, /* STRUCT */
VOID = 656, /* VOID */
WHILE = 657, /* WHILE */
BREAK = 658, /* BREAK */
CONTINUE = 659, /* CONTINUE */
DO = 660, /* DO */
ELSE = 661, /* ELSE */
FOR = 662, /* FOR */
IF = 663, /* IF */
DISCARD = 664, /* DISCARD */
RETURN = 665, /* RETURN */
SWITCH = 666, /* SWITCH */
CASE = 667, /* CASE */
DEFAULT = 668, /* DEFAULT */
TERMINATE_INVOCATION = 669, /* TERMINATE_INVOCATION */
TERMINATE_RAY = 670, /* TERMINATE_RAY */
IGNORE_INTERSECTION = 671, /* IGNORE_INTERSECTION */
UNIFORM = 672, /* UNIFORM */
SHARED = 673, /* SHARED */
BUFFER = 674, /* BUFFER */
TILEIMAGEEXT = 675, /* TILEIMAGEEXT */
FLAT = 676, /* FLAT */
SMOOTH = 677, /* SMOOTH */
LAYOUT = 678, /* LAYOUT */
DOUBLECONSTANT = 679, /* DOUBLECONSTANT */
INT16CONSTANT = 680, /* INT16CONSTANT */
UINT16CONSTANT = 681, /* UINT16CONSTANT */
FLOAT16CONSTANT = 682, /* FLOAT16CONSTANT */
INT32CONSTANT = 683, /* INT32CONSTANT */
UINT32CONSTANT = 684, /* UINT32CONSTANT */
INT64CONSTANT = 685, /* INT64CONSTANT */
UINT64CONSTANT = 686, /* UINT64CONSTANT */
SUBROUTINE = 687, /* SUBROUTINE */
DEMOTE = 688, /* DEMOTE */
FUNCTION = 689, /* FUNCTION */
PAYLOADNV = 690, /* PAYLOADNV */
PAYLOADINNV = 691, /* PAYLOADINNV */
HITATTRNV = 692, /* HITATTRNV */
CALLDATANV = 693, /* CALLDATANV */
CALLDATAINNV = 694, /* CALLDATAINNV */
PAYLOADEXT = 695, /* PAYLOADEXT */
PAYLOADINEXT = 696, /* PAYLOADINEXT */
HITATTREXT = 697, /* HITATTREXT */
CALLDATAEXT = 698, /* CALLDATAEXT */
CALLDATAINEXT = 699, /* CALLDATAINEXT */
PATCH = 700, /* PATCH */
SAMPLE = 701, /* SAMPLE */
NONUNIFORM = 702, /* NONUNIFORM */
COHERENT = 703, /* COHERENT */
VOLATILE = 704, /* VOLATILE */
RESTRICT = 705, /* RESTRICT */
READONLY = 706, /* READONLY */
WRITEONLY = 707, /* WRITEONLY */
NONTEMPORAL = 708, /* NONTEMPORAL */
DEVICECOHERENT = 709, /* DEVICECOHERENT */
QUEUEFAMILYCOHERENT = 710, /* QUEUEFAMILYCOHERENT */
WORKGROUPCOHERENT = 711, /* WORKGROUPCOHERENT */
SUBGROUPCOHERENT = 712, /* SUBGROUPCOHERENT */
NONPRIVATE = 713, /* NONPRIVATE */
SHADERCALLCOHERENT = 714, /* SHADERCALLCOHERENT */
NOPERSPECTIVE = 715, /* NOPERSPECTIVE */
EXPLICITINTERPAMD = 716, /* EXPLICITINTERPAMD */
PERVERTEXEXT = 717, /* PERVERTEXEXT */
PERVERTEXNV = 718, /* PERVERTEXNV */
PERPRIMITIVENV = 719, /* PERPRIMITIVENV */
PERVIEWNV = 720, /* PERVIEWNV */
PERTASKNV = 721, /* PERTASKNV */
PERPRIMITIVEEXT = 722, /* PERPRIMITIVEEXT */
TASKPAYLOADWORKGROUPEXT = 723, /* TASKPAYLOADWORKGROUPEXT */
PRECISE = 724 /* PRECISE */
BFLOAT16_T = 318, /* BFLOAT16_T */
FLOAT16_T = 319, /* FLOAT16_T */
FLOAT32_T = 320, /* FLOAT32_T */
DOUBLE = 321, /* DOUBLE */
FLOAT64_T = 322, /* FLOAT64_T */
INT64_T = 323, /* INT64_T */
UINT64_T = 324, /* UINT64_T */
INT32_T = 325, /* INT32_T */
UINT32_T = 326, /* UINT32_T */
INT16_T = 327, /* INT16_T */
UINT16_T = 328, /* UINT16_T */
INT8_T = 329, /* INT8_T */
UINT8_T = 330, /* UINT8_T */
I64VEC2 = 331, /* I64VEC2 */
I64VEC3 = 332, /* I64VEC3 */
I64VEC4 = 333, /* I64VEC4 */
U64VEC2 = 334, /* U64VEC2 */
U64VEC3 = 335, /* U64VEC3 */
U64VEC4 = 336, /* U64VEC4 */
I32VEC2 = 337, /* I32VEC2 */
I32VEC3 = 338, /* I32VEC3 */
I32VEC4 = 339, /* I32VEC4 */
U32VEC2 = 340, /* U32VEC2 */
U32VEC3 = 341, /* U32VEC3 */
U32VEC4 = 342, /* U32VEC4 */
I16VEC2 = 343, /* I16VEC2 */
I16VEC3 = 344, /* I16VEC3 */
I16VEC4 = 345, /* I16VEC4 */
U16VEC2 = 346, /* U16VEC2 */
U16VEC3 = 347, /* U16VEC3 */
U16VEC4 = 348, /* U16VEC4 */
I8VEC2 = 349, /* I8VEC2 */
I8VEC3 = 350, /* I8VEC3 */
I8VEC4 = 351, /* I8VEC4 */
U8VEC2 = 352, /* U8VEC2 */
U8VEC3 = 353, /* U8VEC3 */
U8VEC4 = 354, /* U8VEC4 */
DVEC2 = 355, /* DVEC2 */
DVEC3 = 356, /* DVEC3 */
DVEC4 = 357, /* DVEC4 */
DMAT2 = 358, /* DMAT2 */
DMAT3 = 359, /* DMAT3 */
DMAT4 = 360, /* DMAT4 */
BF16VEC2 = 361, /* BF16VEC2 */
BF16VEC3 = 362, /* BF16VEC3 */
BF16VEC4 = 363, /* BF16VEC4 */
F16VEC2 = 364, /* F16VEC2 */
F16VEC3 = 365, /* F16VEC3 */
F16VEC4 = 366, /* F16VEC4 */
F16MAT2 = 367, /* F16MAT2 */
F16MAT3 = 368, /* F16MAT3 */
F16MAT4 = 369, /* F16MAT4 */
F32VEC2 = 370, /* F32VEC2 */
F32VEC3 = 371, /* F32VEC3 */
F32VEC4 = 372, /* F32VEC4 */
F32MAT2 = 373, /* F32MAT2 */
F32MAT3 = 374, /* F32MAT3 */
F32MAT4 = 375, /* F32MAT4 */
F64VEC2 = 376, /* F64VEC2 */
F64VEC3 = 377, /* F64VEC3 */
F64VEC4 = 378, /* F64VEC4 */
F64MAT2 = 379, /* F64MAT2 */
F64MAT3 = 380, /* F64MAT3 */
F64MAT4 = 381, /* F64MAT4 */
DMAT2X2 = 382, /* DMAT2X2 */
DMAT2X3 = 383, /* DMAT2X3 */
DMAT2X4 = 384, /* DMAT2X4 */
DMAT3X2 = 385, /* DMAT3X2 */
DMAT3X3 = 386, /* DMAT3X3 */
DMAT3X4 = 387, /* DMAT3X4 */
DMAT4X2 = 388, /* DMAT4X2 */
DMAT4X3 = 389, /* DMAT4X3 */
DMAT4X4 = 390, /* DMAT4X4 */
F16MAT2X2 = 391, /* F16MAT2X2 */
F16MAT2X3 = 392, /* F16MAT2X3 */
F16MAT2X4 = 393, /* F16MAT2X4 */
F16MAT3X2 = 394, /* F16MAT3X2 */
F16MAT3X3 = 395, /* F16MAT3X3 */
F16MAT3X4 = 396, /* F16MAT3X4 */
F16MAT4X2 = 397, /* F16MAT4X2 */
F16MAT4X3 = 398, /* F16MAT4X3 */
F16MAT4X4 = 399, /* F16MAT4X4 */
F32MAT2X2 = 400, /* F32MAT2X2 */
F32MAT2X3 = 401, /* F32MAT2X3 */
F32MAT2X4 = 402, /* F32MAT2X4 */
F32MAT3X2 = 403, /* F32MAT3X2 */
F32MAT3X3 = 404, /* F32MAT3X3 */
F32MAT3X4 = 405, /* F32MAT3X4 */
F32MAT4X2 = 406, /* F32MAT4X2 */
F32MAT4X3 = 407, /* F32MAT4X3 */
F32MAT4X4 = 408, /* F32MAT4X4 */
F64MAT2X2 = 409, /* F64MAT2X2 */
F64MAT2X3 = 410, /* F64MAT2X3 */
F64MAT2X4 = 411, /* F64MAT2X4 */
F64MAT3X2 = 412, /* F64MAT3X2 */
F64MAT3X3 = 413, /* F64MAT3X3 */
F64MAT3X4 = 414, /* F64MAT3X4 */
F64MAT4X2 = 415, /* F64MAT4X2 */
F64MAT4X3 = 416, /* F64MAT4X3 */
F64MAT4X4 = 417, /* F64MAT4X4 */
ATOMIC_UINT = 418, /* ATOMIC_UINT */
ACCSTRUCTNV = 419, /* ACCSTRUCTNV */
ACCSTRUCTEXT = 420, /* ACCSTRUCTEXT */
RAYQUERYEXT = 421, /* RAYQUERYEXT */
FCOOPMATNV = 422, /* FCOOPMATNV */
ICOOPMATNV = 423, /* ICOOPMATNV */
UCOOPMATNV = 424, /* UCOOPMATNV */
COOPMAT = 425, /* COOPMAT */
COOPVECNV = 426, /* COOPVECNV */
HITOBJECTNV = 427, /* HITOBJECTNV */
HITOBJECTATTRNV = 428, /* HITOBJECTATTRNV */
TENSORLAYOUTNV = 429, /* TENSORLAYOUTNV */
TENSORVIEWNV = 430, /* TENSORVIEWNV */
SAMPLERCUBEARRAY = 431, /* SAMPLERCUBEARRAY */
SAMPLERCUBEARRAYSHADOW = 432, /* SAMPLERCUBEARRAYSHADOW */
ISAMPLERCUBEARRAY = 433, /* ISAMPLERCUBEARRAY */
USAMPLERCUBEARRAY = 434, /* USAMPLERCUBEARRAY */
SAMPLER1D = 435, /* SAMPLER1D */
SAMPLER1DARRAY = 436, /* SAMPLER1DARRAY */
SAMPLER1DARRAYSHADOW = 437, /* SAMPLER1DARRAYSHADOW */
ISAMPLER1D = 438, /* ISAMPLER1D */
SAMPLER1DSHADOW = 439, /* SAMPLER1DSHADOW */
SAMPLER2DRECT = 440, /* SAMPLER2DRECT */
SAMPLER2DRECTSHADOW = 441, /* SAMPLER2DRECTSHADOW */
ISAMPLER2DRECT = 442, /* ISAMPLER2DRECT */
USAMPLER2DRECT = 443, /* USAMPLER2DRECT */
SAMPLERBUFFER = 444, /* SAMPLERBUFFER */
ISAMPLERBUFFER = 445, /* ISAMPLERBUFFER */
USAMPLERBUFFER = 446, /* USAMPLERBUFFER */
SAMPLER2DMS = 447, /* SAMPLER2DMS */
ISAMPLER2DMS = 448, /* ISAMPLER2DMS */
USAMPLER2DMS = 449, /* USAMPLER2DMS */
SAMPLER2DMSARRAY = 450, /* SAMPLER2DMSARRAY */
ISAMPLER2DMSARRAY = 451, /* ISAMPLER2DMSARRAY */
USAMPLER2DMSARRAY = 452, /* USAMPLER2DMSARRAY */
SAMPLEREXTERNALOES = 453, /* SAMPLEREXTERNALOES */
SAMPLEREXTERNAL2DY2YEXT = 454, /* SAMPLEREXTERNAL2DY2YEXT */
ISAMPLER1DARRAY = 455, /* ISAMPLER1DARRAY */
USAMPLER1D = 456, /* USAMPLER1D */
USAMPLER1DARRAY = 457, /* USAMPLER1DARRAY */
F16SAMPLER1D = 458, /* F16SAMPLER1D */
F16SAMPLER2D = 459, /* F16SAMPLER2D */
F16SAMPLER3D = 460, /* F16SAMPLER3D */
F16SAMPLER2DRECT = 461, /* F16SAMPLER2DRECT */
F16SAMPLERCUBE = 462, /* F16SAMPLERCUBE */
F16SAMPLER1DARRAY = 463, /* F16SAMPLER1DARRAY */
F16SAMPLER2DARRAY = 464, /* F16SAMPLER2DARRAY */
F16SAMPLERCUBEARRAY = 465, /* F16SAMPLERCUBEARRAY */
F16SAMPLERBUFFER = 466, /* F16SAMPLERBUFFER */
F16SAMPLER2DMS = 467, /* F16SAMPLER2DMS */
F16SAMPLER2DMSARRAY = 468, /* F16SAMPLER2DMSARRAY */
F16SAMPLER1DSHADOW = 469, /* F16SAMPLER1DSHADOW */
F16SAMPLER2DSHADOW = 470, /* F16SAMPLER2DSHADOW */
F16SAMPLER1DARRAYSHADOW = 471, /* F16SAMPLER1DARRAYSHADOW */
F16SAMPLER2DARRAYSHADOW = 472, /* F16SAMPLER2DARRAYSHADOW */
F16SAMPLER2DRECTSHADOW = 473, /* F16SAMPLER2DRECTSHADOW */
F16SAMPLERCUBESHADOW = 474, /* F16SAMPLERCUBESHADOW */
F16SAMPLERCUBEARRAYSHADOW = 475, /* F16SAMPLERCUBEARRAYSHADOW */
IMAGE1D = 476, /* IMAGE1D */
IIMAGE1D = 477, /* IIMAGE1D */
UIMAGE1D = 478, /* UIMAGE1D */
IMAGE2D = 479, /* IMAGE2D */
IIMAGE2D = 480, /* IIMAGE2D */
UIMAGE2D = 481, /* UIMAGE2D */
IMAGE3D = 482, /* IMAGE3D */
IIMAGE3D = 483, /* IIMAGE3D */
UIMAGE3D = 484, /* UIMAGE3D */
IMAGE2DRECT = 485, /* IMAGE2DRECT */
IIMAGE2DRECT = 486, /* IIMAGE2DRECT */
UIMAGE2DRECT = 487, /* UIMAGE2DRECT */
IMAGECUBE = 488, /* IMAGECUBE */
IIMAGECUBE = 489, /* IIMAGECUBE */
UIMAGECUBE = 490, /* UIMAGECUBE */
IMAGEBUFFER = 491, /* IMAGEBUFFER */
IIMAGEBUFFER = 492, /* IIMAGEBUFFER */
UIMAGEBUFFER = 493, /* UIMAGEBUFFER */
IMAGE1DARRAY = 494, /* IMAGE1DARRAY */
IIMAGE1DARRAY = 495, /* IIMAGE1DARRAY */
UIMAGE1DARRAY = 496, /* UIMAGE1DARRAY */
IMAGE2DARRAY = 497, /* IMAGE2DARRAY */
IIMAGE2DARRAY = 498, /* IIMAGE2DARRAY */
UIMAGE2DARRAY = 499, /* UIMAGE2DARRAY */
IMAGECUBEARRAY = 500, /* IMAGECUBEARRAY */
IIMAGECUBEARRAY = 501, /* IIMAGECUBEARRAY */
UIMAGECUBEARRAY = 502, /* UIMAGECUBEARRAY */
IMAGE2DMS = 503, /* IMAGE2DMS */
IIMAGE2DMS = 504, /* IIMAGE2DMS */
UIMAGE2DMS = 505, /* UIMAGE2DMS */
IMAGE2DMSARRAY = 506, /* IMAGE2DMSARRAY */
IIMAGE2DMSARRAY = 507, /* IIMAGE2DMSARRAY */
UIMAGE2DMSARRAY = 508, /* UIMAGE2DMSARRAY */
F16IMAGE1D = 509, /* F16IMAGE1D */
F16IMAGE2D = 510, /* F16IMAGE2D */
F16IMAGE3D = 511, /* F16IMAGE3D */
F16IMAGE2DRECT = 512, /* F16IMAGE2DRECT */
F16IMAGECUBE = 513, /* F16IMAGECUBE */
F16IMAGE1DARRAY = 514, /* F16IMAGE1DARRAY */
F16IMAGE2DARRAY = 515, /* F16IMAGE2DARRAY */
F16IMAGECUBEARRAY = 516, /* F16IMAGECUBEARRAY */
F16IMAGEBUFFER = 517, /* F16IMAGEBUFFER */
F16IMAGE2DMS = 518, /* F16IMAGE2DMS */
F16IMAGE2DMSARRAY = 519, /* F16IMAGE2DMSARRAY */
I64IMAGE1D = 520, /* I64IMAGE1D */
U64IMAGE1D = 521, /* U64IMAGE1D */
I64IMAGE2D = 522, /* I64IMAGE2D */
U64IMAGE2D = 523, /* U64IMAGE2D */
I64IMAGE3D = 524, /* I64IMAGE3D */
U64IMAGE3D = 525, /* U64IMAGE3D */
I64IMAGE2DRECT = 526, /* I64IMAGE2DRECT */
U64IMAGE2DRECT = 527, /* U64IMAGE2DRECT */
I64IMAGECUBE = 528, /* I64IMAGECUBE */
U64IMAGECUBE = 529, /* U64IMAGECUBE */
I64IMAGEBUFFER = 530, /* I64IMAGEBUFFER */
U64IMAGEBUFFER = 531, /* U64IMAGEBUFFER */
I64IMAGE1DARRAY = 532, /* I64IMAGE1DARRAY */
U64IMAGE1DARRAY = 533, /* U64IMAGE1DARRAY */
I64IMAGE2DARRAY = 534, /* I64IMAGE2DARRAY */
U64IMAGE2DARRAY = 535, /* U64IMAGE2DARRAY */
I64IMAGECUBEARRAY = 536, /* I64IMAGECUBEARRAY */
U64IMAGECUBEARRAY = 537, /* U64IMAGECUBEARRAY */
I64IMAGE2DMS = 538, /* I64IMAGE2DMS */
U64IMAGE2DMS = 539, /* U64IMAGE2DMS */
I64IMAGE2DMSARRAY = 540, /* I64IMAGE2DMSARRAY */
U64IMAGE2DMSARRAY = 541, /* U64IMAGE2DMSARRAY */
TEXTURECUBEARRAY = 542, /* TEXTURECUBEARRAY */
ITEXTURECUBEARRAY = 543, /* ITEXTURECUBEARRAY */
UTEXTURECUBEARRAY = 544, /* UTEXTURECUBEARRAY */
TEXTURE1D = 545, /* TEXTURE1D */
ITEXTURE1D = 546, /* ITEXTURE1D */
UTEXTURE1D = 547, /* UTEXTURE1D */
TEXTURE1DARRAY = 548, /* TEXTURE1DARRAY */
ITEXTURE1DARRAY = 549, /* ITEXTURE1DARRAY */
UTEXTURE1DARRAY = 550, /* UTEXTURE1DARRAY */
TEXTURE2DRECT = 551, /* TEXTURE2DRECT */
ITEXTURE2DRECT = 552, /* ITEXTURE2DRECT */
UTEXTURE2DRECT = 553, /* UTEXTURE2DRECT */
TEXTUREBUFFER = 554, /* TEXTUREBUFFER */
ITEXTUREBUFFER = 555, /* ITEXTUREBUFFER */
UTEXTUREBUFFER = 556, /* UTEXTUREBUFFER */
TEXTURE2DMS = 557, /* TEXTURE2DMS */
ITEXTURE2DMS = 558, /* ITEXTURE2DMS */
UTEXTURE2DMS = 559, /* UTEXTURE2DMS */
TEXTURE2DMSARRAY = 560, /* TEXTURE2DMSARRAY */
ITEXTURE2DMSARRAY = 561, /* ITEXTURE2DMSARRAY */
UTEXTURE2DMSARRAY = 562, /* UTEXTURE2DMSARRAY */
F16TEXTURE1D = 563, /* F16TEXTURE1D */
F16TEXTURE2D = 564, /* F16TEXTURE2D */
F16TEXTURE3D = 565, /* F16TEXTURE3D */
F16TEXTURE2DRECT = 566, /* F16TEXTURE2DRECT */
F16TEXTURECUBE = 567, /* F16TEXTURECUBE */
F16TEXTURE1DARRAY = 568, /* F16TEXTURE1DARRAY */
F16TEXTURE2DARRAY = 569, /* F16TEXTURE2DARRAY */
F16TEXTURECUBEARRAY = 570, /* F16TEXTURECUBEARRAY */
F16TEXTUREBUFFER = 571, /* F16TEXTUREBUFFER */
F16TEXTURE2DMS = 572, /* F16TEXTURE2DMS */
F16TEXTURE2DMSARRAY = 573, /* F16TEXTURE2DMSARRAY */
SUBPASSINPUT = 574, /* SUBPASSINPUT */
SUBPASSINPUTMS = 575, /* SUBPASSINPUTMS */
ISUBPASSINPUT = 576, /* ISUBPASSINPUT */
ISUBPASSINPUTMS = 577, /* ISUBPASSINPUTMS */
USUBPASSINPUT = 578, /* USUBPASSINPUT */
USUBPASSINPUTMS = 579, /* USUBPASSINPUTMS */
F16SUBPASSINPUT = 580, /* F16SUBPASSINPUT */
F16SUBPASSINPUTMS = 581, /* F16SUBPASSINPUTMS */
SPIRV_INSTRUCTION = 582, /* SPIRV_INSTRUCTION */
SPIRV_EXECUTION_MODE = 583, /* SPIRV_EXECUTION_MODE */
SPIRV_EXECUTION_MODE_ID = 584, /* SPIRV_EXECUTION_MODE_ID */
SPIRV_DECORATE = 585, /* SPIRV_DECORATE */
SPIRV_DECORATE_ID = 586, /* SPIRV_DECORATE_ID */
SPIRV_DECORATE_STRING = 587, /* SPIRV_DECORATE_STRING */
SPIRV_TYPE = 588, /* SPIRV_TYPE */
SPIRV_STORAGE_CLASS = 589, /* SPIRV_STORAGE_CLASS */
SPIRV_BY_REFERENCE = 590, /* SPIRV_BY_REFERENCE */
SPIRV_LITERAL = 591, /* SPIRV_LITERAL */
ATTACHMENTEXT = 592, /* ATTACHMENTEXT */
IATTACHMENTEXT = 593, /* IATTACHMENTEXT */
UATTACHMENTEXT = 594, /* UATTACHMENTEXT */
LEFT_OP = 595, /* LEFT_OP */
RIGHT_OP = 596, /* RIGHT_OP */
INC_OP = 597, /* INC_OP */
DEC_OP = 598, /* DEC_OP */
LE_OP = 599, /* LE_OP */
GE_OP = 600, /* GE_OP */
EQ_OP = 601, /* EQ_OP */
NE_OP = 602, /* NE_OP */
AND_OP = 603, /* AND_OP */
OR_OP = 604, /* OR_OP */
XOR_OP = 605, /* XOR_OP */
MUL_ASSIGN = 606, /* MUL_ASSIGN */
DIV_ASSIGN = 607, /* DIV_ASSIGN */
ADD_ASSIGN = 608, /* ADD_ASSIGN */
MOD_ASSIGN = 609, /* MOD_ASSIGN */
LEFT_ASSIGN = 610, /* LEFT_ASSIGN */
RIGHT_ASSIGN = 611, /* RIGHT_ASSIGN */
AND_ASSIGN = 612, /* AND_ASSIGN */
XOR_ASSIGN = 613, /* XOR_ASSIGN */
OR_ASSIGN = 614, /* OR_ASSIGN */
SUB_ASSIGN = 615, /* SUB_ASSIGN */
STRING_LITERAL = 616, /* STRING_LITERAL */
LEFT_PAREN = 617, /* LEFT_PAREN */
RIGHT_PAREN = 618, /* RIGHT_PAREN */
LEFT_BRACKET = 619, /* LEFT_BRACKET */
RIGHT_BRACKET = 620, /* RIGHT_BRACKET */
LEFT_BRACE = 621, /* LEFT_BRACE */
RIGHT_BRACE = 622, /* RIGHT_BRACE */
DOT = 623, /* DOT */
COMMA = 624, /* COMMA */
COLON = 625, /* COLON */
EQUAL = 626, /* EQUAL */
SEMICOLON = 627, /* SEMICOLON */
BANG = 628, /* BANG */
DASH = 629, /* DASH */
TILDE = 630, /* TILDE */
PLUS = 631, /* PLUS */
STAR = 632, /* STAR */
SLASH = 633, /* SLASH */
PERCENT = 634, /* PERCENT */
LEFT_ANGLE = 635, /* LEFT_ANGLE */
RIGHT_ANGLE = 636, /* RIGHT_ANGLE */
VERTICAL_BAR = 637, /* VERTICAL_BAR */
CARET = 638, /* CARET */
AMPERSAND = 639, /* AMPERSAND */
QUESTION = 640, /* QUESTION */
INVARIANT = 641, /* INVARIANT */
HIGH_PRECISION = 642, /* HIGH_PRECISION */
MEDIUM_PRECISION = 643, /* MEDIUM_PRECISION */
LOW_PRECISION = 644, /* LOW_PRECISION */
PRECISION = 645, /* PRECISION */
PACKED = 646, /* PACKED */
RESOURCE = 647, /* RESOURCE */
SUPERP = 648, /* SUPERP */
FLOATCONSTANT = 649, /* FLOATCONSTANT */
INTCONSTANT = 650, /* INTCONSTANT */
UINTCONSTANT = 651, /* UINTCONSTANT */
BOOLCONSTANT = 652, /* BOOLCONSTANT */
IDENTIFIER = 653, /* IDENTIFIER */
TYPE_NAME = 654, /* TYPE_NAME */
CENTROID = 655, /* CENTROID */
IN = 656, /* IN */
OUT = 657, /* OUT */
INOUT = 658, /* INOUT */
STRUCT = 659, /* STRUCT */
VOID = 660, /* VOID */
WHILE = 661, /* WHILE */
BREAK = 662, /* BREAK */
CONTINUE = 663, /* CONTINUE */
DO = 664, /* DO */
ELSE = 665, /* ELSE */
FOR = 666, /* FOR */
IF = 667, /* IF */
DISCARD = 668, /* DISCARD */
RETURN = 669, /* RETURN */
SWITCH = 670, /* SWITCH */
CASE = 671, /* CASE */
DEFAULT = 672, /* DEFAULT */
TERMINATE_INVOCATION = 673, /* TERMINATE_INVOCATION */
TERMINATE_RAY = 674, /* TERMINATE_RAY */
IGNORE_INTERSECTION = 675, /* IGNORE_INTERSECTION */
UNIFORM = 676, /* UNIFORM */
SHARED = 677, /* SHARED */
BUFFER = 678, /* BUFFER */
TILEIMAGEEXT = 679, /* TILEIMAGEEXT */
FLAT = 680, /* FLAT */
SMOOTH = 681, /* SMOOTH */
LAYOUT = 682, /* LAYOUT */
DOUBLECONSTANT = 683, /* DOUBLECONSTANT */
INT16CONSTANT = 684, /* INT16CONSTANT */
UINT16CONSTANT = 685, /* UINT16CONSTANT */
FLOAT16CONSTANT = 686, /* FLOAT16CONSTANT */
INT32CONSTANT = 687, /* INT32CONSTANT */
UINT32CONSTANT = 688, /* UINT32CONSTANT */
INT64CONSTANT = 689, /* INT64CONSTANT */
UINT64CONSTANT = 690, /* UINT64CONSTANT */
SUBROUTINE = 691, /* SUBROUTINE */
DEMOTE = 692, /* DEMOTE */
FUNCTION = 693, /* FUNCTION */
PAYLOADNV = 694, /* PAYLOADNV */
PAYLOADINNV = 695, /* PAYLOADINNV */
HITATTRNV = 696, /* HITATTRNV */
CALLDATANV = 697, /* CALLDATANV */
CALLDATAINNV = 698, /* CALLDATAINNV */
PAYLOADEXT = 699, /* PAYLOADEXT */
PAYLOADINEXT = 700, /* PAYLOADINEXT */
HITATTREXT = 701, /* HITATTREXT */
CALLDATAEXT = 702, /* CALLDATAEXT */
CALLDATAINEXT = 703, /* CALLDATAINEXT */
PATCH = 704, /* PATCH */
SAMPLE = 705, /* SAMPLE */
NONUNIFORM = 706, /* NONUNIFORM */
COHERENT = 707, /* COHERENT */
VOLATILE = 708, /* VOLATILE */
RESTRICT = 709, /* RESTRICT */
READONLY = 710, /* READONLY */
WRITEONLY = 711, /* WRITEONLY */
NONTEMPORAL = 712, /* NONTEMPORAL */
DEVICECOHERENT = 713, /* DEVICECOHERENT */
QUEUEFAMILYCOHERENT = 714, /* QUEUEFAMILYCOHERENT */
WORKGROUPCOHERENT = 715, /* WORKGROUPCOHERENT */
SUBGROUPCOHERENT = 716, /* SUBGROUPCOHERENT */
NONPRIVATE = 717, /* NONPRIVATE */
SHADERCALLCOHERENT = 718, /* SHADERCALLCOHERENT */
NOPERSPECTIVE = 719, /* NOPERSPECTIVE */
EXPLICITINTERPAMD = 720, /* EXPLICITINTERPAMD */
PERVERTEXEXT = 721, /* PERVERTEXEXT */
PERVERTEXNV = 722, /* PERVERTEXNV */
PERPRIMITIVENV = 723, /* PERPRIMITIVENV */
PERVIEWNV = 724, /* PERVIEWNV */
PERTASKNV = 725, /* PERTASKNV */
PERPRIMITIVEEXT = 726, /* PERPRIMITIVEEXT */
TASKPAYLOADWORKGROUPEXT = 727, /* TASKPAYLOADWORKGROUPEXT */
PRECISE = 728 /* PRECISE */
};
typedef enum yytokentype yytoken_kind_t;
#endif
@@ -568,7 +572,7 @@ union YYSTYPE
glslang::TTypeParameters* typeParameters;
} interm;
#line 572 "MachineIndependent/glslang_tab.cpp.h"
#line 576 "MachineIndependent/glslang_tab.cpp.h"
};
typedef union YYSTYPE YYSTYPE;

View File

@@ -625,6 +625,10 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
case EOpConstructBMat4x2: out.debug << "Construct bmat4x2"; break;
case EOpConstructBMat4x3: out.debug << "Construct bmat4x3"; break;
case EOpConstructBMat4x4: out.debug << "Construct bmat4"; break;
case EOpConstructBFloat16: out.debug << "Construct bfloat16_t"; break;
case EOpConstructBF16Vec2: out.debug << "Construct bf16vec2"; break;
case EOpConstructBF16Vec3: out.debug << "Construct bf16vec3"; break;
case EOpConstructBF16Vec4: out.debug << "Construct bf16vec4"; break;
case EOpConstructFloat16: out.debug << "Construct float16_t"; break;
case EOpConstructF16Vec2: out.debug << "Construct f16vec2"; break;
case EOpConstructF16Vec3: out.debug << "Construct f16vec3"; break;
@@ -1159,6 +1163,7 @@ static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const
case EbtFloat:
case EbtDouble:
case EbtFloat16:
case EbtBFloat16:
OutputDouble(out, constUnion[i].getDConst(), extra);
out.debug << "\n";
break;

View File

@@ -57,9 +57,12 @@ namespace glslang {
//
// Link-time error emitter.
//
void TIntermediate::error(TInfoSink& infoSink, const char* message, EShLanguage unitStage)
void TIntermediate::error(TInfoSink& infoSink, const TSourceLoc* loc, EShMessages messages, const char* message,
EShLanguage unitStage)
{
infoSink.info.prefix(EPrefixError);
if (loc)
infoSink.info.location(*loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
if (unitStage == EShLangCount)
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
else if (language == EShLangCount)
@@ -71,9 +74,12 @@ void TIntermediate::error(TInfoSink& infoSink, const char* message, EShLanguage
}
// Link-time warning.
void TIntermediate::warn(TInfoSink& infoSink, const char* message, EShLanguage unitStage)
void TIntermediate::warn(TInfoSink& infoSink, const TSourceLoc* loc, EShMessages messages, const char* message,
EShLanguage unitStage)
{
infoSink.info.prefix(EPrefixWarning);
if (loc)
infoSink.info.location(*loc, messages & EShMsgAbsolutePath, messages & EShMsgDisplayErrorColumn);
if (unitStage == EShLangCount)
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
else if (language == EShLangCount)
@@ -143,10 +149,43 @@ static bool isSameSymbol(TIntermSymbol* symbol1, TIntermSymbol* symbol2) {
return true;
return false;
}
//
// merge implicit array sizes for uniform/buffer objects
//
void TIntermediate::mergeImplicitArraySizes(TInfoSink&, TIntermediate& unit) {
if (unit.treeRoot == nullptr || treeRoot == nullptr)
return;
// Get the linker-object lists
TIntermSequence& linkerObjects = findLinkerObjects()->getSequence();
TIntermSequence unitLinkerObjects = unit.findLinkerObjects()->getSequence();
// filter unitLinkerObjects to only contain uniforms
auto end = std::remove_if(unitLinkerObjects.begin(), unitLinkerObjects.end(),
[](TIntermNode* node) {return node->getAsSymbolNode()->getQualifier().storage != EvqUniform &&
node->getAsSymbolNode()->getQualifier().storage != EvqBuffer; });
unitLinkerObjects.resize(end - unitLinkerObjects.begin());
std::size_t initialNumLinkerObjects = linkerObjects.size();
for (unsigned int unitLinkObj = 0; unitLinkObj < unitLinkerObjects.size(); ++unitLinkObj) {
for (std::size_t linkObj = 0; linkObj < initialNumLinkerObjects; ++linkObj) {
TIntermSymbol* symbol = linkerObjects[linkObj]->getAsSymbolNode();
TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode();
assert(symbol && unitSymbol);
if (isSameSymbol(symbol, unitSymbol)) {
// Update implicit array sizes
mergeImplicitArraySizes(symbol->getWritableType(), unitSymbol->getType());
}
}
}
}
//
// do error checking on the shader boundary in / out vars
//
void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) {
void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit, EShMessages messages) {
if (unit.treeRoot == nullptr || treeRoot == nullptr)
return;
@@ -167,7 +206,171 @@ void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) {
// do matching and error checking
mergeLinkerObjects(infoSink, linkerObjects, unitLinkerObjects, unit.getStage());
// TODO: final check; make sure that any statically used `in` have matching `out` written to
if ((messages & EShMsgValidateCrossStageIO) == 0)
return;
// The OpenGL Shading Language, Version 4.60.8 (https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf)
// 4.3.4 Input Variables
// Only the input variables that are statically read need to be written by the previous stage; it is
// allowed to have superfluous declarations of input variables. This is shown in the following table.
// +------------------------------------------------------------------------------------------------+
// | Treatment of Mismatched Input | Consuming Shader (input variables) |
// | Variables |---------------------------------------------------------|
// | | No | Declared but no | Declared and Static Use |
// | | Declaration | Static Use | |
// |--------------------------------------+-------------+-----------------+-------------------------|
// | Generating Shader | No Declaration | Allowed | Allowed | Link-Time Error |
// | (output variables) |-----------------+-------------+-----------------+-------------------------|
// | | Declared but no | Allowed | Allowed | Allowed (values are |
// | | Static Use | | | undefined) |
// | |-----------------+-------------+-----------------+-------------------------|
// | | Declared and | Allowed | Allowed | Allowed (values are |
// | | Static Use | | | potentially undefined) |
// +------------------------------------------------------------------------------------------------+
// Consumption errors are based on static use only. Compilation may generate a warning, but not an
// error, for any dynamic use the compiler can deduce that might cause consumption of undefined values.
// TODO: implement support for geometry passthrough
if (getGeoPassthroughEXT()) {
unit.warn(infoSink, "GL_NV_geometry_shader_passthrough is enabled, skipping cross-stage IO validation",
getStage());
return;
}
class TIOTraverser : public TLiveTraverser {
public:
TIOTraverser(TIntermediate& i, bool all, TIntermSequence& sequence, TStorageQualifier storage)
: TLiveTraverser(i, all, true, false, false), sequence(sequence), storage(storage)
{
}
virtual void visitSymbol(TIntermSymbol* symbol)
{
if (symbol->getQualifier().storage == storage)
sequence.push_back(symbol);
}
private:
TIntermSequence& sequence;
TStorageQualifier storage;
};
// live symbols only
TIntermSequence unitLiveInputs;
TIOTraverser unitTraverser(unit, false, unitLiveInputs, EvqVaryingIn);
unitTraverser.pushFunction(unit.getEntryPointMangledName().c_str());
while (! unitTraverser.destinations.empty()) {
TIntermNode* destination = unitTraverser.destinations.back();
unitTraverser.destinations.pop_back();
destination->traverse(&unitTraverser);
}
// all symbols
TIntermSequence allOutputs;
TIOTraverser traverser(*this, true, allOutputs, EvqVaryingOut);
getTreeRoot()->traverse(&traverser);
std::unordered_set<int> outputLocations;
for (auto& output : allOutputs) {
if (output->getAsSymbolNode()->getBasicType() == EbtBlock) {
int lastLocation = -1;
if (output->getAsSymbolNode()->getQualifier().hasLocation())
lastLocation = output->getAsSymbolNode()->getQualifier().layoutLocation;
const TTypeList* members = output->getAsSymbolNode()->getType().getStruct();
for (auto& member : *members) {
int location = lastLocation;
if (member.type->getQualifier().hasLocation())
location = member.type->getQualifier().layoutLocation;
if (location != -1) {
int locationSize = TIntermediate::computeTypeLocationSize(*member.type, getStage());
for (int i = 0; i < locationSize; ++i)
outputLocations.insert(location + i);
lastLocation = location + locationSize;
}
}
} else {
int locationSize = TIntermediate::computeTypeLocationSize(output->getAsSymbolNode()->getType(), getStage());
for (int i = 0; i < locationSize; ++i)
outputLocations.insert(output->getAsSymbolNode()->getQualifier().layoutLocation + i);
}
}
// remove unitStage inputs with matching outputs in the current stage
auto liveEnd = std::remove_if(
unitLiveInputs.begin(), unitLiveInputs.end(), [this, &allOutputs, &outputLocations](TIntermNode* input) {
// ignore built-ins
if (input->getAsSymbolNode()->getAccessName().compare(0, 3, "gl_") == 0)
return true;
// try to match by location
if (input->getAsSymbolNode()->getQualifier().hasLocation() &&
outputLocations.find(input->getAsSymbolNode()->getQualifier().layoutLocation) != outputLocations.end())
return true;
if (input->getAsSymbolNode()->getBasicType() == EbtBlock) {
int lastLocation = -1;
if (input->getAsSymbolNode()->getQualifier().hasLocation())
lastLocation = input->getAsSymbolNode()->getQualifier().layoutLocation;
const TTypeList* members = input->getAsSymbolNode()->getType().getStruct();
for (auto& member : *members) {
int location = lastLocation;
if (member.type->getQualifier().hasLocation())
location = member.type->getQualifier().layoutLocation;
if (location != -1) {
int locationSize = TIntermediate::computeTypeLocationSize(*member.type, getStage());
for (int i = 0; i < locationSize; ++i)
if (outputLocations.find(location + i) != outputLocations.end())
return true;
lastLocation = location + locationSize;
}
}
}
// otherwise, try to match by name
return std::any_of(allOutputs.begin(), allOutputs.end(), [input](TIntermNode* output) {
return output->getAsSymbolNode()->getAccessName() == input->getAsSymbolNode()->getAccessName();
});
});
unitLiveInputs.resize(liveEnd - unitLiveInputs.begin());
// check remaining loose unitStage inputs for a matching output block member
liveEnd = std::remove_if(unitLiveInputs.begin(), unitLiveInputs.end(), [&allOutputs](TIntermNode* input) {
return std::any_of(allOutputs.begin(), allOutputs.end(), [input](TIntermNode* output) {
if (output->getAsSymbolNode()->getBasicType() != EbtBlock)
return false;
const TTypeList* members = output->getAsSymbolNode()->getType().getStruct();
return std::any_of(members->begin(), members->end(), [input](TTypeLoc type) {
return type.type->getFieldName() == input->getAsSymbolNode()->getName();
});
});
});
unitLiveInputs.resize(liveEnd - unitLiveInputs.begin());
// finally, check remaining unitStage block inputs for a matching loose output
liveEnd = std::remove_if(
unitLiveInputs.begin(), unitLiveInputs.end(), [&allOutputs](TIntermNode* input) {
if (input->getAsSymbolNode()->getBasicType() != EbtBlock)
return false;
// liveness isn't tracked per member so finding any one live member is the best we can do
const TTypeList* members = input->getAsSymbolNode()->getType().getStruct();
return std::any_of(members->begin(), members->end(), [allOutputs](TTypeLoc type) {
return std::any_of(allOutputs.begin(), allOutputs.end(), [&type](TIntermNode* output) {
return type.type->getFieldName() == output->getAsSymbolNode()->getName();
});
});
});
unitLiveInputs.resize(liveEnd - unitLiveInputs.begin());
// any remaining unitStage inputs have no matching output
std::for_each(unitLiveInputs.begin(), unitLiveInputs.end(), [&](TIntermNode* input) {
unit.error(infoSink, &input->getLoc(), messages,
"Preceding stage has no matching declaration for statically used input:", getStage());
infoSink.info << " "
<< input->getAsSymbolNode()->getType().getCompleteString(
true, true, false, true, input->getAsSymbolNode()->getAccessName())
<< "\n";
});
// TODO: warn about statically read inputs with outputs declared but not written to
}
void TIntermediate::optimizeStageIO(TInfoSink&, TIntermediate& unit)
@@ -859,11 +1062,32 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
}
else if (symbol->getWritableType().isImplicitlySizedArray() && unitSymbol->getType().isSizedArray()) {
if (symbol->getWritableType().getImplicitArraySize() > unitSymbol->getType().getOuterArraySize())
error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.");
error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.", unitStage);
}
else if (unitSymbol->getType().isImplicitlySizedArray() && symbol->getWritableType().isSizedArray()) {
if (unitSymbol->getType().getImplicitArraySize() > symbol->getWritableType().getOuterArraySize())
error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.");
error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.", unitStage);
}
if (symbol->getType().isStruct() && unitSymbol->getType().isStruct() &&
symbol->getType().getStruct()->size() == unitSymbol->getType().getStruct()->size()) {
for (int i = 0; i < (int)symbol->getType().getStruct()->size(); ++i) {
auto& type = (*symbol->getWritableType().getStruct())[i];
auto& unitType = (*unitSymbol->getWritableType().getStruct())[i];
if (type.type->isImplicitlySizedArray() && unitType.type->isImplicitlySizedArray()) {
if (unitType.type->getImplicitArraySize() > type.type->getImplicitArraySize())
type.type->updateImplicitArraySize(unitType.type->getImplicitArraySize());
}
else if (type.type->isImplicitlySizedArray() && unitType.type->isSizedArray()) {
if (type.type->getImplicitArraySize() > unitType.type->getOuterArraySize())
error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.", unitStage);
}
else if (type.type->isSizedArray() && unitType.type->isImplicitlySizedArray()) {
if (type.type->getOuterArraySize() < unitType.type->getImplicitArraySize())
error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders.", unitStage);
}
}
}
// Update implicit array sizes
@@ -1316,7 +1540,8 @@ void TIntermediate::sharedBlockCheck(TInfoSink& infoSink)
// Do final link-time error checking of a complete (merged) intermediate representation.
// (Much error checking was done during merging).
//
// Also, lock in defaults of things not set, including array sizes.
// Also, lock in defaults of things not set.
// Defer adopting implicit array sizes to later, after all stages are merged.
//
void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
{
@@ -1477,23 +1702,6 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
error(infoSink, "Unknown Stage.");
break;
}
// Process the tree for any node-specific work.
class TFinalLinkTraverser : public TIntermTraverser {
public:
TFinalLinkTraverser() { }
virtual ~TFinalLinkTraverser() { }
virtual void visitSymbol(TIntermSymbol* symbol)
{
// Implicitly size arrays.
// If an unsized array is left as unsized, it effectively
// becomes run-time sized.
symbol->getWritableType().adoptImplicitArraySizes(false);
}
} finalLinkTraverser;
treeRoot->traverse(&finalLinkTraverser);
}
//
@@ -2176,6 +2384,7 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
case EbtUint64:
case EbtDouble: size = 8; return 8;
case EbtFloat16: size = 2; return 2;
case EbtBFloat16: size = 2; return 2;
case EbtInt8:
case EbtUint8: size = 1; return 1;
case EbtInt16:

View File

@@ -1053,7 +1053,8 @@ public:
void mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& unit, bool mergeExistingOnly);
void mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit);
void checkStageIO(TInfoSink&, TIntermediate&);
void mergeImplicitArraySizes(TInfoSink& infoSink, TIntermediate& unit);
void checkStageIO(TInfoSink&, TIntermediate&, EShMessages);
void optimizeStageIO(TInfoSink&, TIntermediate&);
bool buildConvertOp(TBasicType dst, TBasicType src, TOperator& convertOp) const;
@@ -1124,8 +1125,14 @@ public:
protected:
TIntermSymbol* addSymbol(long long Id, const TString&, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
void error(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount);
void warn(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount);
void error(TInfoSink& infoSink, const TSourceLoc* loc, EShMessages messages, const char*, EShLanguage unitStage = EShLangCount);
void error(TInfoSink& infoSink, const char* message, EShLanguage unitStage = EShLangCount) {
error(infoSink, nullptr, EShMsgDefault, message, unitStage);
}
void warn(TInfoSink& infoSink, const TSourceLoc* loc, EShMessages, const char*, EShLanguage unitStage = EShLangCount);
void warn(TInfoSink& infoSink, const char* message, EShLanguage unitStage = EShLangCount) {
warn(infoSink, nullptr, EShMsgDefault, message, unitStage);
}
void mergeCallGraphs(TInfoSink&, TIntermediate&);
void mergeModes(TInfoSink&, TIntermediate&);
void mergeTrees(TInfoSink&, TIntermediate&);

View File

@@ -103,6 +103,7 @@ public:
virtual void doubleCheck(const TSourceLoc&, const char* op);
virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void float16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual void bfloat16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
virtual bool float16Arithmetic();
virtual void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc);
virtual void int16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);

View File

@@ -273,6 +273,7 @@ enum EShMessages : unsigned {
EShMsgAbsolutePath = (1 << 16), // Output Absolute path for messages
EShMsgDisplayErrorColumn = (1 << 17), // Display error message column aswell as line
EShMsgLinkTimeOptimization = (1 << 18), // perform cross-stage optimizations during linking
EShMsgValidateCrossStageIO = (1 << 19), // validate shader inputs have matching outputs in previous stage
LAST_ELEMENT_MARKER(EShMsgCount),
};