TOOLS: updated glslang
parent
21e8219853
commit
e351951b16
1
Makefile
1
Makefile
|
@ -169,6 +169,7 @@ update-glslang:
|
|||
cp $(UPDATEDIR)/glslang.sync/gen_extension_headers.py tools/glslang/
|
||||
cp $(UPDATEDIR)/glslang.sync/*.cmake tools/glslang/
|
||||
cp $(UPDATEDIR)/glslang.sync/README* tools/glslang/
|
||||
dos2unix tools/glslang/SPIRV/spirv.hpp
|
||||
|
||||
update-simplecpp:
|
||||
$(call UPDATE_GIT,simplecpp,https://github.com/danmar/simplecpp.git)
|
||||
|
|
|
@ -19,8 +19,8 @@ See issue #1964.
|
|||
|
||||
If people are only using this location to get spirv.hpp, I recommend they get that from [SPIRV-Headers](https://github.com/KhronosGroup/SPIRV-Headers) instead.
|
||||
|
||||
[![Build Status](https://travis-ci.org/KhronosGroup/glslang.svg?branch=master)](https://travis-ci.org/KhronosGroup/glslang)
|
||||
[![Build status](https://ci.appveyor.com/api/projects/status/q6fi9cb0qnhkla68/branch/master?svg=true)](https://ci.appveyor.com/project/Khronoswebmaster/glslang/branch/master)
|
||||
[![appveyor status](https://ci.appveyor.com/api/projects/status/q6fi9cb0qnhkla68/branch/master?svg=true)](https://ci.appveyor.com/project/Khronoswebmaster/glslang/branch/master)
|
||||
![Continuous Deployment](https://github.com/KhronosGroup/glslang/actions/workflows/continuous_deployment.yml/badge.svg)
|
||||
|
||||
# Glslang Components and Status
|
||||
|
||||
|
|
|
@ -1256,8 +1256,10 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T
|
|||
if (type.getBasicType() == glslang::EbtRayQuery)
|
||||
return spv::StorageClassPrivate;
|
||||
#ifndef GLSLANG_WEB
|
||||
if (type.getQualifier().isSpirvByReference())
|
||||
return spv::StorageClassFunction;
|
||||
if (type.getQualifier().isSpirvByReference()) {
|
||||
if (type.getQualifier().isParamInput() || type.getQualifier().isParamOutput())
|
||||
return spv::StorageClassFunction;
|
||||
}
|
||||
#endif
|
||||
if (type.getQualifier().isPipeInput())
|
||||
return spv::StorageClassInput;
|
||||
|
@ -1662,9 +1664,22 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
|||
|
||||
case EShLangCompute:
|
||||
builder.addCapability(spv::CapabilityShader);
|
||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
|
||||
glslangIntermediate->getLocalSize(1),
|
||||
glslangIntermediate->getLocalSize(2));
|
||||
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
|
||||
std::vector<spv::Id> dimConstId;
|
||||
for (int dim = 0; dim < 3; ++dim) {
|
||||
bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet);
|
||||
dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst));
|
||||
if (specConst) {
|
||||
builder.addDecoration(dimConstId.back(), spv::DecorationSpecId,
|
||||
glslangIntermediate->getLocalSizeSpecId(dim));
|
||||
}
|
||||
}
|
||||
builder.addExecutionModeId(shaderEntry, spv::ExecutionModeLocalSizeId, dimConstId);
|
||||
} else {
|
||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
|
||||
glslangIntermediate->getLocalSize(1),
|
||||
glslangIntermediate->getLocalSize(2));
|
||||
}
|
||||
if (glslangIntermediate->getLayoutDerivativeModeNone() == glslang::LayoutDerivativeGroupQuads) {
|
||||
builder.addCapability(spv::CapabilityComputeDerivativeGroupQuadsNV);
|
||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeDerivativeGroupQuadsNV);
|
||||
|
@ -1768,9 +1783,22 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
|||
case EShLangMeshNV:
|
||||
builder.addCapability(spv::CapabilityMeshShadingNV);
|
||||
builder.addExtension(spv::E_SPV_NV_mesh_shader);
|
||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
|
||||
glslangIntermediate->getLocalSize(1),
|
||||
glslangIntermediate->getLocalSize(2));
|
||||
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
|
||||
std::vector<spv::Id> dimConstId;
|
||||
for (int dim = 0; dim < 3; ++dim) {
|
||||
bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet);
|
||||
dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst));
|
||||
if (specConst) {
|
||||
builder.addDecoration(dimConstId.back(), spv::DecorationSpecId,
|
||||
glslangIntermediate->getLocalSizeSpecId(dim));
|
||||
}
|
||||
}
|
||||
builder.addExecutionModeId(shaderEntry, spv::ExecutionModeLocalSizeId, dimConstId);
|
||||
} else {
|
||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
|
||||
glslangIntermediate->getLocalSize(1),
|
||||
glslangIntermediate->getLocalSize(2));
|
||||
}
|
||||
if (glslangIntermediate->getStage() == EShLangMeshNV) {
|
||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices,
|
||||
glslangIntermediate->getVertices());
|
||||
|
@ -3777,7 +3805,16 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
|
|||
|
||||
switch (node->getFlowOp()) {
|
||||
case glslang::EOpKill:
|
||||
builder.makeStatementTerminator(spv::OpKill, "post-discard");
|
||||
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
|
||||
if (glslangIntermediate->getSource() == glslang::EShSourceHlsl) {
|
||||
builder.addCapability(spv::CapabilityDemoteToHelperInvocation);
|
||||
builder.createNoResultOp(spv::OpDemoteToHelperInvocationEXT);
|
||||
} else {
|
||||
builder.makeStatementTerminator(spv::OpTerminateInvocation, "post-terminate-invocation");
|
||||
}
|
||||
} else {
|
||||
builder.makeStatementTerminator(spv::OpKill, "post-discard");
|
||||
}
|
||||
break;
|
||||
case glslang::EOpTerminateInvocation:
|
||||
builder.addExtension(spv::E_SPV_KHR_terminate_invocation);
|
||||
|
@ -4148,23 +4185,23 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|||
const auto& spirvType = type.getSpirvType();
|
||||
const auto& spirvInst = spirvType.spirvInst;
|
||||
|
||||
std::vector<spv::Id> operands;
|
||||
std::vector<spv::IdImmediate> operands;
|
||||
for (const auto& typeParam : spirvType.typeParams) {
|
||||
// Constant expression
|
||||
if (typeParam.constant->isLiteral()) {
|
||||
if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
|
||||
float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
|
||||
unsigned literal = *reinterpret_cast<unsigned*>(&floatValue);
|
||||
operands.push_back(literal);
|
||||
operands.push_back({false, literal});
|
||||
} else if (typeParam.constant->getBasicType() == glslang::EbtInt) {
|
||||
unsigned literal = typeParam.constant->getConstArray()[0].getIConst();
|
||||
operands.push_back(literal);
|
||||
operands.push_back({false, literal});
|
||||
} else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
|
||||
unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
|
||||
operands.push_back(literal);
|
||||
operands.push_back({false, literal});
|
||||
} else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
|
||||
unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
|
||||
operands.push_back(literal);
|
||||
operands.push_back({false, literal});
|
||||
} else if (typeParam.constant->getBasicType() == glslang::EbtString) {
|
||||
auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
|
||||
unsigned literal = 0;
|
||||
|
@ -4176,7 +4213,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|||
*(literalPtr++) = ch;
|
||||
++charCount;
|
||||
if (charCount == 4) {
|
||||
operands.push_back(literal);
|
||||
operands.push_back({false, literal});
|
||||
literalPtr = reinterpret_cast<char*>(&literal);
|
||||
charCount = 0;
|
||||
}
|
||||
|
@ -4186,20 +4223,17 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|||
if (charCount > 0) {
|
||||
for (; charCount < 4; ++charCount)
|
||||
*(literalPtr++) = 0;
|
||||
operands.push_back(literal);
|
||||
operands.push_back({false, literal});
|
||||
}
|
||||
} else
|
||||
assert(0); // Unexpected type
|
||||
} else
|
||||
operands.push_back(createSpvConstant(*typeParam.constant));
|
||||
operands.push_back({true, createSpvConstant(*typeParam.constant)});
|
||||
}
|
||||
|
||||
if (spirvInst.set == "")
|
||||
spvType = builder.createOp(static_cast<spv::Op>(spirvInst.id), spv::NoType, operands);
|
||||
else {
|
||||
spvType = builder.createBuiltinCall(
|
||||
spv::NoType, getExtBuiltins(spirvInst.set.c_str()), spirvInst.id, operands);
|
||||
}
|
||||
assert(spirvInst.set == ""); // Currently, couldn't be extended instructions.
|
||||
spvType = builder.makeGenericType(static_cast<spv::Op>(spirvInst.id), operands);
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -8717,8 +8751,18 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|||
builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutOffset);
|
||||
}
|
||||
|
||||
if (symbol->getQualifier().hasLocation())
|
||||
builder.addDecoration(id, spv::DecorationLocation, symbol->getQualifier().layoutLocation);
|
||||
if (symbol->getQualifier().hasLocation()) {
|
||||
if (!(glslangIntermediate->isRayTracingStage() && glslangIntermediate->IsRequestedExtension(glslang::E_GL_EXT_ray_tracing)
|
||||
&& (builder.getStorageClass(id) == spv::StorageClassRayPayloadKHR ||
|
||||
builder.getStorageClass(id) == spv::StorageClassIncomingRayPayloadKHR ||
|
||||
builder.getStorageClass(id) == spv::StorageClassCallableDataKHR ||
|
||||
builder.getStorageClass(id) == spv::StorageClassIncomingCallableDataKHR))) {
|
||||
// Location values are used to link TraceRayKHR and ExecuteCallableKHR to corresponding variables
|
||||
// but are not valid in SPIRV since they are supported only for Input/Output Storage classes.
|
||||
builder.addDecoration(id, spv::DecorationLocation, symbol->getQualifier().layoutLocation);
|
||||
}
|
||||
}
|
||||
|
||||
builder.addDecoration(id, TranslateInvariantDecoration(symbol->getType().getQualifier()));
|
||||
if (symbol->getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
|
||||
builder.addCapability(spv::CapabilityGeometryStreams);
|
||||
|
@ -8752,7 +8796,16 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
|
|||
|
||||
// add built-in variable decoration
|
||||
if (builtIn != spv::BuiltInMax) {
|
||||
builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
|
||||
// WorkgroupSize deprecated in spirv1.6
|
||||
if (glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_6 ||
|
||||
builtIn != spv::BuiltInWorkgroupSize)
|
||||
builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
|
||||
}
|
||||
|
||||
// Add volatile decoration to HelperInvocation for spirv1.6 and beyond
|
||||
if (builtIn == spv::BuiltInHelperInvocation &&
|
||||
glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
|
||||
builder.addDecoration(id, spv::DecorationVolatile);
|
||||
}
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
|
|
|
@ -297,15 +297,21 @@ namespace spv {
|
|||
std::string spirvbin_t::literalString(unsigned word) const
|
||||
{
|
||||
std::string literal;
|
||||
const spirword_t * pos = spv.data() + word;
|
||||
|
||||
literal.reserve(16);
|
||||
|
||||
const char* bytes = reinterpret_cast<const char*>(spv.data() + word);
|
||||
|
||||
while (bytes && *bytes)
|
||||
literal += *bytes++;
|
||||
|
||||
return literal;
|
||||
do {
|
||||
spirword_t word = *pos;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
char c = word & 0xff;
|
||||
if (c == '\0')
|
||||
return literal;
|
||||
literal += c;
|
||||
word >>= 8;
|
||||
}
|
||||
pos++;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
void spirvbin_t::applyMap()
|
||||
|
|
|
@ -427,6 +427,37 @@ Id Builder::makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols)
|
|||
return type->getResultId();
|
||||
}
|
||||
|
||||
Id Builder::makeGenericType(spv::Op opcode, std::vector<spv::IdImmediate>& operands)
|
||||
{
|
||||
// try to find it
|
||||
Instruction* type;
|
||||
for (int t = 0; t < (int)groupedTypes[opcode].size(); ++t) {
|
||||
type = groupedTypes[opcode][t];
|
||||
if (type->getNumOperands() != operands.size())
|
||||
continue; // Number mismatch, find next
|
||||
|
||||
bool match = true;
|
||||
for (int op = 0; match && op < operands.size(); ++op) {
|
||||
match = (operands[op].isId ? type->getIdOperand(op) : type->getImmediateOperand(op)) == operands[op].word;
|
||||
}
|
||||
if (match)
|
||||
return type->getResultId();
|
||||
}
|
||||
|
||||
// not found, make it
|
||||
type = new Instruction(getUniqueId(), NoType, opcode);
|
||||
for (int op = 0; op < operands.size(); ++op) {
|
||||
if (operands[op].isId)
|
||||
type->addIdOperand(operands[op].word);
|
||||
else
|
||||
type->addImmediateOperand(operands[op].word);
|
||||
}
|
||||
groupedTypes[opcode].push_back(type);
|
||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
||||
module.mapInstruction(type);
|
||||
|
||||
return type->getResultId();
|
||||
}
|
||||
|
||||
// TODO: performance: track arrays per stride
|
||||
// If a stride is supplied (non-zero) make an array.
|
||||
|
|
|
@ -181,6 +181,7 @@ public:
|
|||
Id makeSamplerType();
|
||||
Id makeSampledImageType(Id imageType);
|
||||
Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);
|
||||
Id makeGenericType(spv::Op opcode, std::vector<spv::IdImmediate>& operands);
|
||||
|
||||
// accelerationStructureNV type
|
||||
Id makeAccelerationStructureType();
|
||||
|
|
|
@ -68,6 +68,26 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog
|
|||
}
|
||||
case glslang::EShTargetVulkan_1_2:
|
||||
return spv_target_env::SPV_ENV_VULKAN_1_2;
|
||||
case glslang::EShTargetUniversal:
|
||||
switch (spvVersion.spv) {
|
||||
case EShTargetSpv_1_0:
|
||||
return spv_target_env::SPV_ENV_UNIVERSAL_1_0;
|
||||
case EShTargetSpv_1_1:
|
||||
return spv_target_env::SPV_ENV_UNIVERSAL_1_1;
|
||||
case EShTargetSpv_1_2:
|
||||
return spv_target_env::SPV_ENV_UNIVERSAL_1_2;
|
||||
case EShTargetSpv_1_3:
|
||||
return spv_target_env::SPV_ENV_UNIVERSAL_1_3;
|
||||
case EShTargetSpv_1_4:
|
||||
return spv_target_env::SPV_ENV_UNIVERSAL_1_4;
|
||||
case EShTargetSpv_1_5:
|
||||
return spv_target_env::SPV_ENV_UNIVERSAL_1_5;
|
||||
case EShTargetSpv_1_6:
|
||||
return spv_target_env::SPV_ENV_UNIVERSAL_1_6;
|
||||
default:
|
||||
logger->missingFunctionality("Target version for SPIRV-Tools validator");
|
||||
return spv_target_env::SPV_ENV_UNIVERSAL_1_6;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@
|
|||
#include <stack>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <utility>
|
||||
|
||||
#include "disassemble.h"
|
||||
#include "doc.h"
|
||||
|
@ -100,6 +101,7 @@ protected:
|
|||
void outputMask(OperandClass operandClass, unsigned mask);
|
||||
void disassembleImmediates(int numOperands);
|
||||
void disassembleIds(int numOperands);
|
||||
std::pair<int, std::string> decodeString();
|
||||
int disassembleString();
|
||||
void disassembleInstruction(Id resultId, Id typeId, Op opCode, int numOperands);
|
||||
|
||||
|
@ -290,31 +292,44 @@ void SpirvStream::disassembleIds(int numOperands)
|
|||
}
|
||||
}
|
||||
|
||||
// return the number of operands consumed by the string
|
||||
int SpirvStream::disassembleString()
|
||||
// decode string from words at current position (non-consuming)
|
||||
std::pair<int, std::string> SpirvStream::decodeString()
|
||||
{
|
||||
int startWord = word;
|
||||
|
||||
out << " \"";
|
||||
|
||||
const char* wordString;
|
||||
std::string res;
|
||||
int wordPos = word;
|
||||
char c;
|
||||
bool done = false;
|
||||
|
||||
do {
|
||||
unsigned int content = stream[word];
|
||||
wordString = (const char*)&content;
|
||||
unsigned int content = stream[wordPos];
|
||||
for (int charCount = 0; charCount < 4; ++charCount) {
|
||||
if (*wordString == 0) {
|
||||
c = content & 0xff;
|
||||
content >>= 8;
|
||||
if (c == '\0') {
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
out << *(wordString++);
|
||||
res += c;
|
||||
}
|
||||
++word;
|
||||
} while (! done);
|
||||
++wordPos;
|
||||
} while(! done);
|
||||
|
||||
return std::make_pair(wordPos - word, res);
|
||||
}
|
||||
|
||||
// return the number of operands consumed by the string
|
||||
int SpirvStream::disassembleString()
|
||||
{
|
||||
out << " \"";
|
||||
|
||||
std::pair<int, std::string> decoderes = decodeString();
|
||||
|
||||
out << decoderes.second;
|
||||
out << "\"";
|
||||
|
||||
return word - startWord;
|
||||
word += decoderes.first;
|
||||
|
||||
return decoderes.first;
|
||||
}
|
||||
|
||||
void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, int numOperands)
|
||||
|
@ -331,7 +346,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
|||
nextNestedControl = 0;
|
||||
}
|
||||
} else if (opCode == OpExtInstImport) {
|
||||
idDescriptor[resultId] = (const char*)(&stream[word]);
|
||||
idDescriptor[resultId] = decodeString().second;
|
||||
}
|
||||
else {
|
||||
if (resultId != 0 && idDescriptor[resultId].size() == 0) {
|
||||
|
@ -428,7 +443,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
|
|||
--numOperands;
|
||||
// Get names for printing "(XXX)" for readability, *after* this id
|
||||
if (opCode == OpName)
|
||||
idDescriptor[stream[word - 1]] = (const char*)(&stream[word]);
|
||||
idDescriptor[stream[word - 1]] = decodeString().second;
|
||||
break;
|
||||
case OperandVariableIds:
|
||||
disassembleIds(numOperands);
|
||||
|
|
|
@ -900,6 +900,12 @@ const char* CapabilityString(int info)
|
|||
case CapabilityDeviceGroup: return "DeviceGroup";
|
||||
case CapabilityMultiView: return "MultiView";
|
||||
|
||||
case CapabilityDenormPreserve: return "DenormPreserve";
|
||||
case CapabilityDenormFlushToZero: return "DenormFlushToZero";
|
||||
case CapabilitySignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve";
|
||||
case CapabilityRoundingModeRTE: return "RoundingModeRTE";
|
||||
case CapabilityRoundingModeRTZ: return "RoundingModeRTZ";
|
||||
|
||||
case CapabilityStencilExportEXT: return "StencilExportEXT";
|
||||
|
||||
case CapabilityFloat16ImageAMD: return "Float16ImageAMD";
|
||||
|
|
|
@ -1003,6 +1003,7 @@ enum Capability {
|
|||
CapabilityFragmentShaderShadingRateInterlockEXT = 5372,
|
||||
CapabilityShaderSMBuiltinsNV = 5373,
|
||||
CapabilityFragmentShaderPixelInterlockEXT = 5378,
|
||||
CapabilityDemoteToHelperInvocation = 5379,
|
||||
CapabilityDemoteToHelperInvocationEXT = 5379,
|
||||
CapabilitySubgroupShuffleINTEL = 5568,
|
||||
CapabilitySubgroupBufferBlockIOINTEL = 5569,
|
||||
|
@ -2311,4 +2312,3 @@ inline FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShad
|
|||
} // end namespace spv
|
||||
|
||||
#endif // #ifndef spirv_HPP
|
||||
|
||||
|
|
|
@ -111,27 +111,23 @@ public:
|
|||
|
||||
void addStringOperand(const char* str)
|
||||
{
|
||||
unsigned int word;
|
||||
char* wordString = (char*)&word;
|
||||
char* wordPtr = wordString;
|
||||
int charCount = 0;
|
||||
unsigned int word = 0;
|
||||
unsigned int shiftAmount = 0;
|
||||
char c;
|
||||
|
||||
do {
|
||||
c = *(str++);
|
||||
*(wordPtr++) = c;
|
||||
++charCount;
|
||||
if (charCount == 4) {
|
||||
word |= ((unsigned int)c) << shiftAmount;
|
||||
shiftAmount += 8;
|
||||
if (shiftAmount == 32) {
|
||||
addImmediateOperand(word);
|
||||
wordPtr = wordString;
|
||||
charCount = 0;
|
||||
word = 0;
|
||||
shiftAmount = 0;
|
||||
}
|
||||
} while (c != 0);
|
||||
|
||||
// deal with partial last word
|
||||
if (charCount > 0) {
|
||||
// pad with 0s
|
||||
for (; charCount < 4; ++charCount)
|
||||
*(wordPtr++) = 0;
|
||||
if (shiftAmount > 0) {
|
||||
addImmediateOperand(word);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -177,6 +177,7 @@ const char* shaderStageName = nullptr;
|
|||
const char* variableName = nullptr;
|
||||
bool HlslEnable16BitTypes = false;
|
||||
bool HlslDX9compatible = false;
|
||||
bool HlslDxPositionW = false;
|
||||
bool DumpBuiltinSymbols = false;
|
||||
std::vector<std::string> IncludeDirectoryList;
|
||||
|
||||
|
@ -662,6 +663,8 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
|||
HlslEnable16BitTypes = true;
|
||||
} else if (lowerword == "hlsl-dx9-compatible") {
|
||||
HlslDX9compatible = true;
|
||||
} else if (lowerword == "hlsl-dx-position-w") {
|
||||
HlslDxPositionW = true;
|
||||
} else if (lowerword == "auto-sampled-textures") {
|
||||
autoSampledTextures = true;
|
||||
} else if (lowerword == "invert-y" || // synonyms
|
||||
|
@ -785,9 +788,13 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
|||
} else if (strcmp(argv[1], "spirv1.5") == 0) {
|
||||
TargetLanguage = glslang::EShTargetSpv;
|
||||
TargetVersion = glslang::EShTargetSpv_1_5;
|
||||
} else if (strcmp(argv[1], "spirv1.6") == 0) {
|
||||
TargetLanguage = glslang::EShTargetSpv;
|
||||
TargetVersion = glslang::EShTargetSpv_1_6;
|
||||
} else
|
||||
Error("--target-env expected one of: vulkan1.0, vulkan1.1, vulkan1.2, opengl,\n"
|
||||
"spirv1.0, spirv1.1, spirv1.2, spirv1.3, spirv1.4, or spirv1.5");
|
||||
Error("--target-env expected one of: vulkan1.0, vulkan1.1, vulkan1.2,\n"
|
||||
"opengl, spirv1.0, spirv1.1, spirv1.2, spirv1.3,\n"
|
||||
"spirv1.4, spirv1.5 or spirv1.6");
|
||||
}
|
||||
bumpArg();
|
||||
} else if (lowerword == "undef-macro" ||
|
||||
|
@ -1284,6 +1291,9 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||
if (Options & EOptionInvertY)
|
||||
shader->setInvertY(true);
|
||||
|
||||
if (HlslDxPositionW)
|
||||
shader->setDxPositionW(true);
|
||||
|
||||
// Set up the environment, some subsettings take precedence over earlier
|
||||
// ways of setting things.
|
||||
if (Options & EOptionSpv) {
|
||||
|
@ -1847,6 +1857,8 @@ void usage()
|
|||
" --hlsl-dx9-compatible interprets sampler declarations as a\n"
|
||||
" texture/sampler combo like DirectX9 would,\n"
|
||||
" and recognizes DirectX9-specific semantics\n"
|
||||
" --hlsl-dx-position-w W component of SV_Position in HLSL fragment\n"
|
||||
" shaders compatible with DirectX\n"
|
||||
" --invert-y | --iy invert position.Y output in vertex shader\n"
|
||||
" --keep-uncalled | --ku don't eliminate uncalled functions\n"
|
||||
" --nan-clamp favor non-NaN operand in min, max, and clamp\n"
|
||||
|
@ -1922,8 +1934,9 @@ void usage()
|
|||
" --sep synonym for --source-entrypoint\n"
|
||||
" --stdin read from stdin instead of from a file;\n"
|
||||
" requires providing the shader stage using -S\n"
|
||||
" --target-env {vulkan1.0 | vulkan1.1 | vulkan1.2 | opengl | \n"
|
||||
" spirv1.0 | spirv1.1 | spirv1.2 | spirv1.3 | spirv1.4 | spirv1.5}\n"
|
||||
" --target-env {vulkan1.0 | vulkan1.1 | vulkan1.2 | opengl |\n"
|
||||
" spirv1.0 | spirv1.1 | spirv1.2 | spirv1.3 | spirv1.4 |\n"
|
||||
" spirv1.5 | spirv1.6}\n"
|
||||
" Set the execution environment that the\n"
|
||||
" generated code will be executed in.\n"
|
||||
" Defaults to:\n"
|
||||
|
|
|
@ -244,6 +244,8 @@ c_shader_target_language_version(glslang_target_language_version_t target_langua
|
|||
return glslang::EShTargetSpv_1_4;
|
||||
case GLSLANG_TARGET_SPV_1_5:
|
||||
return glslang::EShTargetSpv_1_5;
|
||||
case GLSLANG_TARGET_SPV_1_6:
|
||||
return glslang::EShTargetSpv_1_6;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -269,6 +271,8 @@ static glslang::EShTargetClientVersion c_shader_client_version(glslang_target_cl
|
|||
switch (client_version) {
|
||||
case GLSLANG_TARGET_VULKAN_1_1:
|
||||
return glslang::EShTargetVulkan_1_1;
|
||||
case GLSLANG_TARGET_VULKAN_1_2:
|
||||
return glslang::EShTargetVulkan_1_2;
|
||||
case GLSLANG_TARGET_OPENGL_450:
|
||||
return glslang::EShTargetOpenGL_450;
|
||||
default:
|
||||
|
@ -344,6 +348,34 @@ GLSLANG_EXPORT glslang_shader_t* glslang_shader_create(const glslang_input_t* in
|
|||
return shader;
|
||||
}
|
||||
|
||||
GLSLANG_EXPORT void glslang_shader_shift_binding(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base)
|
||||
{
|
||||
const glslang::TResourceType res_type = glslang::TResourceType(res);
|
||||
shader->shader->setShiftBinding(res_type, base);
|
||||
}
|
||||
|
||||
GLSLANG_EXPORT void glslang_shader_shift_binding_for_set(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base, unsigned int set)
|
||||
{
|
||||
const glslang::TResourceType res_type = glslang::TResourceType(res);
|
||||
shader->shader->setShiftBindingForSet(res_type, base, set);
|
||||
}
|
||||
|
||||
GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int options)
|
||||
{
|
||||
if (options & GLSLANG_SHADER_AUTO_MAP_BINDINGS) {
|
||||
shader->shader->setAutoMapBindings(true);
|
||||
}
|
||||
|
||||
if (options & GLSLANG_SHADER_AUTO_MAP_LOCATIONS) {
|
||||
shader->shader->setAutoMapLocations(true);
|
||||
}
|
||||
|
||||
if (options & GLSLANG_SHADER_VULKAN_RULES_RELAXED) {
|
||||
shader->shader->setEnvInputVulkanRulesRelaxed();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader)
|
||||
{
|
||||
return shader->preprocessedGLSL.c_str();
|
||||
|
@ -417,6 +449,11 @@ GLSLANG_EXPORT int glslang_program_link(glslang_program_t* program, int messages
|
|||
return (int)program->program->link((EShMessages)messages);
|
||||
}
|
||||
|
||||
GLSLANG_EXPORT int glslang_program_map_io(glslang_program_t* program)
|
||||
{
|
||||
return (int)program->program->mapIO();
|
||||
}
|
||||
|
||||
GLSLANG_EXPORT const char* glslang_program_get_info_log(glslang_program_t* program)
|
||||
{
|
||||
return program->program->getInfoLog();
|
||||
|
|
|
@ -36,19 +36,3 @@
|
|||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
//
|
||||
|
||||
#extension GL_EXT_spirv_intrinsics : enable
|
||||
#extension GL_ARB_gpu_shader_int64 : enable
|
||||
|
||||
uvec2 clockRealtime2x32EXT(void) {
|
||||
spirv_instruction (extensions = ["SPV_KHR_shader_clock"], capabilities = [5055], id = 5056)
|
||||
uvec2 clockRealtime2x32EXT_internal(uint scope);
|
||||
|
||||
return clockRealtime2x32EXT_internal(1 /*Device scope*/);
|
||||
}
|
||||
|
||||
uint64_t clockRealtimeEXT(void) {
|
||||
spirv_instruction (extensions = ["SPV_KHR_shader_clock"], capabilities = [5055], id = 5056)
|
||||
uint64_t clockRealtimeEXT_internal(uint scope);
|
||||
|
||||
return clockRealtimeEXT_internal(1 /*Device scope*/);
|
||||
}
|
|
@ -2167,8 +2167,21 @@ TIntermNode* HlslParseContext::transformEntryPoint(const TSourceLoc& loc, TFunct
|
|||
TIntermSymbol* arg = intermediate.addSymbol(*argVars.back());
|
||||
handleFunctionArgument(&callee, callingArgs, arg);
|
||||
if (param.type->getQualifier().isParamInput()) {
|
||||
intermediate.growAggregate(synthBody, handleAssign(loc, EOpAssign, arg,
|
||||
intermediate.addSymbol(**inputIt)));
|
||||
TIntermTyped* input = intermediate.addSymbol(**inputIt);
|
||||
if (input->getType().getQualifier().builtIn == EbvFragCoord && intermediate.getDxPositionW()) {
|
||||
// Replace FragCoord W with reciprocal
|
||||
auto pos_xyz = handleDotDereference(loc, input, "xyz");
|
||||
auto pos_w = handleDotDereference(loc, input, "w");
|
||||
auto one = intermediate.addConstantUnion(1.0, EbtFloat, loc);
|
||||
auto recip_w = intermediate.addBinaryMath(EOpDiv, one, pos_w, loc);
|
||||
TIntermAggregate* dst = new TIntermAggregate(EOpConstructVec4);
|
||||
dst->getSequence().push_back(pos_xyz);
|
||||
dst->getSequence().push_back(recip_w);
|
||||
dst->setType(TType(EbtFloat, EvqTemporary, 4));
|
||||
dst->setLoc(loc);
|
||||
input = dst;
|
||||
}
|
||||
intermediate.growAggregate(synthBody, handleAssign(loc, EOpAssign, arg, input));
|
||||
inputIt++;
|
||||
}
|
||||
if (param.type->getQualifier().storage == EvqUniform) {
|
||||
|
@ -2452,6 +2465,62 @@ void HlslParseContext::handleFunctionArgument(TFunction* function,
|
|||
arguments = newArg;
|
||||
}
|
||||
|
||||
// FragCoord may require special loading: we can optionally reciprocate W.
|
||||
TIntermTyped* HlslParseContext::assignFromFragCoord(const TSourceLoc& loc, TOperator op,
|
||||
TIntermTyped* left, TIntermTyped* right)
|
||||
{
|
||||
// If we are not asked for reciprocal W, use a plain old assign.
|
||||
if (!intermediate.getDxPositionW())
|
||||
return intermediate.addAssign(op, left, right, loc);
|
||||
|
||||
// If we get here, we should reciprocate W.
|
||||
TIntermAggregate* assignList = nullptr;
|
||||
|
||||
// If this is a complex rvalue, we don't want to dereference it many times. Create a temporary.
|
||||
TVariable* rhsTempVar = nullptr;
|
||||
rhsTempVar = makeInternalVariable("@fragcoord", right->getType());
|
||||
rhsTempVar->getWritableType().getQualifier().makeTemporary();
|
||||
|
||||
{
|
||||
TIntermTyped* rhsTempSym = intermediate.addSymbol(*rhsTempVar, loc);
|
||||
assignList = intermediate.growAggregate(assignList,
|
||||
intermediate.addAssign(EOpAssign, rhsTempSym, right, loc), loc);
|
||||
}
|
||||
|
||||
// tmp.w = 1.0 / tmp.w
|
||||
{
|
||||
const int W = 3;
|
||||
|
||||
TIntermTyped* tempSymL = intermediate.addSymbol(*rhsTempVar, loc);
|
||||
TIntermTyped* tempSymR = intermediate.addSymbol(*rhsTempVar, loc);
|
||||
TIntermTyped* index = intermediate.addConstantUnion(W, loc);
|
||||
|
||||
TIntermTyped* lhsElement = intermediate.addIndex(EOpIndexDirect, tempSymL, index, loc);
|
||||
TIntermTyped* rhsElement = intermediate.addIndex(EOpIndexDirect, tempSymR, index, loc);
|
||||
|
||||
const TType derefType(right->getType(), 0);
|
||||
|
||||
lhsElement->setType(derefType);
|
||||
rhsElement->setType(derefType);
|
||||
|
||||
auto one = intermediate.addConstantUnion(1.0, EbtFloat, loc);
|
||||
auto recip_w = intermediate.addBinaryMath(EOpDiv, one, rhsElement, loc);
|
||||
|
||||
assignList = intermediate.growAggregate(assignList, intermediate.addAssign(EOpAssign, lhsElement, recip_w, loc));
|
||||
}
|
||||
|
||||
// Assign the rhs temp (now with W reciprocal) to the final output
|
||||
{
|
||||
TIntermTyped* rhsTempSym = intermediate.addSymbol(*rhsTempVar, loc);
|
||||
assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, left, rhsTempSym, loc));
|
||||
}
|
||||
|
||||
assert(assignList != nullptr);
|
||||
assignList->setOperator(EOpSequence);
|
||||
|
||||
return assignList;
|
||||
}
|
||||
|
||||
// Position may require special handling: we can optionally invert Y.
|
||||
// See: https://github.com/KhronosGroup/glslang/issues/1173
|
||||
// https://github.com/KhronosGroup/glslang/issues/494
|
||||
|
@ -3071,6 +3140,10 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
|
|||
subSplitLeft, subSplitRight);
|
||||
|
||||
assignList = intermediate.growAggregate(assignList, clipCullAssign, loc);
|
||||
} else if (subSplitRight->getType().getQualifier().builtIn == EbvFragCoord) {
|
||||
// FragCoord can require special handling: see comment above assignFromFragCoord
|
||||
TIntermTyped* fragCoordAssign = assignFromFragCoord(loc, op, subSplitLeft, subSplitRight);
|
||||
assignList = intermediate.growAggregate(assignList, fragCoordAssign, loc);
|
||||
} else if (assignsClipPos(subSplitLeft)) {
|
||||
// Position can require special handling: see comment above assignPosition
|
||||
TIntermTyped* positionAssign = assignPosition(loc, op, subSplitLeft, subSplitRight);
|
||||
|
@ -6935,6 +7008,9 @@ void HlslParseContext::shareStructBufferType(TType& type)
|
|||
if (lhs.isStruct() != rhs.isStruct())
|
||||
return false;
|
||||
|
||||
if (lhs.getQualifier().builtIn != rhs.getQualifier().builtIn)
|
||||
return false;
|
||||
|
||||
if (lhs.isStruct() && rhs.isStruct()) {
|
||||
if (lhs.getStruct()->size() != rhs.getStruct()->size())
|
||||
return false;
|
||||
|
|
|
@ -94,6 +94,7 @@ public:
|
|||
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermTyped*);
|
||||
TIntermAggregate* assignClipCullDistance(const TSourceLoc&, TOperator, int semanticId, TIntermTyped* left, TIntermTyped* right);
|
||||
TIntermTyped* assignPosition(const TSourceLoc&, TOperator, TIntermTyped* left, TIntermTyped* right);
|
||||
TIntermTyped* assignFromFragCoord(const TSourceLoc&, TOperator, TIntermTyped* left, TIntermTyped* right);
|
||||
void decomposeIntrinsic(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
|
||||
void decomposeSampleMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
|
||||
void decomposeStructBufferMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
|
||||
|
|
|
@ -39,6 +39,11 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#ifdef _MSC_VER
|
||||
#include <cfloat>
|
||||
#else
|
||||
#include <cmath>
|
||||
#endif
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <list>
|
||||
|
@ -302,6 +307,34 @@ template <class T> int IntLog2(T n)
|
|||
return result;
|
||||
}
|
||||
|
||||
inline bool IsInfinity(double x) {
|
||||
#ifdef _MSC_VER
|
||||
switch (_fpclass(x)) {
|
||||
case _FPCLASS_NINF:
|
||||
case _FPCLASS_PINF:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return std::isinf(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline bool IsNan(double x) {
|
||||
#ifdef _MSC_VER
|
||||
switch (_fpclass(x)) {
|
||||
case _FPCLASS_SNAN:
|
||||
case _FPCLASS_QNAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return std::isnan(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // end namespace glslang
|
||||
|
||||
#endif // _COMMON_INCLUDED_
|
||||
|
|
|
@ -1865,10 +1865,12 @@ public:
|
|||
bool isAtomic() const { return false; }
|
||||
bool isCoopMat() const { return false; }
|
||||
bool isReference() const { return false; }
|
||||
bool isSpirvType() const { return false; }
|
||||
#else
|
||||
bool isAtomic() const { return basicType == EbtAtomicUint; }
|
||||
bool isCoopMat() const { return coopmat; }
|
||||
bool isReference() const { return getBasicType() == EbtReference; }
|
||||
bool isSpirvType() const { return getBasicType() == EbtSpirvType; }
|
||||
#endif
|
||||
|
||||
// return true if this type contains any subtype which satisfies the given predicate.
|
||||
|
@ -2444,11 +2446,15 @@ public:
|
|||
//
|
||||
bool sameStructType(const TType& right) const
|
||||
{
|
||||
// TODO: Why return true when neither types are structures?
|
||||
// Most commonly, they are both nullptr, or the same pointer to the same actual structure
|
||||
if ((!isStruct() && !right.isStruct()) ||
|
||||
(isStruct() && right.isStruct() && structure == right.structure))
|
||||
return true;
|
||||
|
||||
if (!isStruct() || !right.isStruct())
|
||||
return false;
|
||||
|
||||
// Structure names have to match
|
||||
if (*typeName != *right.typeName)
|
||||
return false;
|
||||
|
@ -2458,8 +2464,7 @@ public:
|
|||
bool isGLPerVertex = *typeName == "gl_PerVertex";
|
||||
|
||||
// Both being nullptr was caught above, now they both have to be structures of the same number of elements
|
||||
if (!isStruct() || !right.isStruct() ||
|
||||
(structure->size() != right.structure->size() && !isGLPerVertex))
|
||||
if (structure->size() != right.structure->size() && !isGLPerVertex)
|
||||
return false;
|
||||
|
||||
// Compare the names and types of all the members, which have to match
|
||||
|
@ -2469,6 +2474,14 @@ public:
|
|||
if (*(*structure)[li].type != *(*right.structure)[ri].type)
|
||||
return false;
|
||||
} else {
|
||||
// Skip hidden members
|
||||
if ((*structure)[li].type->hiddenMember()) {
|
||||
ri--;
|
||||
continue;
|
||||
} else if ((*right.structure)[ri].type->hiddenMember()) {
|
||||
li--;
|
||||
continue;
|
||||
}
|
||||
// If one of the members is something that's inconsistently declared, skip over it
|
||||
// for now.
|
||||
if (isGLPerVertex) {
|
||||
|
@ -2485,10 +2498,10 @@ public:
|
|||
}
|
||||
// If we get here, then there should only be inconsistently declared members left
|
||||
} else if (li < structure->size()) {
|
||||
if (!isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName()))
|
||||
if (!(*structure)[li].type->hiddenMember() && !isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName()))
|
||||
return false;
|
||||
} else {
|
||||
if (!isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName()))
|
||||
if (!(*right.structure)[ri].type->hiddenMember() && !isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName()))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -224,6 +224,9 @@ GLSLANG_EXPORT void glslang_finalize_process();
|
|||
|
||||
GLSLANG_EXPORT glslang_shader_t* glslang_shader_create(const glslang_input_t* input);
|
||||
GLSLANG_EXPORT void glslang_shader_delete(glslang_shader_t* shader);
|
||||
GLSLANG_EXPORT void glslang_shader_shift_binding(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base);
|
||||
GLSLANG_EXPORT void glslang_shader_shift_binding_for_set(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base, unsigned int set);
|
||||
GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int options); // glslang_shader_options_t
|
||||
GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input);
|
||||
GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_input_t* input);
|
||||
GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader);
|
||||
|
@ -234,6 +237,7 @@ GLSLANG_EXPORT glslang_program_t* glslang_program_create();
|
|||
GLSLANG_EXPORT void glslang_program_delete(glslang_program_t* program);
|
||||
GLSLANG_EXPORT void glslang_program_add_shader(glslang_program_t* program, glslang_shader_t* shader);
|
||||
GLSLANG_EXPORT int glslang_program_link(glslang_program_t* program, int messages); // glslang_messages_t
|
||||
GLSLANG_EXPORT int glslang_program_map_io(glslang_program_t* program);
|
||||
GLSLANG_EXPORT void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage);
|
||||
GLSLANG_EXPORT size_t glslang_program_SPIRV_get_size(glslang_program_t* program);
|
||||
GLSLANG_EXPORT void glslang_program_SPIRV_get(glslang_program_t* program, unsigned int*);
|
||||
|
|
|
@ -113,7 +113,8 @@ typedef enum {
|
|||
GLSLANG_TARGET_SPV_1_3 = (1 << 16) | (3 << 8),
|
||||
GLSLANG_TARGET_SPV_1_4 = (1 << 16) | (4 << 8),
|
||||
GLSLANG_TARGET_SPV_1_5 = (1 << 16) | (5 << 8),
|
||||
LAST_ELEMENT_MARKER(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT = 6),
|
||||
GLSLANG_TARGET_SPV_1_6 = (1 << 16) | (6 << 8),
|
||||
LAST_ELEMENT_MARKER(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT = 7),
|
||||
} glslang_target_language_version_t;
|
||||
|
||||
/* EShExecutable counterpart */
|
||||
|
@ -181,6 +182,26 @@ typedef enum {
|
|||
LAST_ELEMENT_MARKER(GLSLANG_PROFILE_COUNT),
|
||||
} glslang_profile_t;
|
||||
|
||||
/* Shader options */
|
||||
typedef enum {
|
||||
GLSLANG_SHADER_DEFAULT_BIT = 0,
|
||||
GLSLANG_SHADER_AUTO_MAP_BINDINGS = (1 << 0),
|
||||
GLSLANG_SHADER_AUTO_MAP_LOCATIONS = (1 << 1),
|
||||
GLSLANG_SHADER_VULKAN_RULES_RELAXED = (1 << 2),
|
||||
LAST_ELEMENT_MARKER(GLSLANG_SHADER_COUNT),
|
||||
} glslang_shader_options_t;
|
||||
|
||||
/* TResourceType counterpart */
|
||||
typedef enum {
|
||||
GLSLANG_RESOURCE_TYPE_SAMPLER,
|
||||
GLSLANG_RESOURCE_TYPE_TEXTURE,
|
||||
GLSLANG_RESOURCE_TYPE_IMAGE,
|
||||
GLSLANG_RESOURCE_TYPE_UBO,
|
||||
GLSLANG_RESOURCE_TYPE_SSBO,
|
||||
GLSLANG_RESOURCE_TYPE_UAV,
|
||||
LAST_ELEMENT_MARKER(GLSLANG_RESOURCE_TYPE_COUNT),
|
||||
} glslang_resource_type_t;
|
||||
|
||||
#undef LAST_ELEMENT_MARKER
|
||||
|
||||
#endif
|
||||
|
|
|
@ -46,35 +46,6 @@ namespace {
|
|||
|
||||
using namespace glslang;
|
||||
|
||||
typedef union {
|
||||
double d;
|
||||
int i[2];
|
||||
} DoubleIntUnion;
|
||||
|
||||
// Some helper functions
|
||||
|
||||
bool isNan(double x)
|
||||
{
|
||||
DoubleIntUnion u;
|
||||
// tough to find a platform independent library function, do it directly
|
||||
u.d = x;
|
||||
int bitPatternL = u.i[0];
|
||||
int bitPatternH = u.i[1];
|
||||
return (bitPatternH & 0x7ff80000) == 0x7ff80000 &&
|
||||
((bitPatternH & 0xFFFFF) != 0 || bitPatternL != 0);
|
||||
}
|
||||
|
||||
bool isInf(double x)
|
||||
{
|
||||
DoubleIntUnion u;
|
||||
// tough to find a platform independent library function, do it directly
|
||||
u.d = x;
|
||||
int bitPatternL = u.i[0];
|
||||
int bitPatternH = u.i[1];
|
||||
return (bitPatternH & 0x7ff00000) == 0x7ff00000 &&
|
||||
(bitPatternH & 0xFFFFF) == 0 && bitPatternL == 0;
|
||||
}
|
||||
|
||||
const double pi = 3.1415926535897932384626433832795;
|
||||
|
||||
} // end anonymous namespace
|
||||
|
@ -663,12 +634,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||
|
||||
case EOpIsNan:
|
||||
{
|
||||
newConstArray[i].setBConst(isNan(unionArray[i].getDConst()));
|
||||
newConstArray[i].setBConst(IsNan(unionArray[i].getDConst()));
|
||||
break;
|
||||
}
|
||||
case EOpIsInf:
|
||||
{
|
||||
newConstArray[i].setBConst(isInf(unionArray[i].getDConst()));
|
||||
newConstArray[i].setBConst(IsInfinity(unionArray[i].getDConst()));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -316,6 +316,7 @@ const CustomFunction CustomFunctions[] = {
|
|||
|
||||
{ EOpTextureQuerySize, "textureSize", nullptr },
|
||||
{ EOpTextureQueryLod, "textureQueryLod", nullptr },
|
||||
{ EOpTextureQueryLod, "textureQueryLOD", nullptr }, // extension GL_ARB_texture_query_lod
|
||||
{ EOpTextureQueryLevels, "textureQueryLevels", nullptr },
|
||||
{ EOpTextureQuerySamples, "textureSamples", nullptr },
|
||||
{ EOpTexture, "texture", nullptr },
|
||||
|
@ -4553,11 +4554,13 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"\n");
|
||||
}
|
||||
|
||||
// GL_ARB_shader_clock
|
||||
// GL_ARB_shader_clock& GL_EXT_shader_realtime_clock
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
commonBuiltins.append(
|
||||
"uvec2 clock2x32ARB();"
|
||||
"uint64_t clockARB();"
|
||||
"uvec2 clockRealtime2x32EXT();"
|
||||
"uint64_t clockRealtimeEXT();"
|
||||
"\n");
|
||||
}
|
||||
|
||||
|
@ -6245,38 +6248,44 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int
|
|||
//
|
||||
// textureQueryLod(), fragment stage only
|
||||
// Also enabled with extension GL_ARB_texture_query_lod
|
||||
// Extension GL_ARB_texture_query_lod says that textureQueryLOD() also exist at extension.
|
||||
|
||||
if (profile != EEsProfile && version >= 150 && sampler.isCombined() && sampler.dim != EsdRect &&
|
||||
! sampler.isMultiSample() && ! sampler.isBuffer()) {
|
||||
for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) {
|
||||
if (f16TexAddr && sampler.type != EbtFloat16)
|
||||
continue;
|
||||
stageBuiltins[EShLangFragment].append("vec2 textureQueryLod(");
|
||||
stageBuiltins[EShLangFragment].append(typeName);
|
||||
if (dimMap[sampler.dim] == 1)
|
||||
if (f16TexAddr)
|
||||
stageBuiltins[EShLangFragment].append(", float16_t");
|
||||
else
|
||||
stageBuiltins[EShLangFragment].append(", float");
|
||||
else {
|
||||
if (f16TexAddr)
|
||||
stageBuiltins[EShLangFragment].append(", f16vec");
|
||||
else
|
||||
stageBuiltins[EShLangFragment].append(", vec");
|
||||
stageBuiltins[EShLangFragment].append(postfixes[dimMap[sampler.dim]]);
|
||||
}
|
||||
stageBuiltins[EShLangFragment].append(");\n");
|
||||
}
|
||||
|
||||
stageBuiltins[EShLangCompute].append("vec2 textureQueryLod(");
|
||||
stageBuiltins[EShLangCompute].append(typeName);
|
||||
if (dimMap[sampler.dim] == 1)
|
||||
stageBuiltins[EShLangCompute].append(", float");
|
||||
else {
|
||||
stageBuiltins[EShLangCompute].append(", vec");
|
||||
stageBuiltins[EShLangCompute].append(postfixes[dimMap[sampler.dim]]);
|
||||
const TString funcName[2] = {"vec2 textureQueryLod(", "vec2 textureQueryLOD("};
|
||||
|
||||
for (int i = 0; i < 2; ++i){
|
||||
for (int f16TexAddr = 0; f16TexAddr < 2; ++f16TexAddr) {
|
||||
if (f16TexAddr && sampler.type != EbtFloat16)
|
||||
continue;
|
||||
stageBuiltins[EShLangFragment].append(funcName[i]);
|
||||
stageBuiltins[EShLangFragment].append(typeName);
|
||||
if (dimMap[sampler.dim] == 1)
|
||||
if (f16TexAddr)
|
||||
stageBuiltins[EShLangFragment].append(", float16_t");
|
||||
else
|
||||
stageBuiltins[EShLangFragment].append(", float");
|
||||
else {
|
||||
if (f16TexAddr)
|
||||
stageBuiltins[EShLangFragment].append(", f16vec");
|
||||
else
|
||||
stageBuiltins[EShLangFragment].append(", vec");
|
||||
stageBuiltins[EShLangFragment].append(postfixes[dimMap[sampler.dim]]);
|
||||
}
|
||||
stageBuiltins[EShLangFragment].append(");\n");
|
||||
}
|
||||
|
||||
stageBuiltins[EShLangCompute].append(funcName[i]);
|
||||
stageBuiltins[EShLangCompute].append(typeName);
|
||||
if (dimMap[sampler.dim] == 1)
|
||||
stageBuiltins[EShLangCompute].append(", float");
|
||||
else {
|
||||
stageBuiltins[EShLangCompute].append(", vec");
|
||||
stageBuiltins[EShLangCompute].append(postfixes[dimMap[sampler.dim]]);
|
||||
}
|
||||
stageBuiltins[EShLangCompute].append(");\n");
|
||||
}
|
||||
stageBuiltins[EShLangCompute].append(");\n");
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -8061,7 +8070,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
}
|
||||
|
||||
if (profile != EEsProfile && version < 400) {
|
||||
symbolTable.setFunctionExtensions("textureQueryLod", 1, &E_GL_ARB_texture_query_lod);
|
||||
symbolTable.setFunctionExtensions("textureQueryLOD", 1, &E_GL_ARB_texture_query_lod);
|
||||
}
|
||||
|
||||
if (profile != EEsProfile && version >= 460) {
|
||||
|
@ -8324,6 +8333,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
symbolTable.setFunctionExtensions("clockARB", 1, &E_GL_ARB_shader_clock);
|
||||
symbolTable.setFunctionExtensions("clock2x32ARB", 1, &E_GL_ARB_shader_clock);
|
||||
|
||||
symbolTable.setFunctionExtensions("clockRealtimeEXT", 1, &E_GL_EXT_shader_realtime_clock);
|
||||
symbolTable.setFunctionExtensions("clockRealtime2x32EXT", 1, &E_GL_EXT_shader_realtime_clock);
|
||||
|
||||
if (profile == EEsProfile && version < 320) {
|
||||
symbolTable.setVariableExtensions("gl_PrimitiveID", Num_AEP_geometry_shader, AEP_geometry_shader);
|
||||
symbolTable.setVariableExtensions("gl_Layer", Num_AEP_geometry_shader, AEP_geometry_shader);
|
||||
|
|
|
@ -3902,7 +3902,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
|
|||
case EbtFloat16: PROMOTE(setDConst, double, Get); break; \
|
||||
case EbtFloat: PROMOTE(setDConst, double, Get); break; \
|
||||
case EbtDouble: PROMOTE(setDConst, double, Get); break; \
|
||||
case EbtInt8: PROMOTE(setI8Const, char, Get); break; \
|
||||
case EbtInt8: PROMOTE(setI8Const, signed char, Get); break; \
|
||||
case EbtInt16: PROMOTE(setI16Const, short, Get); break; \
|
||||
case EbtInt: PROMOTE(setIConst, int, Get); break; \
|
||||
case EbtInt64: PROMOTE(setI64Const, long long, Get); break; \
|
||||
|
|
|
@ -1321,7 +1321,7 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction
|
|||
// Find it in the symbol table.
|
||||
//
|
||||
const TFunction* fnCandidate;
|
||||
bool builtIn;
|
||||
bool builtIn {false};
|
||||
fnCandidate = findFunction(loc, *function, builtIn);
|
||||
if (fnCandidate) {
|
||||
// This is a declared function that might map to
|
||||
|
@ -6496,6 +6496,8 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier
|
|||
error(loc, "can only be used with a uniform", "push_constant", "");
|
||||
if (qualifier.hasSet())
|
||||
error(loc, "cannot be used with push_constant", "set", "");
|
||||
if (qualifier.hasBinding())
|
||||
error(loc, "cannot be used with push_constant", "binding", "");
|
||||
}
|
||||
if (qualifier.hasBufferReference()) {
|
||||
if (qualifier.storage != EvqBuffer)
|
||||
|
@ -6650,8 +6652,10 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct
|
|||
: findFunctionExact(loc, call, builtIn));
|
||||
else if (version < 120)
|
||||
function = findFunctionExact(loc, call, builtIn);
|
||||
else if (version < 400)
|
||||
function = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
|
||||
else if (version < 400) {
|
||||
bool needfindFunction400 = extensionTurnedOn(E_GL_ARB_gpu_shader_fp64) || extensionTurnedOn(E_GL_ARB_gpu_shader5);
|
||||
function = needfindFunction400 ? findFunction400(loc, call, builtIn) : findFunction120(loc, call, builtIn);
|
||||
}
|
||||
else if (explicitTypesEnabled)
|
||||
function = findFunctionExplicitTypes(loc, call, builtIn);
|
||||
else
|
||||
|
|
|
@ -1343,7 +1343,6 @@ int ShInitialize()
|
|||
|
||||
glslang::GetGlobalLock();
|
||||
++NumberOfClients;
|
||||
glslang::ReleaseGlobalLock();
|
||||
|
||||
if (PerProcessGPA == nullptr)
|
||||
PerProcessGPA = new TPoolAllocator();
|
||||
|
@ -1353,6 +1352,7 @@ int ShInitialize()
|
|||
glslang::HlslScanContext::fillInKeywordMap();
|
||||
#endif
|
||||
|
||||
glslang::ReleaseGlobalLock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1415,9 +1415,10 @@ int ShFinalize()
|
|||
--NumberOfClients;
|
||||
assert(NumberOfClients >= 0);
|
||||
bool finalize = NumberOfClients == 0;
|
||||
glslang::ReleaseGlobalLock();
|
||||
if (! finalize)
|
||||
if (! finalize) {
|
||||
glslang::ReleaseGlobalLock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (int version = 0; version < VersionCount; ++version) {
|
||||
for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) {
|
||||
|
@ -1455,6 +1456,7 @@ int ShFinalize()
|
|||
glslang::HlslScanContext::deleteKeywordMap();
|
||||
#endif
|
||||
|
||||
glslang::ReleaseGlobalLock();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -1827,6 +1829,7 @@ void TShader::setUniqueId(unsigned long long id)
|
|||
}
|
||||
|
||||
void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
|
||||
void TShader::setDxPositionW(bool invert) { intermediate->setDxPositionW(invert); }
|
||||
void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); }
|
||||
|
||||
#ifndef GLSLANG_WEB
|
||||
|
|
|
@ -426,12 +426,7 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
|
|||
symTableLevel->thisLevel = thisLevel;
|
||||
symTableLevel->retargetedSymbols.clear();
|
||||
for (auto &s : retargetedSymbols) {
|
||||
// Extra constructions to make sure they use the correct allocator pool
|
||||
TString newFrom;
|
||||
newFrom = s.first;
|
||||
TString newTo;
|
||||
newTo = s.second;
|
||||
symTableLevel->retargetedSymbols.push_back({std::move(newFrom), std::move(newTo)});
|
||||
symTableLevel->retargetedSymbols.push_back({s.first, s.second});
|
||||
}
|
||||
std::vector<bool> containerCopied(anonId, false);
|
||||
tLevel::const_iterator iter;
|
||||
|
@ -462,11 +457,7 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
|
|||
TSymbol* sym = symTableLevel->find(s.second);
|
||||
if (!sym)
|
||||
continue;
|
||||
|
||||
// Need to declare and assign so newS is using the correct pool allocator
|
||||
TString newS;
|
||||
newS = s.first;
|
||||
symTableLevel->insert(newS, sym);
|
||||
symTableLevel->insert(s.first, sym);
|
||||
}
|
||||
|
||||
return symTableLevel;
|
||||
|
|
|
@ -84,7 +84,7 @@ typedef TVector<const char*> TExtensionList;
|
|||
class TSymbol {
|
||||
public:
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
explicit TSymbol(const TString *n) : name(n), extensions(0), writable(true) { }
|
||||
explicit TSymbol(const TString *n) : name(n), uniqueId(0), extensions(0), writable(true) { }
|
||||
virtual TSymbol* clone() const = 0;
|
||||
virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool
|
||||
|
||||
|
|
|
@ -225,6 +225,9 @@ void TParseVersions::initializeExtensionBehavior()
|
|||
extensionBehavior[E_GL_ARB_shading_language_packing] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_texture_query_lod] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_vertex_attrib_64bit] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_draw_instanced] = EBhDisable;
|
||||
extensionBehavior[E_GL_ARB_fragment_coord_conventions] = EBhDisable;
|
||||
|
||||
|
||||
extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable;
|
||||
extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable;
|
||||
|
@ -465,6 +468,8 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||
"#define GL_ARB_shader_storage_buffer_object 1\n"
|
||||
"#define GL_ARB_texture_query_lod 1\n"
|
||||
"#define GL_ARB_vertex_attrib_64bit 1\n"
|
||||
"#define GL_ARB_draw_instanced 1\n"
|
||||
"#define GL_ARB_fragment_coord_conventions 1\n"
|
||||
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
||||
"#define GL_EXT_shader_image_load_formatted 1\n"
|
||||
"#define GL_EXT_post_depth_coverage 1\n"
|
||||
|
|
|
@ -161,6 +161,8 @@ const char* const E_GL_ARB_shader_storage_buffer_object = "GL_ARB_shader_storage
|
|||
const char* const E_GL_ARB_shading_language_packing = "GL_ARB_shading_language_packing";
|
||||
const char* const E_GL_ARB_texture_query_lod = "GL_ARB_texture_query_lod";
|
||||
const char* const E_GL_ARB_vertex_attrib_64bit = "GL_ARB_vertex_attrib_64bit";
|
||||
const char* const E_GL_ARB_draw_instanced = "GL_ARB_draw_instanced";
|
||||
const char* const E_GL_ARB_fragment_coord_conventions = "GL_ARB_fragment_coord_conventions";
|
||||
|
||||
const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic";
|
||||
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
|
||||
|
|
|
@ -48,37 +48,6 @@
|
|||
#endif
|
||||
#include <cstdint>
|
||||
|
||||
namespace {
|
||||
|
||||
bool IsInfinity(double x) {
|
||||
#ifdef _MSC_VER
|
||||
switch (_fpclass(x)) {
|
||||
case _FPCLASS_NINF:
|
||||
case _FPCLASS_PINF:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return std::isinf(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsNan(double x) {
|
||||
#ifdef _MSC_VER
|
||||
switch (_fpclass(x)) {
|
||||
case _FPCLASS_SNAN:
|
||||
case _FPCLASS_QNAN:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
return std::isnan(x);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace glslang {
|
||||
|
||||
|
|
|
@ -514,6 +514,24 @@ struct TSymbolValidater
|
|||
return;
|
||||
}
|
||||
else {
|
||||
// Deal with input/output pairs where one is a block member but the other is loose,
|
||||
// e.g. with ARB_separate_shader_objects
|
||||
if (type1.getBasicType() == EbtBlock &&
|
||||
type1.isStruct() && !type2.isStruct()) {
|
||||
// Iterate through block members tracking layout
|
||||
glslang::TString name;
|
||||
type1.getStruct()->begin()->type->appendMangledName(name);
|
||||
if (name == mangleName2
|
||||
&& type1.getQualifier().layoutLocation == type2.getQualifier().layoutLocation) return;
|
||||
}
|
||||
if (type2.getBasicType() == EbtBlock &&
|
||||
type2.isStruct() && !type1.isStruct()) {
|
||||
// Iterate through block members tracking layout
|
||||
glslang::TString name;
|
||||
type2.getStruct()->begin()->type->appendMangledName(name);
|
||||
if (name == mangleName1
|
||||
&& type1.getQualifier().layoutLocation == type2.getQualifier().layoutLocation) return;
|
||||
}
|
||||
TString err = "Invalid In/Out variable type : " + entKey.first;
|
||||
infoSink.info.message(EPrefixInternalError, err.c_str());
|
||||
hadError = true;
|
||||
|
@ -827,7 +845,7 @@ int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
|||
}
|
||||
// no locations added if already present, a built-in variable, a block, or an opaque
|
||||
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
|
||||
type.isAtomic() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
|
||||
type.isAtomic() || type.isSpirvType() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
|
||||
return ent.newLocation = -1;
|
||||
}
|
||||
// no locations on blocks of built-in variables
|
||||
|
@ -855,8 +873,8 @@ int TDefaultIoResolverBase::resolveInOutLocation(EShLanguage stage, TVarEntryInf
|
|||
return ent.newLocation = -1;
|
||||
}
|
||||
|
||||
// no locations added if already present, or a built-in variable
|
||||
if (type.getQualifier().hasLocation() || type.isBuiltIn()) {
|
||||
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
|
||||
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
|
||||
return ent.newLocation = -1;
|
||||
}
|
||||
|
||||
|
@ -942,8 +960,8 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
|
|||
if (type.getQualifier().hasLocation()) {
|
||||
return ent.newLocation = type.getQualifier().layoutLocation;
|
||||
}
|
||||
// no locations added if already present, or a built-in variable
|
||||
if (type.isBuiltIn()) {
|
||||
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
|
||||
if (type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
|
||||
return ent.newLocation = -1;
|
||||
}
|
||||
// no locations on blocks of built-in variables
|
||||
|
@ -1024,7 +1042,8 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
|
|||
} else {
|
||||
// no locations added if already present, a built-in variable, a block, or an opaque
|
||||
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
|
||||
type.isAtomic() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
|
||||
type.isAtomic() || type.isSpirvType() ||
|
||||
(type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
|
||||
return ent.newLocation = -1;
|
||||
}
|
||||
// no locations on blocks of built-in variables
|
||||
|
|
|
@ -312,6 +312,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
|||
MERGE_TRUE(autoMapBindings);
|
||||
MERGE_TRUE(autoMapLocations);
|
||||
MERGE_TRUE(invertY);
|
||||
MERGE_TRUE(dxPositionW);
|
||||
MERGE_TRUE(flattenUniformArrays);
|
||||
MERGE_TRUE(useUnknownFormat);
|
||||
MERGE_TRUE(hlslOffsets);
|
||||
|
@ -759,7 +760,10 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin
|
|||
|
||||
auto checkName = [this, unitSymbol, &infoSink](const TString& name) {
|
||||
for (unsigned int i = 0; i < unitSymbol->getType().getStruct()->size(); ++i) {
|
||||
if (name == (*unitSymbol->getType().getStruct())[i].type->getFieldName()) {
|
||||
if (name == (*unitSymbol->getType().getStruct())[i].type->getFieldName()
|
||||
&& !((*unitSymbol->getType().getStruct())[i].type->getQualifier().hasLocation()
|
||||
|| unitSymbol->getType().getQualifier().hasLocation())
|
||||
) {
|
||||
error(infoSink, "Anonymous member name used for global variable or other anonymous member: ");
|
||||
infoSink.info << (*unitSymbol->getType().getStruct())[i].type->getCompleteString() << "\n";
|
||||
}
|
||||
|
@ -858,9 +862,19 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
|||
if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock &&
|
||||
symbol.getType().getStruct() && unitSymbol.getType().getStruct() &&
|
||||
symbol.getType().sameStructType(unitSymbol.getType())) {
|
||||
for (unsigned int i = 0; i < symbol.getType().getStruct()->size(); ++i) {
|
||||
const TQualifier& qualifier = (*symbol.getType().getStruct())[i].type->getQualifier();
|
||||
const TQualifier& unitQualifier = (*unitSymbol.getType().getStruct())[i].type->getQualifier();
|
||||
unsigned int li = 0;
|
||||
unsigned int ri = 0;
|
||||
while (li < symbol.getType().getStruct()->size() && ri < unitSymbol.getType().getStruct()->size()) {
|
||||
if ((*symbol.getType().getStruct())[li].type->hiddenMember()) {
|
||||
++li;
|
||||
continue;
|
||||
}
|
||||
if ((*unitSymbol.getType().getStruct())[ri].type->hiddenMember()) {
|
||||
++ri;
|
||||
continue;
|
||||
}
|
||||
const TQualifier& qualifier = (*symbol.getType().getStruct())[li].type->getQualifier();
|
||||
const TQualifier & unitQualifier = (*unitSymbol.getType().getStruct())[ri].type->getQualifier();
|
||||
if (qualifier.layoutMatrix != unitQualifier.layoutMatrix ||
|
||||
qualifier.layoutOffset != unitQualifier.layoutOffset ||
|
||||
qualifier.layoutAlign != unitQualifier.layoutAlign ||
|
||||
|
@ -869,6 +883,8 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
|||
error(infoSink, "Interface block member layout qualifiers must match:");
|
||||
writeTypeComparison = true;
|
||||
}
|
||||
++li;
|
||||
++ri;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -290,6 +290,7 @@ public:
|
|||
resources(TBuiltInResource{}),
|
||||
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
|
||||
invertY(false),
|
||||
dxPositionW(false),
|
||||
useStorageBuffer(false),
|
||||
invariantAll(false),
|
||||
nanMinMaxClamp(false),
|
||||
|
@ -397,6 +398,9 @@ public:
|
|||
case EShTargetSpv_1_5:
|
||||
processes.addProcess("target-env spirv1.5");
|
||||
break;
|
||||
case EShTargetSpv_1_6:
|
||||
processes.addProcess("target-env spirv1.6");
|
||||
break;
|
||||
default:
|
||||
processes.addProcess("target-env spirvUnknown");
|
||||
break;
|
||||
|
@ -460,6 +464,14 @@ public:
|
|||
}
|
||||
bool getInvertY() const { return invertY; }
|
||||
|
||||
void setDxPositionW(bool dxPosW)
|
||||
{
|
||||
dxPositionW = dxPosW;
|
||||
if (dxPositionW)
|
||||
processes.addProcess("dx-position-w");
|
||||
}
|
||||
bool getDxPositionW() const { return dxPositionW; }
|
||||
|
||||
#ifdef ENABLE_HLSL
|
||||
void setSource(EShSource s) { source = s; }
|
||||
EShSource getSource() const { return source; }
|
||||
|
@ -1070,6 +1082,7 @@ protected:
|
|||
int numPushConstants;
|
||||
bool recursive;
|
||||
bool invertY;
|
||||
bool dxPositionW;
|
||||
bool useStorageBuffer;
|
||||
bool invariantAll;
|
||||
bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
|
||||
|
|
|
@ -172,7 +172,7 @@ namespace {
|
|||
pthread_mutex_t gMutex;
|
||||
}
|
||||
|
||||
void InitGlobalLock()
|
||||
static void InitMutex(void)
|
||||
{
|
||||
pthread_mutexattr_t mutexattr;
|
||||
pthread_mutexattr_init(&mutexattr);
|
||||
|
@ -180,6 +180,12 @@ void InitGlobalLock()
|
|||
pthread_mutex_init(&gMutex, &mutexattr);
|
||||
}
|
||||
|
||||
void InitGlobalLock()
|
||||
{
|
||||
static pthread_once_t once = PTHREAD_ONCE_INIT;
|
||||
pthread_once(&once, InitMutex);
|
||||
}
|
||||
|
||||
void GetGlobalLock()
|
||||
{
|
||||
pthread_mutex_lock(&gMutex);
|
||||
|
|
|
@ -163,6 +163,7 @@ typedef enum {
|
|||
} EShTargetLanguage;
|
||||
|
||||
typedef enum {
|
||||
EShTargetUniversal = 0, // Universal
|
||||
EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0
|
||||
EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1
|
||||
EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2
|
||||
|
@ -179,7 +180,8 @@ typedef enum {
|
|||
EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3
|
||||
EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4
|
||||
EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5
|
||||
LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount = 6),
|
||||
EShTargetSpv_1_6 = (1 << 16) | (6 << 8), // SPIR-V 1.6
|
||||
LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount = 7),
|
||||
} EShTargetLanguageVersion;
|
||||
|
||||
struct TInputLanguage {
|
||||
|
@ -485,6 +487,7 @@ public:
|
|||
GLSLANG_EXPORT void addUniformLocationOverride(const char* name, int loc);
|
||||
GLSLANG_EXPORT void setUniformLocationBase(int base);
|
||||
GLSLANG_EXPORT void setInvertY(bool invert);
|
||||
GLSLANG_EXPORT void setDxPositionW(bool dxPosW);
|
||||
#ifdef ENABLE_HLSL
|
||||
GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap);
|
||||
GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten);
|
||||
|
|
Loading…
Reference in New Issue