mirror of https://github.com/bkaradzic/bgfx
Updated glslang.
This commit is contained in:
parent
0d6d961680
commit
8b9afdef85
|
@ -83,14 +83,8 @@ static EShLanguage c_shader_stage(glslang_stage_t stage)
|
|||
|
||||
GLSLANG_EXPORT void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage)
|
||||
{
|
||||
glslang_spv_options_t spv_options;
|
||||
spv_options.generate_debug_info = false;
|
||||
spv_options.strip_debug_info = false;
|
||||
spv_options.emit_nonsemantic_shader_debug_info = false;
|
||||
spv_options.emit_nonsemantic_shader_debug_source = false;
|
||||
glslang_spv_options_t spv_options {};
|
||||
spv_options.disable_optimizer = true;
|
||||
spv_options.optimize_size = false;
|
||||
spv_options.disassemble = false;
|
||||
spv_options.validate = true;
|
||||
|
||||
glslang_program_SPIRV_generate_with_options(program, stage, &spv_options);
|
||||
|
|
|
@ -84,4 +84,7 @@ const char* const E_SPV_NV_shader_sm_builtins = "SPV_NV_shader_sm_builtins";
|
|||
//SPV_NV_shader_execution_reorder
|
||||
const char* const E_SPV_NV_shader_invocation_reorder = "SPV_NV_shader_invocation_reorder";
|
||||
|
||||
//SPV_NV_displacement_micromap
|
||||
const char* const E_SPV_NV_displacement_micromap = "SPV_NV_displacement_micromap";
|
||||
|
||||
#endif // #ifndef GLSLextNV_H
|
||||
|
|
|
@ -133,7 +133,7 @@ public:
|
|||
bool visitLoop(glslang::TVisit, glslang::TIntermLoop*);
|
||||
bool visitBranch(glslang::TVisit visit, glslang::TIntermBranch*);
|
||||
|
||||
void finishSpv();
|
||||
void finishSpv(bool compileOnly);
|
||||
void dumpSpv(std::vector<unsigned int>& out);
|
||||
|
||||
protected:
|
||||
|
@ -167,6 +167,7 @@ protected:
|
|||
bool filterMember(const glslang::TType& member);
|
||||
spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct,
|
||||
glslang::TLayoutPacking, const glslang::TQualifier&);
|
||||
spv::LinkageType convertGlslangLinkageToSpv(glslang::TLinkType glslangLinkType);
|
||||
void decorateStructType(const glslang::TType&, const glslang::TTypeList* glslangStruct, glslang::TLayoutPacking,
|
||||
const glslang::TQualifier&, spv::Id, const std::vector<spv::Id>& spvMembers);
|
||||
spv::Id makeArraySizeId(const glslang::TArraySizes&, int dim, bool allowZero = false);
|
||||
|
@ -1008,6 +1009,22 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
|
|||
builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur);
|
||||
builder.addCapability(spv::CapabilityRayTracingMotionBlurNV);
|
||||
return spv::BuiltInCurrentRayTimeNV;
|
||||
case glslang::EbvMicroTrianglePositionNV:
|
||||
builder.addCapability(spv::CapabilityRayTracingDisplacementMicromapNV);
|
||||
builder.addExtension("SPV_NV_displacement_micromap");
|
||||
return spv::BuiltInHitMicroTriangleVertexPositionsNV;
|
||||
case glslang::EbvMicroTriangleBaryNV:
|
||||
builder.addCapability(spv::CapabilityRayTracingDisplacementMicromapNV);
|
||||
builder.addExtension("SPV_NV_displacement_micromap");
|
||||
return spv::BuiltInHitMicroTriangleVertexBarycentricsNV;
|
||||
case glslang::EbvHitKindFrontFacingMicroTriangleNV:
|
||||
builder.addCapability(spv::CapabilityRayTracingDisplacementMicromapNV);
|
||||
builder.addExtension("SPV_NV_displacement_micromap");
|
||||
return spv::BuiltInHitKindFrontFacingMicroTriangleNV;
|
||||
case glslang::EbvHitKindBackFacingMicroTriangleNV:
|
||||
builder.addCapability(spv::CapabilityRayTracingDisplacementMicromapNV);
|
||||
builder.addExtension("SPV_NV_displacement_micromap");
|
||||
return spv::BuiltInHitKindBackFacingMicroTriangleNV;
|
||||
|
||||
// barycentrics
|
||||
case glslang::EbvBaryCoordNV:
|
||||
|
@ -1588,8 +1605,12 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
|||
builder.addCapability(spv::CapabilityVariablePointers);
|
||||
}
|
||||
|
||||
shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
|
||||
entryPoint = builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPointName().c_str());
|
||||
// If not linking, there is no entry point
|
||||
if (!options.compileOnly) {
|
||||
shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str());
|
||||
entryPoint =
|
||||
builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPointName().c_str());
|
||||
}
|
||||
|
||||
// Add the source extensions
|
||||
const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions();
|
||||
|
@ -1720,23 +1741,31 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
|||
}
|
||||
break;
|
||||
|
||||
case EShLangCompute:
|
||||
case EShLangCompute: {
|
||||
builder.addCapability(spv::CapabilityShader);
|
||||
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));
|
||||
bool needSizeId = false;
|
||||
for (int dim = 0; dim < 3; ++dim) {
|
||||
if ((glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet)) {
|
||||
needSizeId = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
builder.addExecutionModeId(shaderEntry, spv::ExecutionModeLocalSizeId, dimConstId);
|
||||
}
|
||||
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6 && needSizeId) {
|
||||
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));
|
||||
needSizeId = true;
|
||||
}
|
||||
}
|
||||
builder.addExecutionModeId(shaderEntry, spv::ExecutionModeLocalSizeId, dimConstId);
|
||||
} else {
|
||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
|
||||
glslangIntermediate->getLocalSize(1),
|
||||
glslangIntermediate->getLocalSize(2));
|
||||
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
|
||||
glslangIntermediate->getLocalSize(1),
|
||||
glslangIntermediate->getLocalSize(2));
|
||||
}
|
||||
if (glslangIntermediate->getLayoutDerivativeModeNone() == glslang::LayoutDerivativeGroupQuads) {
|
||||
builder.addCapability(spv::CapabilityComputeDerivativeGroupQuadsNV);
|
||||
|
@ -1748,6 +1777,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
|||
builder.addExtension(spv::E_SPV_NV_compute_shader_derivatives);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EShLangTessEvaluation:
|
||||
case EShLangTessControl:
|
||||
builder.addCapability(spv::CapabilityTessellation);
|
||||
|
@ -1939,23 +1969,26 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
|
|||
}
|
||||
|
||||
// Finish creating SPV, after the traversal is complete.
|
||||
void TGlslangToSpvTraverser::finishSpv()
|
||||
void TGlslangToSpvTraverser::finishSpv(bool compileOnly)
|
||||
{
|
||||
// Finish the entry point function
|
||||
if (! entryPointTerminated) {
|
||||
builder.setBuildPoint(shaderEntry->getLastBlock());
|
||||
builder.leaveFunction();
|
||||
}
|
||||
// If not linking, an entry point is not expected
|
||||
if (!compileOnly) {
|
||||
// Finish the entry point function
|
||||
if (!entryPointTerminated) {
|
||||
builder.setBuildPoint(shaderEntry->getLastBlock());
|
||||
builder.leaveFunction();
|
||||
}
|
||||
|
||||
// finish off the entry-point SPV instruction by adding the Input/Output <id>
|
||||
for (auto it = iOSet.cbegin(); it != iOSet.cend(); ++it)
|
||||
entryPoint->addIdOperand(*it);
|
||||
// finish off the entry-point SPV instruction by adding the Input/Output <id>
|
||||
for (auto it = iOSet.cbegin(); it != iOSet.cend(); ++it)
|
||||
entryPoint->addIdOperand(*it);
|
||||
}
|
||||
|
||||
// Add capabilities, extensions, remove unneeded decorations, etc.,
|
||||
// based on the resulting SPIR-V.
|
||||
// Note: WebGPU code generation must have the opportunity to aggressively
|
||||
// prune unreachable merge blocks and continue targets.
|
||||
builder.postProcess();
|
||||
builder.postProcess(compileOnly);
|
||||
}
|
||||
|
||||
// Write the SPV into 'out'.
|
||||
|
@ -2840,9 +2873,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
// In all cases, still let the traverser visit the children for us.
|
||||
makeFunctions(node->getAsAggregate()->getSequence());
|
||||
|
||||
// Also, we want all globals initializers to go into the beginning of the entry point, before
|
||||
// anything else gets there, so visit out of order, doing them all now.
|
||||
makeGlobalInitializers(node->getAsAggregate()->getSequence());
|
||||
// Global initializers is specific to the shader entry point, which does not exist in compile-only mode
|
||||
if (!options.compileOnly) {
|
||||
// Also, we want all globals initializers to go into the beginning of the entry point, before
|
||||
// anything else gets there, so visit out of order, doing them all now.
|
||||
makeGlobalInitializers(node->getAsAggregate()->getSequence());
|
||||
}
|
||||
|
||||
//Pre process linker objects for ray tracing stages
|
||||
if (glslangIntermediate->isRayTracingStage())
|
||||
|
@ -3292,6 +3328,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
builder.addExtension(spv::E_SPV_QCOM_image_processing);
|
||||
break;
|
||||
|
||||
case glslang::EOpFetchMicroTriangleVertexPositionNV:
|
||||
case glslang::EOpFetchMicroTriangleVertexBarycentricNV:
|
||||
builder.addExtension(spv::E_SPV_NV_displacement_micromap);
|
||||
builder.addCapability(spv::CapabilityDisplacementMicromapNV);
|
||||
break;
|
||||
|
||||
case glslang::EOpDebugPrintf:
|
||||
noReturnValue = true;
|
||||
break;
|
||||
|
@ -3656,7 +3698,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
spv::Id typeId = builder.makeArrayType(builder.makeVectorType(builder.makeFloatType(32), 3),
|
||||
builder.makeUintConstant(3), 0);
|
||||
// do the op
|
||||
spv::Id result = builder.createOp(spv::OpRayQueryGetIntersectionTriangleVertexPositionsKHR, typeId, idImmOps);
|
||||
|
||||
spv::Op spvOp = spv::OpRayQueryGetIntersectionTriangleVertexPositionsKHR;
|
||||
|
||||
spv::Id result = builder.createOp(spvOp, typeId, idImmOps);
|
||||
// store the result to the pointer (out param 'm')
|
||||
builder.createStore(result, operands[2]);
|
||||
result = 0;
|
||||
|
@ -3670,13 +3715,13 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt
|
|||
|
||||
// Determine Cooperative Matrix Operands bits from the signedness of the types.
|
||||
if (isTypeSignedInt(glslangOperands[0]->getAsTyped()->getBasicType()))
|
||||
matrixOperands |= spv::CooperativeMatrixOperandsMatrixASignedComponentsMask;
|
||||
matrixOperands |= spv::CooperativeMatrixOperandsMatrixASignedComponentsKHRMask;
|
||||
if (isTypeSignedInt(glslangOperands[1]->getAsTyped()->getBasicType()))
|
||||
matrixOperands |= spv::CooperativeMatrixOperandsMatrixBSignedComponentsMask;
|
||||
matrixOperands |= spv::CooperativeMatrixOperandsMatrixBSignedComponentsKHRMask;
|
||||
if (isTypeSignedInt(glslangOperands[2]->getAsTyped()->getBasicType()))
|
||||
matrixOperands |= spv::CooperativeMatrixOperandsMatrixCSignedComponentsMask;
|
||||
matrixOperands |= spv::CooperativeMatrixOperandsMatrixCSignedComponentsKHRMask;
|
||||
if (isTypeSignedInt(node->getBasicType()))
|
||||
matrixOperands |= spv::CooperativeMatrixOperandsMatrixResultSignedComponentsMask;
|
||||
matrixOperands |= spv::CooperativeMatrixOperandsMatrixResultSignedComponentsKHRMask;
|
||||
|
||||
std::vector<spv::IdImmediate> idImmOps;
|
||||
idImmOps.push_back(spv::IdImmediate(true, operands[0]));
|
||||
|
@ -4329,6 +4374,16 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|||
return convertGlslangToSpvType(type, getExplicitLayout(type), type.getQualifier(), false, forwardReferenceOnly);
|
||||
}
|
||||
|
||||
spv::LinkageType TGlslangToSpvTraverser::convertGlslangLinkageToSpv(glslang::TLinkType linkType)
|
||||
{
|
||||
switch (linkType) {
|
||||
case glslang::ELinkExport:
|
||||
return spv::LinkageTypeExport;
|
||||
default:
|
||||
return spv::LinkageTypeMax;
|
||||
}
|
||||
}
|
||||
|
||||
// Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id.
|
||||
// explicitLayout can be kept the same throughout the hierarchical recursive walk.
|
||||
// Mutually recursive with convertGlslangStructToSpvType().
|
||||
|
@ -4492,26 +4547,27 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|||
|
||||
std::vector<spv::IdImmediate> operands;
|
||||
for (const auto& typeParam : spirvType.typeParams) {
|
||||
if (typeParam.constant != nullptr) {
|
||||
if (typeParam.getAsConstant() != nullptr) {
|
||||
// Constant expression
|
||||
if (typeParam.constant->isLiteral()) {
|
||||
if (typeParam.constant->getBasicType() == glslang::EbtFloat) {
|
||||
float floatValue = static_cast<float>(typeParam.constant->getConstArray()[0].getDConst());
|
||||
auto constant = typeParam.getAsConstant();
|
||||
if (constant->isLiteral()) {
|
||||
if (constant->getBasicType() == glslang::EbtFloat) {
|
||||
float floatValue = static_cast<float>(constant->getConstArray()[0].getDConst());
|
||||
unsigned literal;
|
||||
static_assert(sizeof(literal) == sizeof(floatValue), "sizeof(unsigned) != sizeof(float)");
|
||||
memcpy(&literal, &floatValue, sizeof(literal));
|
||||
operands.push_back({false, literal});
|
||||
} else if (typeParam.constant->getBasicType() == glslang::EbtInt) {
|
||||
unsigned literal = typeParam.constant->getConstArray()[0].getIConst();
|
||||
} else if (constant->getBasicType() == glslang::EbtInt) {
|
||||
unsigned literal = constant->getConstArray()[0].getIConst();
|
||||
operands.push_back({false, literal});
|
||||
} else if (typeParam.constant->getBasicType() == glslang::EbtUint) {
|
||||
unsigned literal = typeParam.constant->getConstArray()[0].getUConst();
|
||||
} else if (constant->getBasicType() == glslang::EbtUint) {
|
||||
unsigned literal = constant->getConstArray()[0].getUConst();
|
||||
operands.push_back({false, literal});
|
||||
} else if (typeParam.constant->getBasicType() == glslang::EbtBool) {
|
||||
unsigned literal = typeParam.constant->getConstArray()[0].getBConst();
|
||||
} else if (constant->getBasicType() == glslang::EbtBool) {
|
||||
unsigned literal = constant->getConstArray()[0].getBConst();
|
||||
operands.push_back({false, literal});
|
||||
} else if (typeParam.constant->getBasicType() == glslang::EbtString) {
|
||||
auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str();
|
||||
} else if (constant->getBasicType() == glslang::EbtString) {
|
||||
auto str = constant->getConstArray()[0].getSConst()->c_str();
|
||||
unsigned literal = 0;
|
||||
char* literalPtr = reinterpret_cast<char*>(&literal);
|
||||
unsigned charCount = 0;
|
||||
|
@ -4536,11 +4592,11 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty
|
|||
} else
|
||||
assert(0); // Unexpected type
|
||||
} else
|
||||
operands.push_back({true, createSpvConstant(*typeParam.constant)});
|
||||
operands.push_back({true, createSpvConstant(*constant)});
|
||||
} else {
|
||||
// Type specifier
|
||||
assert(typeParam.type != nullptr);
|
||||
operands.push_back({true, convertGlslangToSpvType(*typeParam.type)});
|
||||
assert(typeParam.getAsType() != nullptr);
|
||||
operands.push_back({true, convertGlslangToSpvType(*typeParam.getAsType())});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5347,9 +5403,17 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
|
|||
|
||||
for (int f = 0; f < (int)glslFunctions.size(); ++f) {
|
||||
glslang::TIntermAggregate* glslFunction = glslFunctions[f]->getAsAggregate();
|
||||
if (! glslFunction || glslFunction->getOp() != glslang::EOpFunction || isShaderEntryPoint(glslFunction))
|
||||
if (! glslFunction || glslFunction->getOp() != glslang::EOpFunction)
|
||||
continue;
|
||||
|
||||
if (isShaderEntryPoint(glslFunction)) {
|
||||
if (glslangIntermediate->getSource() != glslang::EShSourceHlsl) {
|
||||
builder.setupDebugFunctionEntry(shaderEntry, glslangIntermediate->getEntryPointMangledName().c_str(),
|
||||
glslFunction->getLoc().line,
|
||||
std::vector<spv::Id>(), // main function has no param
|
||||
std::vector<char const*>());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// We're on a user function. Set up the basic interface for the function now,
|
||||
// so that it's available to call. Translating the body will happen later.
|
||||
//
|
||||
|
@ -5395,10 +5459,12 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
|
|||
}
|
||||
|
||||
spv::Block* functionBlock;
|
||||
spv::Function *function = builder.makeFunctionEntry(TranslatePrecisionDecoration(glslFunction->getType()),
|
||||
convertGlslangToSpvType(glslFunction->getType()),
|
||||
glslFunction->getName().c_str(), paramTypes, paramNames,
|
||||
paramDecorations, &functionBlock);
|
||||
spv::Function* function = builder.makeFunctionEntry(
|
||||
TranslatePrecisionDecoration(glslFunction->getType()), convertGlslangToSpvType(glslFunction->getType()),
|
||||
glslFunction->getName().c_str(), convertGlslangLinkageToSpv(glslFunction->getLinkType()), paramTypes,
|
||||
paramNames, paramDecorations, &functionBlock);
|
||||
builder.setupDebugFunctionEntry(function, glslFunction->getName().c_str(), glslFunction->getLoc().line,
|
||||
paramTypes, paramNames);
|
||||
if (implicitThis)
|
||||
function->setImplicitThis();
|
||||
|
||||
|
@ -7177,6 +7243,14 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe
|
|||
unaryOp = spv::OpHitObjectGetShaderRecordBufferHandleNV;
|
||||
break;
|
||||
|
||||
case glslang::EOpFetchMicroTriangleVertexPositionNV:
|
||||
unaryOp = spv::OpFetchMicroTriangleVertexPositionNV;
|
||||
break;
|
||||
|
||||
case glslang::EOpFetchMicroTriangleVertexBarycentricNV:
|
||||
unaryOp = spv::OpFetchMicroTriangleVertexBarycentricNV;
|
||||
break;
|
||||
|
||||
case glslang::EOpCopyObject:
|
||||
unaryOp = spv::OpCopyObject;
|
||||
break;
|
||||
|
@ -9061,6 +9135,17 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
|
|||
addImageProcessingQCOMDecoration(operands[0], spv::DecorationBlockMatchTextureQCOM);
|
||||
addImageProcessingQCOMDecoration(operands[2], spv::DecorationBlockMatchTextureQCOM);
|
||||
break;
|
||||
|
||||
case glslang::EOpFetchMicroTriangleVertexBarycentricNV:
|
||||
typeId = builder.makeVectorType(builder.makeFloatType(32), 2);
|
||||
opCode = spv::OpFetchMicroTriangleVertexBarycentricNV;
|
||||
break;
|
||||
|
||||
case glslang::EOpFetchMicroTriangleVertexPositionNV:
|
||||
typeId = builder.makeVectorType(builder.makeFloatType(32), 3);
|
||||
opCode = spv::OpFetchMicroTriangleVertexPositionNV;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -10101,7 +10186,7 @@ void GlslangToSpv(const TIntermediate& intermediate, std::vector<unsigned int>&
|
|||
|
||||
TGlslangToSpvTraverser it(intermediate.getSpv().spv, &intermediate, logger, *options);
|
||||
root->traverse(&it);
|
||||
it.finishSpv();
|
||||
it.finishSpv(options->compileOnly);
|
||||
it.dumpSpv(spirv);
|
||||
|
||||
#if ENABLE_OPT
|
||||
|
|
|
@ -859,11 +859,19 @@ Id Builder::makeBoolDebugType(int const size)
|
|||
|
||||
Id Builder::makeIntegerDebugType(int const width, bool const hasSign)
|
||||
{
|
||||
const char* typeName = nullptr;
|
||||
switch (width) {
|
||||
case 8: typeName = hasSign ? "int8_t" : "uint8_t"; break;
|
||||
case 16: typeName = hasSign ? "int16_t" : "uint16_t"; break;
|
||||
case 64: typeName = hasSign ? "int64_t" : "uint64_t"; break;
|
||||
default: typeName = hasSign ? "int" : "uint";
|
||||
}
|
||||
auto nameId = getStringId(typeName);
|
||||
// try to find it
|
||||
Instruction* type;
|
||||
for (int t = 0; t < (int)groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].size(); ++t) {
|
||||
type = groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic][t];
|
||||
if (type->getIdOperand(0) == (hasSign ? getStringId("int") : getStringId("uint")) &&
|
||||
if (type->getIdOperand(0) == nameId &&
|
||||
type->getIdOperand(1) == static_cast<unsigned int>(width) &&
|
||||
type->getIdOperand(2) == (hasSign ? NonSemanticShaderDebugInfo100Signed : NonSemanticShaderDebugInfo100Unsigned))
|
||||
return type->getResultId();
|
||||
|
@ -873,11 +881,7 @@ Id Builder::makeIntegerDebugType(int const width, bool const hasSign)
|
|||
type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
|
||||
type->addIdOperand(nonSemanticShaderDebugInfo);
|
||||
type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeBasic);
|
||||
if(hasSign == true) {
|
||||
type->addIdOperand(getStringId("int")); // name id
|
||||
} else {
|
||||
type->addIdOperand(getStringId("uint")); // name id
|
||||
}
|
||||
type->addIdOperand(nameId); // name id
|
||||
type->addIdOperand(makeUintConstant(width)); // size id
|
||||
if(hasSign == true) {
|
||||
type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100Signed)); // encoding id
|
||||
|
@ -895,11 +899,18 @@ Id Builder::makeIntegerDebugType(int const width, bool const hasSign)
|
|||
|
||||
Id Builder::makeFloatDebugType(int const width)
|
||||
{
|
||||
const char* typeName = nullptr;
|
||||
switch (width) {
|
||||
case 16: typeName = "float16_t"; break;
|
||||
case 64: typeName = "double"; break;
|
||||
default: typeName = "float"; break;
|
||||
}
|
||||
auto nameId = getStringId(typeName);
|
||||
// try to find it
|
||||
Instruction* type;
|
||||
for (int t = 0; t < (int)groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].size(); ++t) {
|
||||
type = groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic][t];
|
||||
if (type->getIdOperand(0) == getStringId("float") &&
|
||||
if (type->getIdOperand(0) == nameId &&
|
||||
type->getIdOperand(1) == static_cast<unsigned int>(width) &&
|
||||
type->getIdOperand(2) == NonSemanticShaderDebugInfo100Float)
|
||||
return type->getResultId();
|
||||
|
@ -909,7 +920,7 @@ Id Builder::makeFloatDebugType(int const width)
|
|||
type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst);
|
||||
type->addIdOperand(nonSemanticShaderDebugInfo);
|
||||
type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeBasic);
|
||||
type->addIdOperand(getStringId("float")); // name id
|
||||
type->addIdOperand(nameId); // name id
|
||||
type->addIdOperand(makeUintConstant(width)); // size id
|
||||
type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100Float)); // encoding id
|
||||
type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100None)); // flags id
|
||||
|
@ -1018,7 +1029,10 @@ Id Builder::makeCompositeDebugType(std::vector<Id> const& memberTypes, char cons
|
|||
for(auto const memberType : memberTypes) {
|
||||
assert(debugTypeLocs.find(memberType) != debugTypeLocs.end());
|
||||
|
||||
memberDebugTypes.emplace_back(makeMemberDebugType(memberType, debugTypeLocs[memberType]));
|
||||
// There _should_ be debug types for all the member types but currently buffer references
|
||||
// do not have member debug info generated.
|
||||
if (debugId[memberType])
|
||||
memberDebugTypes.emplace_back(makeMemberDebugType(memberType, debugTypeLocs[memberType]));
|
||||
|
||||
// TODO: Need to rethink this method of passing location information.
|
||||
// debugTypeLocs.erase(memberType);
|
||||
|
@ -1824,6 +1838,10 @@ Instruction* Builder::addEntryPoint(ExecutionModel model, Function* function, co
|
|||
// Currently relying on the fact that all 'value' of interest are small non-negative values.
|
||||
void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int value1, int value2, int value3)
|
||||
{
|
||||
// entryPoint can be null if we are in compile-only mode
|
||||
if (!entryPoint)
|
||||
return;
|
||||
|
||||
Instruction* instr = new Instruction(OpExecutionMode);
|
||||
instr->addIdOperand(entryPoint->getId());
|
||||
instr->addImmediateOperand(mode);
|
||||
|
@ -1839,6 +1857,10 @@ void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int val
|
|||
|
||||
void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, const std::vector<unsigned>& literals)
|
||||
{
|
||||
// entryPoint can be null if we are in compile-only mode
|
||||
if (!entryPoint)
|
||||
return;
|
||||
|
||||
Instruction* instr = new Instruction(OpExecutionMode);
|
||||
instr->addIdOperand(entryPoint->getId());
|
||||
instr->addImmediateOperand(mode);
|
||||
|
@ -1850,6 +1872,10 @@ void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, const s
|
|||
|
||||
void Builder::addExecutionModeId(Function* entryPoint, ExecutionMode mode, const std::vector<Id>& operandIds)
|
||||
{
|
||||
// entryPoint can be null if we are in compile-only mode
|
||||
if (!entryPoint)
|
||||
return;
|
||||
|
||||
Instruction* instr = new Instruction(OpExecutionModeId);
|
||||
instr->addIdOperand(entryPoint->getId());
|
||||
instr->addImmediateOperand(mode);
|
||||
|
@ -1933,6 +1959,16 @@ void Builder::addDecoration(Id id, Decoration decoration, const std::vector<cons
|
|||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||
}
|
||||
|
||||
void Builder::addLinkageDecoration(Id id, const char* name, spv::LinkageType linkType) {
|
||||
Instruction* dec = new Instruction(OpDecorate);
|
||||
dec->addIdOperand(id);
|
||||
dec->addImmediateOperand(spv::DecorationLinkageAttributes);
|
||||
dec->addStringOperand(name);
|
||||
dec->addImmediateOperand(linkType);
|
||||
|
||||
decorations.push_back(std::unique_ptr<Instruction>(dec));
|
||||
}
|
||||
|
||||
void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration)
|
||||
{
|
||||
if (decoration == spv::DecorationMax)
|
||||
|
@ -2037,7 +2073,7 @@ Function* Builder::makeEntryPoint(const char* entryPoint)
|
|||
emitNonSemanticShaderDebugInfo = false;
|
||||
}
|
||||
|
||||
entryPointFunction = makeFunctionEntry(NoPrecision, returnType, entryPoint, paramsTypes, paramNames, decorations, &entry);
|
||||
entryPointFunction = makeFunctionEntry(NoPrecision, returnType, entryPoint, LinkageTypeMax, paramsTypes, paramNames, decorations, &entry);
|
||||
|
||||
emitNonSemanticShaderDebugInfo = restoreNonSemanticShaderDebugInfo;
|
||||
|
||||
|
@ -2045,7 +2081,7 @@ Function* Builder::makeEntryPoint(const char* entryPoint)
|
|||
}
|
||||
|
||||
// Comments in header
|
||||
Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name,
|
||||
Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name, LinkageType linkType,
|
||||
const std::vector<Id>& paramTypes, const std::vector<char const*>& paramNames,
|
||||
const std::vector<std::vector<Decoration>>& decorations, Block **entry)
|
||||
{
|
||||
|
@ -2053,7 +2089,7 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
|
|||
Id typeId = makeFunctionType(returnType, paramTypes);
|
||||
Id firstParamId = paramTypes.size() == 0 ? 0 : getUniqueIds((int)paramTypes.size());
|
||||
Id funcId = getUniqueId();
|
||||
Function* function = new Function(funcId, returnType, typeId, firstParamId, module);
|
||||
Function* function = new Function(funcId, returnType, typeId, firstParamId, linkType, name, module);
|
||||
|
||||
// Set up the precisions
|
||||
setPrecision(function->getId(), precision);
|
||||
|
@ -2065,12 +2101,8 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
|
|||
}
|
||||
}
|
||||
|
||||
// Make the debug function instruction
|
||||
// reset last debug scope
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
Id nameId = getStringId(unmangleFunctionName(name));
|
||||
Id debugFuncId = makeDebugFunction(function, nameId, typeId);
|
||||
debugId[funcId] = debugFuncId;
|
||||
currentDebugScopeId.push(debugFuncId);
|
||||
lastDebugScopeId = NoResult;
|
||||
}
|
||||
|
||||
|
@ -2080,41 +2112,62 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
|
|||
function->addBlock(*entry);
|
||||
setBuildPoint(*entry);
|
||||
|
||||
// DebugScope and DebugLine for parameter DebugDeclares
|
||||
if (emitNonSemanticShaderDebugInfo && (int)paramTypes.size() > 0) {
|
||||
addDebugScopeAndLine(currentFileId, currentLine, 0);
|
||||
}
|
||||
if (name)
|
||||
addName(function->getId(), name);
|
||||
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
assert(paramTypes.size() == paramNames.size());
|
||||
for(size_t p = 0; p < paramTypes.size(); ++p)
|
||||
{
|
||||
functions.push_back(std::unique_ptr<Function>(function));
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
void Builder::setupDebugFunctionEntry(Function* function, const char* name, int line, const std::vector<Id>& paramTypes,
|
||||
const std::vector<char const*>& paramNames)
|
||||
{
|
||||
|
||||
if (!emitNonSemanticShaderDebugInfo)
|
||||
return;
|
||||
|
||||
currentLine = line;
|
||||
Id nameId = getStringId(unmangleFunctionName(name));
|
||||
Id funcTypeId = function->getFuncTypeId();
|
||||
assert(debugId[funcTypeId] != 0);
|
||||
Id funcId = function->getId();
|
||||
|
||||
assert(funcId != 0);
|
||||
|
||||
// Make the debug function instruction
|
||||
Id debugFuncId = makeDebugFunction(function, nameId, funcTypeId);
|
||||
debugId[funcId] = debugFuncId;
|
||||
currentDebugScopeId.push(debugFuncId);
|
||||
|
||||
// DebugScope and DebugLine for parameter DebugDeclares
|
||||
assert(paramTypes.size() == paramNames.size());
|
||||
if ((int)paramTypes.size() > 0) {
|
||||
addDebugScopeAndLine(currentFileId, currentLine, 0);
|
||||
|
||||
Id firstParamId = function->getParamId(0);
|
||||
|
||||
for (size_t p = 0; p < paramTypes.size(); ++p) {
|
||||
auto getParamTypeId = [this](Id const& typeId) {
|
||||
if (isPointerType(typeId) || isArrayType(typeId)) {
|
||||
return getContainedTypeId(typeId);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return typeId;
|
||||
}
|
||||
};
|
||||
auto const& paramName = paramNames[p];
|
||||
auto const debugLocalVariableId = createDebugLocalVariable(debugId[getParamTypeId(paramTypes[p])], paramName, p+1);
|
||||
auto const debugLocalVariableId =
|
||||
createDebugLocalVariable(debugId[getParamTypeId(paramTypes[p])], paramName, p + 1);
|
||||
|
||||
debugId[firstParamId + p] = debugLocalVariableId;
|
||||
|
||||
makeDebugDeclare(debugLocalVariableId, firstParamId + p);
|
||||
}
|
||||
}
|
||||
|
||||
if (name)
|
||||
addName(function->getId(), name);
|
||||
|
||||
functions.push_back(std::unique_ptr<Function>(function));
|
||||
|
||||
// Clear debug scope stack
|
||||
if (emitNonSemanticShaderDebugInfo)
|
||||
currentDebugScopeId.pop();
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
Id Builder::makeDebugFunction([[maybe_unused]] Function* function, Id nameId, Id funcTypeId)
|
||||
|
@ -2130,13 +2183,13 @@ Id Builder::makeDebugFunction([[maybe_unused]] Function* function, Id nameId, Id
|
|||
type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugFunction);
|
||||
type->addIdOperand(nameId);
|
||||
type->addIdOperand(debugId[funcTypeId]);
|
||||
type->addIdOperand(makeDebugSource(currentFileId)); // Will be fixed later when true filename available
|
||||
type->addIdOperand(makeUintConstant(currentLine)); // Will be fixed later when true line available
|
||||
type->addIdOperand(makeDebugSource(currentFileId)); // TODO: This points to file of definition instead of declaration
|
||||
type->addIdOperand(makeUintConstant(currentLine)); // TODO: This points to line of definition instead of declaration
|
||||
type->addIdOperand(makeUintConstant(0)); // column
|
||||
type->addIdOperand(makeDebugCompilationUnit()); // scope
|
||||
type->addIdOperand(nameId); // linkage name
|
||||
type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsPublic));
|
||||
type->addIdOperand(makeUintConstant(currentLine)); // TODO(greg-lunarg): correct scope line
|
||||
type->addIdOperand(makeUintConstant(currentLine));
|
||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
||||
module.mapInstruction(type);
|
||||
return funcId;
|
||||
|
@ -2223,6 +2276,12 @@ void Builder::enterFunction(Function const* function)
|
|||
defInst->addIdOperand(funcId);
|
||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(defInst));
|
||||
}
|
||||
|
||||
if (auto linkType = function->getLinkType(); linkType != LinkageTypeMax) {
|
||||
Id funcId = function->getFuncId();
|
||||
addCapability(CapabilityLinkage);
|
||||
addLinkageDecoration(funcId, function->getExportName(), linkType);
|
||||
}
|
||||
}
|
||||
|
||||
// Comments in header
|
||||
|
|
|
@ -237,6 +237,9 @@ public:
|
|||
Id makeDebugFunction(Function* function, Id nameId, Id funcTypeId);
|
||||
Id makeDebugLexicalBlock(uint32_t line);
|
||||
std::string unmangleFunctionName(std::string const& name) const;
|
||||
void setupDebugFunctionEntry(Function* function, const char* name, int line,
|
||||
const std::vector<Id>& paramTypes,
|
||||
const std::vector<char const*>& paramNames);
|
||||
|
||||
// accelerationStructureNV type
|
||||
Id makeAccelerationStructureType();
|
||||
|
@ -393,6 +396,7 @@ public:
|
|||
void addDecoration(Id, Decoration, const char*);
|
||||
void addDecoration(Id, Decoration, const std::vector<unsigned>& literals);
|
||||
void addDecoration(Id, Decoration, const std::vector<const char*>& strings);
|
||||
void addLinkageDecoration(Id id, const char* name, spv::LinkageType linkType);
|
||||
void addDecorationId(Id id, Decoration, Id idDecoration);
|
||||
void addDecorationId(Id id, Decoration, const std::vector<Id>& operandIds);
|
||||
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
||||
|
@ -417,7 +421,8 @@ public:
|
|||
// Return the function, pass back the entry.
|
||||
// The returned pointer is only valid for the lifetime of this builder.
|
||||
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name,
|
||||
const std::vector<Id>& paramTypes, const std::vector<char const*>& paramNames,
|
||||
LinkageType linkType, const std::vector<Id>& paramTypes,
|
||||
const std::vector<char const*>& paramNames,
|
||||
const std::vector<std::vector<Decoration>>& precisions, Block **entry = nullptr);
|
||||
|
||||
// Create a return. An 'implicit' return is one not appearing in the source
|
||||
|
@ -828,7 +833,7 @@ public:
|
|||
|
||||
// Add capabilities, extensions, remove unneeded decorations, etc.,
|
||||
// based on the resulting SPIR-V.
|
||||
void postProcess();
|
||||
void postProcess(bool compileOnly);
|
||||
|
||||
// Prune unreachable blocks in the CFG and remove unneeded decorations.
|
||||
void postProcessCFG();
|
||||
|
|
|
@ -483,9 +483,13 @@ void Builder::postProcessFeatures() {
|
|||
}
|
||||
|
||||
// comment in header
|
||||
void Builder::postProcess() {
|
||||
postProcessCFG();
|
||||
postProcessFeatures();
|
||||
void Builder::postProcess(bool compileOnly)
|
||||
{
|
||||
// postProcessCFG needs an entrypoint to determine what is reachable, but if we are not creating an "executable" shader, we don't have an entrypoint
|
||||
if (!compileOnly)
|
||||
postProcessCFG();
|
||||
|
||||
postProcessFeatures();
|
||||
}
|
||||
|
||||
}; // end spv namespace
|
||||
|
|
|
@ -61,6 +61,7 @@ struct SpvOptions {
|
|||
bool validate {false};
|
||||
bool emitNonSemanticShaderDebugInfo {false};
|
||||
bool emitNonSemanticShaderDebugSource{ false };
|
||||
bool compileOnly{false};
|
||||
};
|
||||
|
||||
#if ENABLE_OPT
|
||||
|
|
|
@ -414,6 +414,10 @@ const char* BuiltInString(int builtIn)
|
|||
case BuiltInRayTmaxKHR: return "RayTmaxKHR";
|
||||
case BuiltInCullMaskKHR: return "CullMaskKHR";
|
||||
case BuiltInHitTriangleVertexPositionsKHR: return "HitTriangleVertexPositionsKHR";
|
||||
case BuiltInHitMicroTriangleVertexPositionsNV: return "HitMicroTriangleVertexPositionsNV";
|
||||
case BuiltInHitMicroTriangleVertexBarycentricsNV: return "HitMicroTriangleVertexBarycentricsNV";
|
||||
case BuiltInHitKindFrontFacingMicroTriangleNV: return "HitKindFrontFacingMicroTriangleNV";
|
||||
case BuiltInHitKindBackFacingMicroTriangleNV: return "HitKindBackFacingMicroTriangleNV";
|
||||
case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR";
|
||||
case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR";
|
||||
case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR";
|
||||
|
@ -798,11 +802,11 @@ const int CooperativeMatrixOperandsCeiling = 6;
|
|||
const char* CooperativeMatrixOperandsString(int op)
|
||||
{
|
||||
switch (op) {
|
||||
case CooperativeMatrixOperandsMatrixASignedComponentsShift: return "ASignedComponents";
|
||||
case CooperativeMatrixOperandsMatrixBSignedComponentsShift: return "BSignedComponents";
|
||||
case CooperativeMatrixOperandsMatrixCSignedComponentsShift: return "CSignedComponents";
|
||||
case CooperativeMatrixOperandsMatrixResultSignedComponentsShift: return "ResultSignedComponents";
|
||||
case CooperativeMatrixOperandsSaturatingAccumulationShift: return "SaturatingAccumulation";
|
||||
case CooperativeMatrixOperandsMatrixASignedComponentsKHRShift: return "ASignedComponentsKHR";
|
||||
case CooperativeMatrixOperandsMatrixBSignedComponentsKHRShift: return "BSignedComponentsKHR";
|
||||
case CooperativeMatrixOperandsMatrixCSignedComponentsKHRShift: return "CSignedComponentsKHR";
|
||||
case CooperativeMatrixOperandsMatrixResultSignedComponentsKHRShift: return "ResultSignedComponentsKHR";
|
||||
case CooperativeMatrixOperandsSaturatingAccumulationKHRShift: return "SaturatingAccumulationKHR";
|
||||
|
||||
default: return "Bad";
|
||||
}
|
||||
|
@ -977,6 +981,8 @@ const char* CapabilityString(int info)
|
|||
case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR";
|
||||
case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR";
|
||||
case CapabilityRayTracingPositionFetchKHR: return "RayTracingPositionFetchKHR";
|
||||
case CapabilityDisplacementMicromapNV: return "DisplacementMicromapNV";
|
||||
case CapabilityRayTracingDisplacementMicromapNV: return "CapabilityRayTracingDisplacementMicromapNV";
|
||||
case CapabilityRayQueryPositionFetchKHR: return "RayQueryPositionFetchKHR";
|
||||
case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV";
|
||||
case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV";
|
||||
|
@ -1542,6 +1548,9 @@ const char* OpcodeString(int op)
|
|||
case OpHitObjectGetShaderBindingTableRecordIndexNV: return "OpHitObjectGetShaderBindingTableRecordIndexNV";
|
||||
case OpHitObjectGetShaderRecordBufferHandleNV: return "OpHitObjectGetShaderRecordBufferHandleNV";
|
||||
|
||||
case OpFetchMicroTriangleVertexBarycentricNV: return "OpFetchMicroTriangleVertexBarycentricNV";
|
||||
case OpFetchMicroTriangleVertexPositionNV: return "OpFetchMicroTriangleVertexPositionNV";
|
||||
|
||||
case OpColorAttachmentReadEXT: return "OpColorAttachmentReadEXT";
|
||||
case OpDepthAttachmentReadEXT: return "OpDepthAttachmentReadEXT";
|
||||
case OpStencilAttachmentReadEXT: return "OpStencilAttachmentReadEXT";
|
||||
|
@ -3082,7 +3091,7 @@ void Parameterize()
|
|||
|
||||
InstructionDesc[OpRayQueryGetIntersectionTriangleVertexPositionsKHR].operands.push(OperandId, "'RayQuery'");
|
||||
InstructionDesc[OpRayQueryGetIntersectionTriangleVertexPositionsKHR].operands.push(OperandId, "'Committed'");
|
||||
InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].setResultAndType(true, true);
|
||||
InstructionDesc[OpRayQueryGetIntersectionTriangleVertexPositionsKHR].setResultAndType(true, true);
|
||||
|
||||
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Sampled Image'");
|
||||
InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'");
|
||||
|
@ -3348,6 +3357,20 @@ void Parameterize()
|
|||
InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'Payload'");
|
||||
InstructionDesc[OpHitObjectTraceRayMotionNV].setResultAndType(false, false);
|
||||
|
||||
InstructionDesc[OpFetchMicroTriangleVertexBarycentricNV].operands.push(OperandId, "'Acceleration Structure'");
|
||||
InstructionDesc[OpFetchMicroTriangleVertexBarycentricNV].operands.push(OperandId, "'Instance ID'");
|
||||
InstructionDesc[OpFetchMicroTriangleVertexBarycentricNV].operands.push(OperandId, "'Geometry Index'");
|
||||
InstructionDesc[OpFetchMicroTriangleVertexBarycentricNV].operands.push(OperandId, "'Primitive Index'");
|
||||
InstructionDesc[OpFetchMicroTriangleVertexBarycentricNV].operands.push(OperandId, "'Barycentrics'");
|
||||
InstructionDesc[OpFetchMicroTriangleVertexBarycentricNV].setResultAndType(true, true);
|
||||
|
||||
InstructionDesc[OpFetchMicroTriangleVertexPositionNV].operands.push(OperandId, "'Acceleration Structure'");
|
||||
InstructionDesc[OpFetchMicroTriangleVertexPositionNV].operands.push(OperandId, "'Instance ID'");
|
||||
InstructionDesc[OpFetchMicroTriangleVertexPositionNV].operands.push(OperandId, "'Geometry Index'");
|
||||
InstructionDesc[OpFetchMicroTriangleVertexPositionNV].operands.push(OperandId, "'Primitive Index'");
|
||||
InstructionDesc[OpFetchMicroTriangleVertexPositionNV].operands.push(OperandId, "'Barycentrics'");
|
||||
InstructionDesc[OpFetchMicroTriangleVertexPositionNV].setResultAndType(true, true);
|
||||
|
||||
InstructionDesc[OpColorAttachmentReadEXT].operands.push(OperandId, "'Attachment'");
|
||||
InstructionDesc[OpColorAttachmentReadEXT].operands.push(OperandId, "'Sample'", true);
|
||||
InstructionDesc[OpStencilAttachmentReadEXT].operands.push(OperandId, "'Sample'", true);
|
||||
|
|
|
@ -720,6 +720,10 @@ enum BuiltIn {
|
|||
BuiltInHitKindNV = 5333,
|
||||
BuiltInCurrentRayTimeNV = 5334,
|
||||
BuiltInHitTriangleVertexPositionsKHR = 5335,
|
||||
BuiltInHitMicroTriangleVertexPositionsNV = 5337,
|
||||
BuiltInHitMicroTriangleVertexBarycentricsNV = 5344,
|
||||
BuiltInHitKindFrontFacingMicroTriangleNV = 5405,
|
||||
BuiltInHitKindBackFacingMicroTriangleNV = 5406,
|
||||
BuiltInIncomingRayFlagsKHR = 5351,
|
||||
BuiltInIncomingRayFlagsNV = 5351,
|
||||
BuiltInRayGeometryIndexKHR = 5352,
|
||||
|
@ -1094,6 +1098,8 @@ enum Capability {
|
|||
CapabilityFragmentShaderPixelInterlockEXT = 5378,
|
||||
CapabilityDemoteToHelperInvocation = 5379,
|
||||
CapabilityDemoteToHelperInvocationEXT = 5379,
|
||||
CapabilityDisplacementMicromapNV = 5380,
|
||||
CapabilityRayTracingDisplacementMicromapNV = 5409,
|
||||
CapabilityRayTracingOpacityMicromapEXT = 5381,
|
||||
CapabilityShaderInvocationReorderNV = 5383,
|
||||
CapabilityBindlessTextureNV = 5390,
|
||||
|
@ -1268,26 +1274,26 @@ enum PackedVectorFormat {
|
|||
};
|
||||
|
||||
enum CooperativeMatrixOperandsShift {
|
||||
CooperativeMatrixOperandsMatrixASignedComponentsShift = 0,
|
||||
CooperativeMatrixOperandsMatrixBSignedComponentsShift = 1,
|
||||
CooperativeMatrixOperandsMatrixCSignedComponentsShift = 2,
|
||||
CooperativeMatrixOperandsMatrixResultSignedComponentsShift = 3,
|
||||
CooperativeMatrixOperandsSaturatingAccumulationShift = 4,
|
||||
CooperativeMatrixOperandsMatrixASignedComponentsKHRShift = 0,
|
||||
CooperativeMatrixOperandsMatrixBSignedComponentsKHRShift = 1,
|
||||
CooperativeMatrixOperandsMatrixCSignedComponentsKHRShift = 2,
|
||||
CooperativeMatrixOperandsMatrixResultSignedComponentsKHRShift = 3,
|
||||
CooperativeMatrixOperandsSaturatingAccumulationKHRShift = 4,
|
||||
CooperativeMatrixOperandsMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
enum CooperativeMatrixOperandsMask {
|
||||
CooperativeMatrixOperandsMaskNone = 0,
|
||||
CooperativeMatrixOperandsMatrixASignedComponentsMask = 0x00000001,
|
||||
CooperativeMatrixOperandsMatrixBSignedComponentsMask = 0x00000002,
|
||||
CooperativeMatrixOperandsMatrixCSignedComponentsMask = 0x00000004,
|
||||
CooperativeMatrixOperandsMatrixResultSignedComponentsMask = 0x00000008,
|
||||
CooperativeMatrixOperandsSaturatingAccumulationMask = 0x00000010,
|
||||
CooperativeMatrixOperandsMatrixASignedComponentsKHRMask = 0x00000001,
|
||||
CooperativeMatrixOperandsMatrixBSignedComponentsKHRMask = 0x00000002,
|
||||
CooperativeMatrixOperandsMatrixCSignedComponentsKHRMask = 0x00000004,
|
||||
CooperativeMatrixOperandsMatrixResultSignedComponentsKHRMask = 0x00000008,
|
||||
CooperativeMatrixOperandsSaturatingAccumulationKHRMask = 0x00000010,
|
||||
};
|
||||
|
||||
enum CooperativeMatrixLayout {
|
||||
CooperativeMatrixLayoutCooperativeMatrixRowMajorKHR = 0,
|
||||
CooperativeMatrixLayoutCooperativeMatrixColumnMajorKHR = 1,
|
||||
CooperativeMatrixLayoutRowMajorKHR = 0,
|
||||
CooperativeMatrixLayoutColumnMajorKHR = 1,
|
||||
CooperativeMatrixLayoutMax = 0x7fffffff,
|
||||
};
|
||||
|
||||
|
@ -1736,6 +1742,8 @@ enum Op {
|
|||
OpSetMeshOutputsEXT = 5295,
|
||||
OpGroupNonUniformPartitionNV = 5296,
|
||||
OpWritePackedPrimitiveIndices4x8NV = 5299,
|
||||
OpFetchMicroTriangleVertexPositionNV = 5300,
|
||||
OpFetchMicroTriangleVertexBarycentricNV = 5301,
|
||||
OpReportIntersectionKHR = 5334,
|
||||
OpReportIntersectionNV = 5334,
|
||||
OpIgnoreIntersectionNV = 5335,
|
||||
|
|
|
@ -323,7 +323,7 @@ void inReadableOrder(Block* root, std::function<void(Block*, ReachReason, Block*
|
|||
|
||||
class Function {
|
||||
public:
|
||||
Function(Id id, Id resultType, Id functionType, Id firstParam, Module& parent);
|
||||
Function(Id id, Id resultType, Id functionType, Id firstParam, LinkageType linkage, const std::string& name, Module& parent);
|
||||
virtual ~Function()
|
||||
{
|
||||
for (int i = 0; i < (int)parameterInstructions.size(); ++i)
|
||||
|
@ -352,6 +352,7 @@ public:
|
|||
void addLocalVariable(std::unique_ptr<Instruction> inst);
|
||||
Id getReturnType() const { return functionInstruction.getTypeId(); }
|
||||
Id getFuncId() const { return functionInstruction.getResultId(); }
|
||||
Id getFuncTypeId() const { return functionInstruction.getIdOperand(1); }
|
||||
void setReturnPrecision(Decoration precision)
|
||||
{
|
||||
if (precision == DecorationRelaxedPrecision)
|
||||
|
@ -402,6 +403,9 @@ public:
|
|||
end.dump(out);
|
||||
}
|
||||
|
||||
LinkageType getLinkType() const { return linkType; }
|
||||
const char* getExportName() const { return exportName.c_str(); }
|
||||
|
||||
protected:
|
||||
Function(const Function&);
|
||||
Function& operator=(Function&);
|
||||
|
@ -414,6 +418,8 @@ protected:
|
|||
bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument
|
||||
bool reducedPrecisionReturn;
|
||||
std::set<int> reducedPrecisionParams; // list of parameter indexes that need a relaxed precision arg
|
||||
LinkageType linkType;
|
||||
std::string exportName;
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -473,10 +479,11 @@ protected:
|
|||
// Add both
|
||||
// - the OpFunction instruction
|
||||
// - all the OpFunctionParameter instructions
|
||||
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)
|
||||
__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),
|
||||
reducedPrecisionReturn(false)
|
||||
reducedPrecisionReturn(false),
|
||||
linkType(linkage)
|
||||
{
|
||||
// OpFunction
|
||||
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
|
||||
|
@ -492,6 +499,11 @@ __inline Function::Function(Id id, Id resultType, Id functionType, Id firstParam
|
|||
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) {
|
||||
exportName = name.substr(0, name.find_first_of('('));
|
||||
}
|
||||
}
|
||||
|
||||
__inline void Function::addLocalVariable(std::unique_ptr<Instruction> inst)
|
||||
|
|
|
@ -51,15 +51,16 @@
|
|||
#include "../SPIRV/doc.h"
|
||||
#include "../SPIRV/disassemble.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <array>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <set>
|
||||
#include <thread>
|
||||
|
||||
#include "../glslang/OSDependent/osinclude.h"
|
||||
|
||||
|
@ -73,40 +74,41 @@ extern "C" {
|
|||
}
|
||||
|
||||
// Command-line options
|
||||
enum TOptions {
|
||||
EOptionNone = 0,
|
||||
EOptionIntermediate = (1 << 0),
|
||||
EOptionSuppressInfolog = (1 << 1),
|
||||
EOptionMemoryLeakMode = (1 << 2),
|
||||
EOptionRelaxedErrors = (1 << 3),
|
||||
EOptionGiveWarnings = (1 << 4),
|
||||
EOptionLinkProgram = (1 << 5),
|
||||
EOptionMultiThreaded = (1 << 6),
|
||||
EOptionDumpConfig = (1 << 7),
|
||||
EOptionDumpReflection = (1 << 8),
|
||||
EOptionSuppressWarnings = (1 << 9),
|
||||
EOptionDumpVersions = (1 << 10),
|
||||
EOptionSpv = (1 << 11),
|
||||
EOptionHumanReadableSpv = (1 << 12),
|
||||
EOptionVulkanRules = (1 << 13),
|
||||
EOptionDefaultDesktop = (1 << 14),
|
||||
EOptionOutputPreprocessed = (1 << 15),
|
||||
EOptionOutputHexadecimal = (1 << 16),
|
||||
EOptionReadHlsl = (1 << 17),
|
||||
EOptionCascadingErrors = (1 << 18),
|
||||
EOptionAutoMapBindings = (1 << 19),
|
||||
EOptionFlattenUniformArrays = (1 << 20),
|
||||
EOptionNoStorageFormat = (1 << 21),
|
||||
EOptionKeepUncalled = (1 << 22),
|
||||
EOptionHlslOffsets = (1 << 23),
|
||||
EOptionHlslIoMapping = (1 << 24),
|
||||
EOptionAutoMapLocations = (1 << 25),
|
||||
EOptionDebug = (1 << 26),
|
||||
EOptionStdin = (1 << 27),
|
||||
EOptionOptimizeDisable = (1 << 28),
|
||||
EOptionOptimizeSize = (1 << 29),
|
||||
EOptionInvertY = (1 << 30),
|
||||
EOptionDumpBareVersion = (1 << 31),
|
||||
enum TOptions : uint64_t {
|
||||
EOptionNone = 0,
|
||||
EOptionIntermediate = (1ull << 0),
|
||||
EOptionSuppressInfolog = (1ull << 1),
|
||||
EOptionMemoryLeakMode = (1ull << 2),
|
||||
EOptionRelaxedErrors = (1ull << 3),
|
||||
EOptionGiveWarnings = (1ull << 4),
|
||||
EOptionLinkProgram = (1ull << 5),
|
||||
EOptionMultiThreaded = (1ull << 6),
|
||||
EOptionDumpConfig = (1ull << 7),
|
||||
EOptionDumpReflection = (1ull << 8),
|
||||
EOptionSuppressWarnings = (1ull << 9),
|
||||
EOptionDumpVersions = (1ull << 10),
|
||||
EOptionSpv = (1ull << 11),
|
||||
EOptionHumanReadableSpv = (1ull << 12),
|
||||
EOptionVulkanRules = (1ull << 13),
|
||||
EOptionDefaultDesktop = (1ull << 14),
|
||||
EOptionOutputPreprocessed = (1ull << 15),
|
||||
EOptionOutputHexadecimal = (1ull << 16),
|
||||
EOptionReadHlsl = (1ull << 17),
|
||||
EOptionCascadingErrors = (1ull << 18),
|
||||
EOptionAutoMapBindings = (1ull << 19),
|
||||
EOptionFlattenUniformArrays = (1ull << 20),
|
||||
EOptionNoStorageFormat = (1ull << 21),
|
||||
EOptionKeepUncalled = (1ull << 22),
|
||||
EOptionHlslOffsets = (1ull << 23),
|
||||
EOptionHlslIoMapping = (1ull << 24),
|
||||
EOptionAutoMapLocations = (1ull << 25),
|
||||
EOptionDebug = (1ull << 26),
|
||||
EOptionStdin = (1ull << 27),
|
||||
EOptionOptimizeDisable = (1ull << 28),
|
||||
EOptionOptimizeSize = (1ull << 29),
|
||||
EOptionInvertY = (1ull << 30),
|
||||
EOptionDumpBareVersion = (1ull << 31),
|
||||
EOptionCompileOnly = (1ull << 32),
|
||||
};
|
||||
bool targetHlslFunctionality1 = false;
|
||||
bool SpvToolsDisassembler = false;
|
||||
|
@ -143,8 +145,9 @@ void FreeFileData(char* data);
|
|||
void InfoLogMsg(const char* msg, const char* name, const int num);
|
||||
|
||||
// Globally track if any compile or link failure.
|
||||
bool CompileFailed = false;
|
||||
bool LinkFailed = false;
|
||||
std::atomic<int8_t> CompileFailed{0};
|
||||
std::atomic<int8_t> LinkFailed{0};
|
||||
std::atomic<int8_t> CompileOrLinkFailed{0};
|
||||
|
||||
// array of unique places to leave the shader names and infologs for the asynchronous compiles
|
||||
std::vector<std::unique_ptr<glslang::TWorkItem>> WorkItems;
|
||||
|
@ -166,7 +169,7 @@ void ProcessConfigFile()
|
|||
}
|
||||
|
||||
int ReflectOptions = EShReflectionDefault;
|
||||
int Options = 0;
|
||||
std::underlying_type_t<TOptions> Options = EOptionNone;
|
||||
const char* ExecutableName = nullptr;
|
||||
const char* binaryFileName = nullptr;
|
||||
const char* depencyFileName = nullptr;
|
||||
|
@ -513,7 +516,7 @@ void ProcessGlobalBlockSettings(int& argc, char**& argv, std::string* name, unsi
|
|||
|
||||
if (set) {
|
||||
errno = 0;
|
||||
int setVal = ::strtol(argv[curArg], nullptr, 10);
|
||||
int setVal = static_cast<int>(::strtol(argv[curArg], nullptr, 10));
|
||||
if (errno || setVal < 0) {
|
||||
printf("%s: invalid set\n", argv[curArg]);
|
||||
usage();
|
||||
|
@ -525,7 +528,7 @@ void ProcessGlobalBlockSettings(int& argc, char**& argv, std::string* name, unsi
|
|||
|
||||
if (binding) {
|
||||
errno = 0;
|
||||
int bindingVal = ::strtol(argv[curArg], nullptr, 10);
|
||||
int bindingVal = static_cast<int>(::strtol(argv[curArg], nullptr, 10));
|
||||
if (errno || bindingVal < 0) {
|
||||
printf("%s: invalid binding\n", argv[curArg]);
|
||||
usage();
|
||||
|
@ -608,7 +611,7 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
|||
exit(EFailUsage);
|
||||
}
|
||||
errno = 0;
|
||||
int location = ::strtol(split + 1, nullptr, 10);
|
||||
int location = static_cast<int>(::strtol(split + 1, nullptr, 10));
|
||||
if (errno) {
|
||||
printf("%s: invalid location\n", arg);
|
||||
exit(EFailUsage);
|
||||
|
@ -635,7 +638,7 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
|||
} else if (lowerword == "uniform-base") {
|
||||
if (argc <= 1)
|
||||
Error("no <base> provided", lowerword.c_str());
|
||||
uniformBase = ::strtol(argv[1], nullptr, 10);
|
||||
uniformBase = static_cast<int>(::strtol(argv[1], nullptr, 10));
|
||||
bumpArg();
|
||||
break;
|
||||
} else if (lowerword == "client") {
|
||||
|
@ -889,6 +892,8 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
|
|||
bumpArg();
|
||||
} else if (lowerword == "version") {
|
||||
Options |= EOptionDumpVersions;
|
||||
} else if (lowerword == "no-link") {
|
||||
Options |= EOptionCompileOnly;
|
||||
} else if (lowerword == "help") {
|
||||
usage();
|
||||
break;
|
||||
|
@ -1163,10 +1168,11 @@ void CompileShaders(glslang::TWorklist& worklist)
|
|||
if (Options & EOptionDebug)
|
||||
Error("cannot generate debug information unless linking to generate code");
|
||||
|
||||
// NOTE: TWorkList::remove is thread-safe
|
||||
glslang::TWorkItem* workItem;
|
||||
if (Options & EOptionStdin) {
|
||||
if (worklist.remove(workItem)) {
|
||||
ShHandle compiler = ShConstructCompiler(FindLanguage("stdin"), Options);
|
||||
ShHandle compiler = ShConstructCompiler(FindLanguage("stdin"), 0);
|
||||
if (compiler == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -1179,7 +1185,7 @@ void CompileShaders(glslang::TWorklist& worklist)
|
|||
}
|
||||
} else {
|
||||
while (worklist.remove(workItem)) {
|
||||
ShHandle compiler = ShConstructCompiler(FindLanguage(workItem->name), Options);
|
||||
ShHandle compiler = ShConstructCompiler(FindLanguage(workItem->name), 0);
|
||||
if (compiler == nullptr)
|
||||
return;
|
||||
|
||||
|
@ -1310,6 +1316,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||
//
|
||||
|
||||
glslang::TProgram& program = *new glslang::TProgram;
|
||||
const bool compileOnly = (Options & EOptionCompileOnly) != 0;
|
||||
for (auto it = compUnits.cbegin(); it != compUnits.cend(); ++it) {
|
||||
const auto &compUnit = *it;
|
||||
for (int i = 0; i < compUnit.count; i++) {
|
||||
|
@ -1326,6 +1333,9 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||
shader->setSourceEntryPoint(sourceEntryPointName);
|
||||
}
|
||||
|
||||
if (compileOnly)
|
||||
shader->setCompileOnly();
|
||||
|
||||
shader->setOverrideVersion(GlslVersion);
|
||||
|
||||
std::string intrinsicString = getIntrinsic(compUnit.text, compUnit.count);
|
||||
|
@ -1435,7 +1445,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||
if (shader->preprocess(GetResources(), defaultVersion, ENoProfile, false, false, messages, &str, includer)) {
|
||||
PutsIfNonEmpty(str.c_str());
|
||||
} else {
|
||||
CompileFailed = true;
|
||||
CompileFailed = 1;
|
||||
}
|
||||
StderrIfNonEmpty(shader->getInfoLog());
|
||||
StderrIfNonEmpty(shader->getInfoDebugLog());
|
||||
|
@ -1443,9 +1453,10 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||
}
|
||||
|
||||
if (! shader->parse(GetResources(), defaultVersion, false, messages, includer))
|
||||
CompileFailed = true;
|
||||
CompileFailed = 1;
|
||||
|
||||
program.addShader(shader);
|
||||
if (!compileOnly)
|
||||
program.addShader(shader);
|
||||
|
||||
if (! (Options & EOptionSuppressInfolog) &&
|
||||
! (Options & EOptionMemoryLeakMode)) {
|
||||
|
@ -1460,79 +1471,98 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
|
|||
// Program-level processing...
|
||||
//
|
||||
|
||||
// Link
|
||||
if (! (Options & EOptionOutputPreprocessed) && ! program.link(messages))
|
||||
LinkFailed = true;
|
||||
|
||||
// Map IO
|
||||
if (Options & EOptionSpv) {
|
||||
if (!program.mapIO())
|
||||
if (!compileOnly) {
|
||||
// Link
|
||||
if (!(Options & EOptionOutputPreprocessed) && !program.link(messages))
|
||||
LinkFailed = true;
|
||||
}
|
||||
|
||||
// Report
|
||||
if (! (Options & EOptionSuppressInfolog) &&
|
||||
! (Options & EOptionMemoryLeakMode)) {
|
||||
PutsIfNonEmpty(program.getInfoLog());
|
||||
PutsIfNonEmpty(program.getInfoDebugLog());
|
||||
}
|
||||
// Map IO
|
||||
if (Options & EOptionSpv) {
|
||||
if (!program.mapIO())
|
||||
LinkFailed = true;
|
||||
}
|
||||
|
||||
// Reflect
|
||||
if (Options & EOptionDumpReflection) {
|
||||
program.buildReflection(ReflectOptions);
|
||||
program.dumpReflection();
|
||||
// Report
|
||||
if (!(Options & EOptionSuppressInfolog) && !(Options & EOptionMemoryLeakMode)) {
|
||||
PutsIfNonEmpty(program.getInfoLog());
|
||||
PutsIfNonEmpty(program.getInfoDebugLog());
|
||||
}
|
||||
|
||||
// Reflect
|
||||
if (Options & EOptionDumpReflection) {
|
||||
program.buildReflection(ReflectOptions);
|
||||
program.dumpReflection();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::string> outputFiles;
|
||||
|
||||
// Dump SPIR-V
|
||||
if (Options & EOptionSpv) {
|
||||
if (CompileFailed || LinkFailed)
|
||||
CompileOrLinkFailed.fetch_or(CompileFailed);
|
||||
CompileOrLinkFailed.fetch_or(LinkFailed);
|
||||
if (static_cast<bool>(CompileOrLinkFailed.load()))
|
||||
printf("SPIR-V is not generated for failed compile or link\n");
|
||||
else {
|
||||
for (int stage = 0; stage < EShLangCount; ++stage) {
|
||||
if (program.getIntermediate((EShLanguage)stage)) {
|
||||
std::vector<unsigned int> spirv;
|
||||
spv::SpvBuildLogger logger;
|
||||
glslang::SpvOptions spvOptions;
|
||||
if (Options & EOptionDebug) {
|
||||
spvOptions.generateDebugInfo = true;
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
spvOptions.emitNonSemanticShaderDebugInfo = true;
|
||||
if (emitNonSemanticShaderDebugSource) {
|
||||
spvOptions.emitNonSemanticShaderDebugSource = true;
|
||||
}
|
||||
}
|
||||
} else if (stripDebugInfo)
|
||||
spvOptions.stripDebugInfo = true;
|
||||
spvOptions.disableOptimizer = (Options & EOptionOptimizeDisable) != 0;
|
||||
spvOptions.optimizeSize = (Options & EOptionOptimizeSize) != 0;
|
||||
spvOptions.disassemble = SpvToolsDisassembler;
|
||||
spvOptions.validate = SpvToolsValidate;
|
||||
glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv, &logger, &spvOptions);
|
||||
|
||||
// Dump the spv to a file or stdout, etc., but only if not doing
|
||||
// memory/perf testing, as it's not internal to programmatic use.
|
||||
if (! (Options & EOptionMemoryLeakMode)) {
|
||||
printf("%s", logger.getAllMessages().c_str());
|
||||
if (Options & EOptionOutputHexadecimal) {
|
||||
if (!glslang::OutputSpvHex(spirv, GetBinaryName((EShLanguage)stage), variableName))
|
||||
exit(EFailUsage);
|
||||
} else {
|
||||
if (!glslang::OutputSpvBin(spirv, GetBinaryName((EShLanguage)stage)))
|
||||
exit(EFailUsage);
|
||||
}
|
||||
|
||||
outputFiles.push_back(GetBinaryName((EShLanguage)stage));
|
||||
if (!SpvToolsDisassembler && (Options & EOptionHumanReadableSpv))
|
||||
spv::Disassemble(std::cout, spirv);
|
||||
std::vector<glslang::TIntermediate*> intermediates;
|
||||
if (!compileOnly) {
|
||||
for (int stage = 0; stage < EShLangCount; ++stage) {
|
||||
if (auto* i = program.getIntermediate((EShLanguage)stage)) {
|
||||
intermediates.emplace_back(i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const auto* shader : shaders) {
|
||||
if (auto* i = shader->getIntermediate()) {
|
||||
intermediates.emplace_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto* intermediate : intermediates) {
|
||||
std::vector<unsigned int> spirv;
|
||||
spv::SpvBuildLogger logger;
|
||||
glslang::SpvOptions spvOptions;
|
||||
if (Options & EOptionDebug) {
|
||||
spvOptions.generateDebugInfo = true;
|
||||
if (emitNonSemanticShaderDebugInfo) {
|
||||
spvOptions.emitNonSemanticShaderDebugInfo = true;
|
||||
if (emitNonSemanticShaderDebugSource) {
|
||||
spvOptions.emitNonSemanticShaderDebugSource = true;
|
||||
}
|
||||
}
|
||||
} else if (stripDebugInfo)
|
||||
spvOptions.stripDebugInfo = true;
|
||||
spvOptions.disableOptimizer = (Options & EOptionOptimizeDisable) != 0;
|
||||
spvOptions.optimizeSize = (Options & EOptionOptimizeSize) != 0;
|
||||
spvOptions.disassemble = SpvToolsDisassembler;
|
||||
spvOptions.validate = SpvToolsValidate;
|
||||
spvOptions.compileOnly = compileOnly;
|
||||
glslang::GlslangToSpv(*intermediate, spirv, &logger, &spvOptions);
|
||||
|
||||
// Dump the spv to a file or stdout, etc., but only if not doing
|
||||
// memory/perf testing, as it's not internal to programmatic use.
|
||||
if (!(Options & EOptionMemoryLeakMode)) {
|
||||
printf("%s", logger.getAllMessages().c_str());
|
||||
const auto filename = GetBinaryName(intermediate->getStage());
|
||||
if (Options & EOptionOutputHexadecimal) {
|
||||
if (!glslang::OutputSpvHex(spirv, filename, variableName))
|
||||
exit(EFailUsage);
|
||||
} else {
|
||||
if (!glslang::OutputSpvBin(spirv, filename))
|
||||
exit(EFailUsage);
|
||||
}
|
||||
|
||||
outputFiles.push_back(filename);
|
||||
if (!SpvToolsDisassembler && (Options & EOptionHumanReadableSpv))
|
||||
spv::Disassemble(std::cout, spirv);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (depencyFileName && !(CompileFailed || LinkFailed)) {
|
||||
CompileOrLinkFailed.fetch_or(CompileFailed);
|
||||
CompileOrLinkFailed.fetch_or(LinkFailed);
|
||||
if (depencyFileName && !static_cast<bool>(CompileOrLinkFailed.load())) {
|
||||
std::set<std::string> includedFiles = includer.getIncludedFiles();
|
||||
sources.insert(sources.end(), includedFiles.begin(), includedFiles.end());
|
||||
|
||||
|
@ -1708,9 +1738,9 @@ int singleMain()
|
|||
ShFinalize();
|
||||
}
|
||||
|
||||
if (CompileFailed)
|
||||
if (CompileFailed.load())
|
||||
return EFailCompile;
|
||||
if (LinkFailed)
|
||||
if (LinkFailed.load())
|
||||
return EFailLink;
|
||||
|
||||
return 0;
|
||||
|
@ -1846,7 +1876,8 @@ void CompileFile(const char* fileName, ShHandle compiler)
|
|||
for (int i = 0; i < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++i) {
|
||||
for (int j = 0; j < ((Options & EOptionMemoryLeakMode) ? 100 : 1); ++j) {
|
||||
// ret = ShCompile(compiler, shaderStrings, NumShaderStrings, lengths, EShOptNone, &Resources, Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
|
||||
ret = ShCompile(compiler, &shaderString, 1, nullptr, EShOptNone, GetResources(), Options, (Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
|
||||
ret = ShCompile(compiler, &shaderString, 1, nullptr, EShOptNone, GetResources(), 0,
|
||||
(Options & EOptionDefaultDesktop) ? 110 : 100, false, messages);
|
||||
// const char* multi[12] = { "# ve", "rsion", " 300 e", "s", "\n#err",
|
||||
// "or should be l", "ine 1", "string 5\n", "float glo", "bal",
|
||||
// ";\n#error should be line 2\n void main() {", "global = 2.3;}" };
|
||||
|
@ -2075,7 +2106,10 @@ void usage()
|
|||
" --variable-name <name>\n"
|
||||
" --vn <name> creates a C header file that contains a\n"
|
||||
" uint32_t array named <name>\n"
|
||||
" initialized with the shader binary code\n");
|
||||
" initialized with the shader binary code\n"
|
||||
" --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");
|
||||
|
||||
exit(EFailUsage);
|
||||
}
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
#define GLSLANG_BUILD_INFO
|
||||
|
||||
#define GLSLANG_VERSION_MAJOR 13
|
||||
#define GLSLANG_VERSION_MINOR 0
|
||||
#define GLSLANG_VERSION_PATCH 0
|
||||
#define GLSLANG_VERSION_MINOR 1
|
||||
#define GLSLANG_VERSION_PATCH 1
|
||||
#define GLSLANG_VERSION_FLAVOR ""
|
||||
|
||||
#define GLSLANG_VERSION_GREATER_THAN(major, minor, patch) \
|
||||
|
|
|
@ -41,10 +41,9 @@
|
|||
//
|
||||
class TGenericCompiler : public TCompiler {
|
||||
public:
|
||||
TGenericCompiler(EShLanguage l, int dOptions) : TCompiler(l, infoSink), debugOptions(dOptions) { }
|
||||
TGenericCompiler(EShLanguage l) : TCompiler(l, infoSink) {}
|
||||
virtual bool compile(TIntermNode* root, int version = 0, EProfile profile = ENoProfile);
|
||||
TInfoSink infoSink;
|
||||
int debugOptions;
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -52,10 +51,7 @@ public:
|
|||
// compile object used by higher level code. It returns
|
||||
// a subclass of TCompiler.
|
||||
//
|
||||
TCompiler* ConstructCompiler(EShLanguage language, int debugOptions)
|
||||
{
|
||||
return new TGenericCompiler(language, debugOptions);
|
||||
}
|
||||
TCompiler* ConstructCompiler(EShLanguage language, int) { return new TGenericCompiler(language); }
|
||||
|
||||
//
|
||||
// Delete the compiler made by ConstructCompiler
|
||||
|
|
|
@ -44,11 +44,10 @@
|
|||
//
|
||||
class TGenericLinker : public TLinker {
|
||||
public:
|
||||
TGenericLinker(EShExecutable e, int dOptions) : TLinker(e, infoSink), debugOptions(dOptions) { }
|
||||
TGenericLinker(EShExecutable e) : TLinker(e, infoSink) {}
|
||||
bool link(TCompilerList&, TUniformMap*) { return true; }
|
||||
void getAttributeBindings(ShBindingTable const **) const { }
|
||||
TInfoSink infoSink;
|
||||
int debugOptions;
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -60,10 +59,7 @@ public:
|
|||
virtual int getLocation(const char*) { return 0; }
|
||||
};
|
||||
|
||||
TShHandleBase* ConstructLinker(EShExecutable executable, int debugOptions)
|
||||
{
|
||||
return new TGenericLinker(executable, debugOptions);
|
||||
}
|
||||
TShHandleBase* ConstructLinker(EShExecutable executable, int) { return new TGenericLinker(executable); }
|
||||
|
||||
void DeleteLinker(TShHandleBase* linker)
|
||||
{
|
||||
|
|
|
@ -101,6 +101,8 @@ namespace glslang {
|
|||
|
||||
if (name == "nonwritable") return EatNonWritable;
|
||||
if (name == "nonreadable") return EatNonReadable;
|
||||
|
||||
if (name == "export") return EatExport;
|
||||
} else if (nameSpace.size() > 0)
|
||||
return EatNone;
|
||||
|
||||
|
|
|
@ -290,6 +290,12 @@ enum TBuiltInVariable {
|
|||
EbvLayerPerViewNV,
|
||||
EbvMeshViewCountNV,
|
||||
EbvMeshViewIndicesNV,
|
||||
|
||||
EbvMicroTrianglePositionNV,
|
||||
EbvMicroTriangleBaryNV,
|
||||
EbvHitKindFrontFacingMicroTriangleNV,
|
||||
EbvHitKindBackFacingMicroTriangleNV,
|
||||
|
||||
//GL_EXT_mesh_shader
|
||||
EbvPrimitivePointIndicesEXT,
|
||||
EbvPrimitiveLineIndicesEXT,
|
||||
|
@ -523,6 +529,9 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
|||
case EbvShadingRateKHR: return "ShadingRateKHR";
|
||||
case EbvPrimitiveShadingRateKHR: return "PrimitiveShadingRateKHR";
|
||||
|
||||
case EbvHitKindFrontFacingMicroTriangleNV: return "HitKindFrontFacingMicroTriangleNV";
|
||||
case EbvHitKindBackFacingMicroTriangleNV: return "HitKindBackFacingMicroTriangleNV";
|
||||
|
||||
default: return "unknown built-in variable";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
// GL_EXT_spirv_intrinsics
|
||||
//
|
||||
#include "Common.h"
|
||||
#include <variant>
|
||||
|
||||
namespace glslang {
|
||||
|
||||
|
@ -96,23 +97,27 @@ struct TSpirvInstruction {
|
|||
struct TSpirvTypeParameter {
|
||||
POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
|
||||
|
||||
TSpirvTypeParameter(const TIntermConstantUnion* arg)
|
||||
{
|
||||
constant = arg;
|
||||
type = nullptr;
|
||||
}
|
||||
TSpirvTypeParameter(const TIntermConstantUnion* arg) { value = arg; }
|
||||
TSpirvTypeParameter(const TType* arg) { value = arg; }
|
||||
|
||||
TSpirvTypeParameter(const TType *arg)
|
||||
const TIntermConstantUnion* getAsConstant() const
|
||||
{
|
||||
constant = nullptr;
|
||||
type = arg;
|
||||
if (value.index() == 0)
|
||||
return std::get<const TIntermConstantUnion*>(value);
|
||||
return nullptr;
|
||||
}
|
||||
const TType* getAsType() const
|
||||
{
|
||||
if (value.index() == 1)
|
||||
return std::get<const TType*>(value);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool operator==(const TSpirvTypeParameter& rhs) const;
|
||||
bool operator!=(const TSpirvTypeParameter& rhs) const { return !operator==(rhs); }
|
||||
|
||||
const TIntermConstantUnion* constant; // Constant expression
|
||||
const TType* type; // Type specifier
|
||||
// Parameter value: constant expression or type specifier
|
||||
std::variant<const TIntermConstantUnion*, const TType*> value;
|
||||
};
|
||||
|
||||
typedef TVector<TSpirvTypeParameter> TSpirvTypeParameters;
|
||||
|
|
|
@ -226,6 +226,7 @@ typedef struct glslang_spv_options_s {
|
|||
bool validate;
|
||||
bool emit_nonsemantic_shader_debug_info;
|
||||
bool emit_nonsemantic_shader_debug_source;
|
||||
bool compile_only;
|
||||
} glslang_spv_options_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -1006,6 +1006,8 @@ enum TOperator {
|
|||
EOpHitObjectGetAttributesNV,
|
||||
EOpHitObjectGetCurrentTimeNV,
|
||||
EOpReorderThreadNV,
|
||||
EOpFetchMicroTriangleVertexPositionNV,
|
||||
EOpFetchMicroTriangleVertexBarycentricNV,
|
||||
|
||||
// HLSL operations
|
||||
//
|
||||
|
@ -1108,6 +1110,11 @@ enum TOperator {
|
|||
EOpImageBlockMatchSSDQCOM,
|
||||
};
|
||||
|
||||
enum TLinkType {
|
||||
ELinkNone,
|
||||
ELinkExport,
|
||||
};
|
||||
|
||||
class TIntermTraverser;
|
||||
class TIntermOperator;
|
||||
class TIntermAggregate;
|
||||
|
@ -1325,9 +1332,11 @@ public:
|
|||
virtual const TString& getMethodName() const { return method; }
|
||||
virtual TIntermTyped* getObject() const { return object; }
|
||||
virtual void traverse(TIntermTraverser*);
|
||||
void setExport() { linkType = ELinkExport; }
|
||||
protected:
|
||||
TIntermTyped* object;
|
||||
TString method;
|
||||
TLinkType linkType;
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -1700,6 +1709,9 @@ public:
|
|||
const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
|
||||
void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
|
||||
const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
|
||||
|
||||
void setLinkType(TLinkType l) { linkType = l; }
|
||||
TLinkType getLinkType() const { return linkType; }
|
||||
protected:
|
||||
TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
|
||||
TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
|
||||
|
@ -1711,6 +1723,7 @@ protected:
|
|||
bool debug;
|
||||
TPragmaTable* pragmaTable;
|
||||
TSpirvInstruction spirvInst;
|
||||
TLinkType linkType = ELinkNone;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
// including identifying what extensions are needed if a version does not allow a symbol
|
||||
//
|
||||
|
||||
#include "../Include/intermediate.h"
|
||||
#include "Initialize.h"
|
||||
|
||||
namespace glslang {
|
||||
|
@ -4109,6 +4108,19 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"\n");
|
||||
}
|
||||
|
||||
// Builtins for GL_EXT_texture_shadow_lod
|
||||
if ((profile == EEsProfile && version >= 300) || ((profile != EEsProfile && version >= 130))) {
|
||||
commonBuiltins.append(
|
||||
"float texture(sampler2DArrayShadow, vec4, float);"
|
||||
"float texture(samplerCubeArrayShadow, vec4, float, float);"
|
||||
"float textureLod(sampler2DArrayShadow, vec4, float);"
|
||||
"float textureLod(samplerCubeShadow, vec4, float);"
|
||||
"float textureLod(samplerCubeArrayShadow, vec4, float, float);"
|
||||
"float textureLodOffset(sampler2DArrayShadow, vec4, float, ivec2);"
|
||||
"float textureOffset(sampler2DArrayShadow, vec4 , ivec2, float);"
|
||||
"\n");
|
||||
}
|
||||
|
||||
if (profile != EEsProfile && version >= 450) {
|
||||
stageBuiltins[EShLangFragment].append(derivativesAndControl64bits);
|
||||
stageBuiltins[EShLangFragment].append(
|
||||
|
@ -4702,6 +4714,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"void reorderThreadNV(uint, uint);"
|
||||
"void reorderThreadNV(hitObjectNV);"
|
||||
"void reorderThreadNV(hitObjectNV, uint, uint);"
|
||||
"vec3 fetchMicroTriangleVertexPositionNV(accelerationStructureEXT, int, int, int, ivec2);"
|
||||
"vec2 fetchMicroTriangleVertexBarycentricNV(accelerationStructureEXT, int, int, int, ivec2);"
|
||||
"\n");
|
||||
stageBuiltins[EShLangIntersect].append(
|
||||
"bool reportIntersectionNV(float, uint);"
|
||||
|
@ -4819,6 +4833,20 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"void SetMeshOutputsEXT(uint, uint);"
|
||||
"\n");
|
||||
}
|
||||
// Builtins for GL_NV_displacement_micromap
|
||||
if ((profile != EEsProfile && version >= 460) || (profile == EEsProfile && version >= 320)) {
|
||||
stageBuiltins[EShLangMesh].append(
|
||||
"vec3 fetchMicroTriangleVertexPositionNV(accelerationStructureEXT, int, int, int, ivec2);"
|
||||
"vec2 fetchMicroTriangleVertexBarycentricNV(accelerationStructureEXT, int, int, int, ivec2);"
|
||||
"\n");
|
||||
|
||||
stageBuiltins[EShLangCompute].append(
|
||||
"vec3 fetchMicroTriangleVertexPositionNV(accelerationStructureEXT, int, int, int, ivec2);"
|
||||
"vec2 fetchMicroTriangleVertexBarycentricNV(accelerationStructureEXT, int, int, int, ivec2);"
|
||||
"\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
|
@ -6001,6 +6029,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"const uint gl_RayFlagsForceOpacityMicromap2StateEXT = 1024U;"
|
||||
"const uint gl_HitKindFrontFacingTriangleEXT = 254U;"
|
||||
"const uint gl_HitKindBackFacingTriangleEXT = 255U;"
|
||||
"in uint gl_HitKindFrontFacingMicroTriangleNV;"
|
||||
"in uint gl_HitKindBackFacingMicroTriangleNV;"
|
||||
"\n";
|
||||
|
||||
const char *constRayQueryIntersection =
|
||||
|
@ -6089,7 +6119,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
|
|||
"in float gl_CurrentRayTimeNV;"
|
||||
"in uint gl_CullMaskEXT;"
|
||||
"in vec3 gl_HitTriangleVertexPositionsEXT[3];"
|
||||
"in vec3 gl_HitMicroTriangleVertexPositionsNV[3];"
|
||||
"in vec2 gl_HitMicroTriangleVertexBarycentricsNV[3];"
|
||||
"\n";
|
||||
|
||||
const char *missDecls =
|
||||
"in uvec3 gl_LaunchIDNV;"
|
||||
"in uvec3 gl_LaunchIDEXT;"
|
||||
|
@ -8901,6 +8934,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
symbolTable.setVariableExtensions("gl_ShadingRateFlag2HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate);
|
||||
symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate);
|
||||
}
|
||||
|
||||
if ((profile != EEsProfile && version >= 460)) {
|
||||
symbolTable.setFunctionExtensions("fetchMicroTriangleVertexPositionNV", 1, &E_GL_NV_displacement_micromap);
|
||||
symbolTable.setFunctionExtensions("fetchMicroTriangleVertexBarycentricNV", 1, &E_GL_NV_displacement_micromap);
|
||||
}
|
||||
break;
|
||||
|
||||
case EShLangRayGen:
|
||||
|
@ -8947,6 +8985,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
symbolTable.setVariableExtensions("gl_IncomingRayFlagsEXT", 1, &E_GL_EXT_ray_tracing);
|
||||
symbolTable.setVariableExtensions("gl_CurrentRayTimeNV", 1, &E_GL_NV_ray_tracing_motion_blur);
|
||||
symbolTable.setVariableExtensions("gl_HitTriangleVertexPositionsEXT", 1, &E_GL_EXT_ray_tracing_position_fetch);
|
||||
symbolTable.setVariableExtensions("gl_HitMicroTriangleVertexPositionsNV", 1, &E_GL_NV_displacement_micromap);
|
||||
symbolTable.setVariableExtensions("gl_HitMicroTriangleVertexBarycentricsNV", 1, &E_GL_NV_displacement_micromap);
|
||||
|
||||
symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group);
|
||||
|
||||
|
@ -8992,6 +9032,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
symbolTable.setFunctionExtensions("hitObjectGetShaderBindingTableRecordIndexNV", 1, &E_GL_NV_shader_invocation_reorder);
|
||||
symbolTable.setFunctionExtensions("hitObjectGetShaderRecordBufferHandleNV", 1, &E_GL_NV_shader_invocation_reorder);
|
||||
symbolTable.setFunctionExtensions("reorderThreadNV", 1, &E_GL_NV_shader_invocation_reorder);
|
||||
symbolTable.setFunctionExtensions("fetchMicroTriangleVertexPositionNV", 1, &E_GL_NV_displacement_micromap);
|
||||
symbolTable.setFunctionExtensions("fetchMicroTriangleVertexBarycentricNV", 1, &E_GL_NV_displacement_micromap);
|
||||
|
||||
|
||||
BuiltInVariable("gl_LaunchIDNV", EbvLaunchId, symbolTable);
|
||||
|
@ -9031,6 +9073,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable);
|
||||
BuiltInVariable("gl_CurrentRayTimeNV", EbvCurrentRayTimeNV, symbolTable);
|
||||
BuiltInVariable("gl_HitTriangleVertexPositionsEXT", EbvPositionFetch, symbolTable);
|
||||
BuiltInVariable("gl_HitMicroTriangleVertexPositionsNV", EbvMicroTrianglePositionNV, symbolTable);
|
||||
BuiltInVariable("gl_HitMicroTriangleVertexBarycentricsNV", EbvMicroTriangleBaryNV, symbolTable);
|
||||
BuiltInVariable("gl_HitKindFrontFacingMicroTriangleNV", EbvHitKindFrontFacingMicroTriangleNV, symbolTable);
|
||||
BuiltInVariable("gl_HitKindBackFacingMicroTriangleNV", EbvHitKindBackFacingMicroTriangleNV, symbolTable);
|
||||
|
||||
// GL_ARB_shader_ballot
|
||||
symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot);
|
||||
|
@ -9332,6 +9378,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
symbolTable.setVariableExtensions("gl_ShadingRateFlag2HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate);
|
||||
symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate);
|
||||
}
|
||||
|
||||
// Builtins for GL_NV_displacment_micromap
|
||||
if ((profile != EEsProfile && version >= 460)) {
|
||||
symbolTable.setFunctionExtensions("fetchMicroTriangleVertexPositionNV", 1, &E_GL_NV_displacement_micromap);
|
||||
symbolTable.setFunctionExtensions("fetchMicroTriangleVertexBarycentricNV", 1, &E_GL_NV_displacement_micromap);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EShLangTask:
|
||||
|
@ -10005,9 +10058,18 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
symbolTable.relateToOperator("coopMatLoad", EOpCooperativeMatrixLoad);
|
||||
symbolTable.relateToOperator("coopMatStore", EOpCooperativeMatrixStore);
|
||||
symbolTable.relateToOperator("coopMatMulAdd", EOpCooperativeMatrixMulAdd);
|
||||
|
||||
if (profile != EEsProfile && version >= 460) {
|
||||
symbolTable.relateToOperator("fetchMicroTriangleVertexPositionNV", EOpFetchMicroTriangleVertexPositionNV);
|
||||
symbolTable.relateToOperator("fetchMicroTriangleVertexBarycentricNV", EOpFetchMicroTriangleVertexBarycentricNV);
|
||||
}
|
||||
break;
|
||||
|
||||
case EShLangRayGen:
|
||||
if (profile != EEsProfile && version >= 460) {
|
||||
symbolTable.relateToOperator("fetchMicroTriangleVertexPositionNV", EOpFetchMicroTriangleVertexPositionNV);
|
||||
symbolTable.relateToOperator("fetchMicroTriangleVertexBarycentricNV", EOpFetchMicroTriangleVertexBarycentricNV);
|
||||
} // fallthrough
|
||||
case EShLangClosestHit:
|
||||
case EShLangMiss:
|
||||
if (profile != EEsProfile && version >= 460) {
|
||||
|
@ -10079,6 +10141,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
|
|||
if (profile != EEsProfile && version >= 450) {
|
||||
symbolTable.relateToOperator("SetMeshOutputsEXT", EOpSetMeshOutputsEXT);
|
||||
}
|
||||
|
||||
if (profile != EEsProfile && version >= 460) {
|
||||
// Builtins for GL_NV_displacement_micromap.
|
||||
symbolTable.relateToOperator("fetchMicroTriangleVertexPositionNV", EOpFetchMicroTriangleVertexPositionNV);
|
||||
symbolTable.relateToOperator("fetchMicroTriangleVertexBarycentricNV", EOpFetchMicroTriangleVertexBarycentricNV);
|
||||
}
|
||||
break;
|
||||
case EShLangTask:
|
||||
if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) {
|
||||
|
|
|
@ -626,10 +626,8 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem
|
|||
if (symbol) {
|
||||
if (memberType != symbol->getType()) {
|
||||
TString err;
|
||||
err += "\"" + memberType.getCompleteString() + "\"";
|
||||
err += " versus ";
|
||||
err += "\"" + symbol->getType().getCompleteString() + "\"";
|
||||
error(loc, "Types must match:", memberType.getFieldName().c_str(), err.c_str());
|
||||
err += "Redeclaration: already declared as \"" + symbol->getType().getCompleteString() + "\"";
|
||||
error(loc, "", memberName.c_str(), err.c_str());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1243,6 +1243,8 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc,
|
|||
error(loc, "function cannot take any parameter(s)", function.getName().c_str(), "");
|
||||
if (function.getType().getBasicType() != EbtVoid)
|
||||
error(loc, "", function.getType().getBasicTypeString().c_str(), "entry point cannot return a value");
|
||||
if (function.getLinkType() != ELinkNone)
|
||||
error(loc, "main function cannot be exported", "", "");
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -1279,6 +1281,7 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc,
|
|||
} else
|
||||
paramNodes = intermediate.growAggregate(paramNodes, intermediate.addSymbol(*param.type, loc), loc);
|
||||
}
|
||||
paramNodes->setLinkType(function.getLinkType());
|
||||
intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), loc);
|
||||
loopNestingLevel = 0;
|
||||
statementNestingLevel = 0;
|
||||
|
@ -2169,6 +2172,37 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case EOpTexture:
|
||||
case EOpTextureLod:
|
||||
{
|
||||
if ((fnCandidate.getParamCount() > 2) && ((*argp)[1]->getAsTyped()->getType().getBasicType() == EbtFloat) &&
|
||||
((*argp)[1]->getAsTyped()->getType().getVectorSize() == 4) && fnCandidate[0].type->getSampler().shadow) {
|
||||
featureString = fnCandidate.getName();
|
||||
if (callNode.getOp() == EOpTexture)
|
||||
featureString += "(..., float bias)";
|
||||
else
|
||||
featureString += "(..., float lod)";
|
||||
feature = featureString.c_str();
|
||||
|
||||
if ((fnCandidate[0].type->getSampler().dim == Esd2D && fnCandidate[0].type->getSampler().arrayed) || //2D Array Shadow
|
||||
(fnCandidate[0].type->getSampler().dim == EsdCube && fnCandidate[0].type->getSampler().arrayed && fnCandidate.getParamCount() > 3) || // Cube Array Shadow
|
||||
(fnCandidate[0].type->getSampler().dim == EsdCube && callNode.getOp() == EOpTextureLod)) { // Cube Shadow
|
||||
requireExtensions(loc, 1, &E_GL_EXT_texture_shadow_lod, feature);
|
||||
if (isEsProfile()) {
|
||||
if (version < 320 &&
|
||||
!extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array))
|
||||
error(loc, "GL_EXT_texture_shadow_lod not supported for this ES version", feature, "");
|
||||
else
|
||||
profileRequires(loc, EEsProfile, 320, nullptr, feature);
|
||||
} else { // Desktop
|
||||
profileRequires(loc, ~EEsProfile, 130, nullptr, feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case EOpSparseTextureGather:
|
||||
case EOpSparseTextureGatherOffset:
|
||||
case EOpSparseTextureGatherOffsets:
|
||||
|
@ -2283,12 +2317,36 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||
if (callNode.getOp() == EOpTextureOffset) {
|
||||
TSampler s = arg0->getType().getSampler();
|
||||
if (s.is2D() && s.isArrayed() && s.isShadow()) {
|
||||
if (isEsProfile())
|
||||
if (
|
||||
((*argp)[1]->getAsTyped()->getType().getBasicType() == EbtFloat) &&
|
||||
((*argp)[1]->getAsTyped()->getType().getVectorSize() == 4) &&
|
||||
(fnCandidate.getParamCount() == 4)) {
|
||||
featureString = fnCandidate.getName() + " for sampler2DArrayShadow";
|
||||
feature = featureString.c_str();
|
||||
requireExtensions(loc, 1, &E_GL_EXT_texture_shadow_lod, feature);
|
||||
profileRequires(loc, EEsProfile, 300, nullptr, feature);
|
||||
profileRequires(loc, ~EEsProfile, 130, nullptr, feature);
|
||||
}
|
||||
else if (isEsProfile())
|
||||
error(loc, "TextureOffset does not support sampler2DArrayShadow : ", "sampler", "ES Profile");
|
||||
else if (version <= 420)
|
||||
error(loc, "TextureOffset does not support sampler2DArrayShadow : ", "sampler", "version <= 420");
|
||||
}
|
||||
}
|
||||
|
||||
if (callNode.getOp() == EOpTextureLodOffset) {
|
||||
TSampler s = arg0->getType().getSampler();
|
||||
if (s.is2D() && s.isArrayed() && s.isShadow() &&
|
||||
((*argp)[1]->getAsTyped()->getType().getBasicType() == EbtFloat) &&
|
||||
((*argp)[1]->getAsTyped()->getType().getVectorSize() == 4) &&
|
||||
(fnCandidate.getParamCount() == 4)) {
|
||||
featureString = fnCandidate.getName() + " for sampler2DArrayShadow";
|
||||
feature = featureString.c_str();
|
||||
profileRequires(loc, EEsProfile, 300, nullptr, feature);
|
||||
profileRequires(loc, ~EEsProfile, 130, nullptr, feature);
|
||||
requireExtensions(loc, 1, &E_GL_EXT_texture_shadow_lod, feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -2514,11 +2572,18 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
|
|||
}
|
||||
|
||||
const TIntermTyped* base = TIntermediate::findLValueBase(arg0, true , true);
|
||||
const TType* refType = (base->getType().isReference()) ? base->getType().getReferentType() : nullptr;
|
||||
const TQualifier& qualifier = (refType != nullptr) ? refType->getQualifier() : base->getType().getQualifier();
|
||||
if (qualifier.storage != EvqShared && qualifier.storage != EvqBuffer && qualifier.storage != EvqtaskPayloadSharedEXT)
|
||||
error(loc,"Atomic memory function can only be used for shader storage block member or shared variable.",
|
||||
fnCandidate.getName().c_str(), "");
|
||||
const char* errMsg = "Only l-values corresponding to shader block storage or shared variables can be used with "
|
||||
"atomic memory functions.";
|
||||
if (base) {
|
||||
const TType* refType = (base->getType().isReference()) ? base->getType().getReferentType() : nullptr;
|
||||
const TQualifier& qualifier =
|
||||
(refType != nullptr) ? refType->getQualifier() : base->getType().getQualifier();
|
||||
if (qualifier.storage != EvqShared && qualifier.storage != EvqBuffer &&
|
||||
qualifier.storage != EvqtaskPayloadSharedEXT)
|
||||
error(loc, errMsg, fnCandidate.getName().c_str(), "");
|
||||
} else {
|
||||
error(loc, errMsg, fnCandidate.getName().c_str(), "");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -196,6 +196,7 @@ public:
|
|||
struct TPragma contextPragma;
|
||||
int beginInvocationInterlockCount;
|
||||
int endInvocationInterlockCount;
|
||||
bool compileOnly = false;
|
||||
|
||||
protected:
|
||||
TParseContextBase(TParseContextBase&);
|
||||
|
|
|
@ -1073,12 +1073,18 @@ int TScanContext::tokenizeIdentifier()
|
|||
parseContext.extensionTurnedOn(E_GL_NV_ray_tracing))
|
||||
return keyword;
|
||||
return identifierOrType();
|
||||
case ACCSTRUCTEXT:
|
||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||
parseContext.extensionTurnedOn(E_GL_EXT_ray_tracing) ||
|
||||
parseContext.extensionTurnedOn(E_GL_EXT_ray_query) ||
|
||||
parseContext.extensionTurnedOn(E_GL_NV_displacement_micromap))
|
||||
return keyword;
|
||||
return identifierOrType();
|
||||
case PAYLOADEXT:
|
||||
case PAYLOADINEXT:
|
||||
case HITATTREXT:
|
||||
case CALLDATAEXT:
|
||||
case CALLDATAINEXT:
|
||||
case ACCSTRUCTEXT:
|
||||
if (parseContext.symbolTable.atBuiltInLevel() ||
|
||||
parseContext.extensionTurnedOn(E_GL_EXT_ray_tracing) ||
|
||||
parseContext.extensionTurnedOn(E_GL_EXT_ray_query))
|
||||
|
|
|
@ -796,7 +796,8 @@ bool ProcessDeferred(
|
|||
bool requireNonempty,
|
||||
TShader::Includer& includer,
|
||||
const std::string sourceEntryPointName = "",
|
||||
const TEnvironment* environment = nullptr) // optional way of fully setting all versions, overriding the above
|
||||
const TEnvironment* environment = nullptr, // optional way of fully setting all versions, overriding the above
|
||||
bool compileOnly = false)
|
||||
{
|
||||
// This must be undone (.pop()) by the caller, after it finishes consuming the created tree.
|
||||
GetThreadPoolAllocator().push();
|
||||
|
@ -942,6 +943,7 @@ bool ProcessDeferred(
|
|||
std::unique_ptr<TParseContextBase> parseContext(CreateParseContext(*symbolTable, intermediate, version, profile, source,
|
||||
stage, compiler->infoSink,
|
||||
spvVersion, forwardCompatible, messages, false, sourceEntryPointName));
|
||||
parseContext->compileOnly = compileOnly;
|
||||
TPpContext ppContext(*parseContext, names[numPre] ? names[numPre] : "", includer);
|
||||
|
||||
// only GLSL (bison triggered, really) needs an externally set scan context
|
||||
|
@ -1066,8 +1068,8 @@ struct DoPreprocessing {
|
|||
EShOptimizationLevel, EShMessages)
|
||||
{
|
||||
// This is a list of tokens that do not require a space before or after.
|
||||
static const std::string unNeededSpaceTokens = ";()[]";
|
||||
static const std::string noSpaceBeforeTokens = ",";
|
||||
static const std::string noNeededSpaceBeforeTokens = ";)[].,";
|
||||
static const std::string noNeededSpaceAfterTokens = ".([";
|
||||
glslang::TPpToken ppToken;
|
||||
|
||||
parseContext.setScanner(&input);
|
||||
|
@ -1140,6 +1142,7 @@ struct DoPreprocessing {
|
|||
});
|
||||
|
||||
int lastToken = EndOfInput; // lastToken records the last token processed.
|
||||
std::string lastTokenName;
|
||||
do {
|
||||
int token = ppContext.tokenize(ppToken);
|
||||
if (token == EndOfInput)
|
||||
|
@ -1158,12 +1161,23 @@ struct DoPreprocessing {
|
|||
// Output a space in between tokens, but not at the start of a line,
|
||||
// and also not around special tokens. This helps with readability
|
||||
// and consistency.
|
||||
if (!isNewString && !isNewLine && lastToken != EndOfInput &&
|
||||
(unNeededSpaceTokens.find((char)token) == std::string::npos) &&
|
||||
(unNeededSpaceTokens.find((char)lastToken) == std::string::npos) &&
|
||||
(noSpaceBeforeTokens.find((char)token) == std::string::npos)) {
|
||||
outputBuffer += ' ';
|
||||
if (!isNewString && !isNewLine && lastToken != EndOfInput) {
|
||||
// left parenthesis need a leading space, except it is in a function-call-like context.
|
||||
// examples: `for (xxx)`, `a * (b + c)`, `vec(2.0)`, `foo(x, y, z)`
|
||||
if (token == '(') {
|
||||
if (lastToken != PpAtomIdentifier ||
|
||||
lastTokenName == "if" ||
|
||||
lastTokenName == "for" ||
|
||||
lastTokenName == "while" ||
|
||||
lastTokenName == "switch")
|
||||
outputBuffer += ' ';
|
||||
} else if ((noNeededSpaceBeforeTokens.find((char)token) == std::string::npos) &&
|
||||
(noNeededSpaceAfterTokens.find((char)lastToken) == std::string::npos)) {
|
||||
outputBuffer += ' ';
|
||||
}
|
||||
}
|
||||
if (token == PpAtomIdentifier)
|
||||
lastTokenName = ppToken.name;
|
||||
lastToken = token;
|
||||
if (token == PpAtomConstString)
|
||||
outputBuffer += "\"";
|
||||
|
@ -1279,14 +1293,15 @@ bool CompileDeferred(
|
|||
TIntermediate& intermediate,// returned tree, etc.
|
||||
TShader::Includer& includer,
|
||||
const std::string sourceEntryPointName = "",
|
||||
TEnvironment* environment = nullptr)
|
||||
TEnvironment* environment = nullptr,
|
||||
bool compileOnly = false)
|
||||
{
|
||||
DoFullParse parser;
|
||||
return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames,
|
||||
preamble, optLevel, resources, defaultVersion,
|
||||
defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
|
||||
forwardCompatible, messages, intermediate, parser,
|
||||
true, includer, sourceEntryPointName, environment);
|
||||
true, includer, sourceEntryPointName, environment, compileOnly);
|
||||
}
|
||||
|
||||
} // end anonymous namespace for local functions
|
||||
|
@ -1318,22 +1333,22 @@ int ShInitialize()
|
|||
// objects.
|
||||
//
|
||||
|
||||
ShHandle ShConstructCompiler(const EShLanguage language, int debugOptions)
|
||||
ShHandle ShConstructCompiler(const EShLanguage language, int /*debugOptions unused*/)
|
||||
{
|
||||
if (!InitThread())
|
||||
return nullptr;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, debugOptions));
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructCompiler(language, 0));
|
||||
|
||||
return reinterpret_cast<void*>(base);
|
||||
}
|
||||
|
||||
ShHandle ShConstructLinker(const EShExecutable executable, int debugOptions)
|
||||
ShHandle ShConstructLinker(const EShExecutable executable, int /*debugOptions unused*/)
|
||||
{
|
||||
if (!InitThread())
|
||||
return nullptr;
|
||||
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructLinker(executable, debugOptions));
|
||||
TShHandleBase* base = static_cast<TShHandleBase*>(ConstructLinker(executable, 0));
|
||||
|
||||
return reinterpret_cast<void*>(base);
|
||||
}
|
||||
|
@ -1867,7 +1882,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
|
|||
preamble, EShOptNone, builtInResources, defaultVersion,
|
||||
defaultProfile, forceDefaultVersionAndProfile, overrideVersion,
|
||||
forwardCompatible, messages, *intermediate, includer, sourceEntryPointName,
|
||||
&environment);
|
||||
&environment, compileOnly);
|
||||
}
|
||||
|
||||
// Fill in a string with the result of preprocessing ShaderStrings
|
||||
|
|
|
@ -45,11 +45,11 @@ namespace glslang {
|
|||
|
||||
bool TSpirvTypeParameter::operator==(const TSpirvTypeParameter& rhs) const
|
||||
{
|
||||
if (constant != nullptr)
|
||||
return constant->getConstArray() == rhs.constant->getConstArray();
|
||||
if (getAsConstant() != nullptr)
|
||||
return getAsConstant()->getConstArray() == rhs.getAsConstant()->getConstArray();
|
||||
|
||||
assert(type != nullptr);
|
||||
return *type == *rhs.type;
|
||||
assert(getAsType() != nullptr);
|
||||
return *getAsType() == *rhs.getAsType();
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
@ -318,6 +318,16 @@ void TSymbolTableLevel::setFunctionExtensions(const char* name, int num, const c
|
|||
}
|
||||
}
|
||||
|
||||
// Make a single function require an extension(s). i.e., this will only set the extensions for the symbol that matches 'name' exactly.
|
||||
// This is different from setFunctionExtensions, which uses std::map::lower_bound to effectively set all symbols that start with 'name'.
|
||||
// Should only be used for a version/profile that actually needs the extension(s).
|
||||
void TSymbolTableLevel::setSingleFunctionExtensions(const char* name, int num, const char* const extensions[])
|
||||
{
|
||||
if (auto candidate = level.find(name); candidate != level.end()) {
|
||||
candidate->second->setExtensions(num, extensions);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Make all symbols in this table level read only.
|
||||
//
|
||||
|
|
|
@ -246,7 +246,8 @@ public:
|
|||
TSymbol(name),
|
||||
mangledName(*name + '('),
|
||||
op(tOp),
|
||||
defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0)
|
||||
defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0),
|
||||
linkType(ELinkNone)
|
||||
{
|
||||
returnType.shallowCopy(retType);
|
||||
declaredBuiltIn = retType.getQualifier().builtIn;
|
||||
|
@ -326,6 +327,9 @@ public:
|
|||
|
||||
virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
|
||||
|
||||
void setExport() { linkType = ELinkExport; }
|
||||
TLinkType getLinkType() const { return linkType; }
|
||||
|
||||
protected:
|
||||
explicit TFunction(const TFunction&);
|
||||
TFunction& operator=(const TFunction&);
|
||||
|
@ -347,6 +351,7 @@ protected:
|
|||
int defaultParamCount;
|
||||
|
||||
TSpirvInstruction spirvInst; // SPIR-V instruction qualifiers
|
||||
TLinkType linkType;
|
||||
};
|
||||
|
||||
//
|
||||
|
@ -571,6 +576,7 @@ public:
|
|||
|
||||
void relateToOperator(const char* name, TOperator op);
|
||||
void setFunctionExtensions(const char* name, int num, const char* const extensions[]);
|
||||
void setSingleFunctionExtensions(const char* name, int num, const char* const extensions[]);
|
||||
void dump(TInfoSink& infoSink, bool complete = false) const;
|
||||
TSymbolTableLevel* clone() const;
|
||||
void readOnly();
|
||||
|
@ -872,6 +878,12 @@ public:
|
|||
table[level]->setFunctionExtensions(name, num, extensions);
|
||||
}
|
||||
|
||||
void setSingleFunctionExtensions(const char* name, int num, const char* const extensions[])
|
||||
{
|
||||
for (unsigned int level = 0; level < table.size(); ++level)
|
||||
table[level]->setSingleFunctionExtensions(name, num, extensions);
|
||||
}
|
||||
|
||||
void setVariableExtensions(const char* name, int numExts, const char* const extensions[])
|
||||
{
|
||||
TSymbol* symbol = find(TString(name));
|
||||
|
|
|
@ -297,12 +297,11 @@ void TParseVersions::initializeExtensionBehavior()
|
|||
extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable;
|
||||
extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable;
|
||||
extensionBehavior[E_GL_NV_mesh_shader] = EBhDisable;
|
||||
|
||||
extensionBehavior[E_GL_NV_cooperative_matrix] = EBhDisable;
|
||||
extensionBehavior[E_GL_NV_shader_sm_builtins] = EBhDisable;
|
||||
extensionBehavior[E_GL_NV_integer_cooperative_matrix] = EBhDisable;
|
||||
|
||||
extensionBehavior[E_GL_NV_shader_invocation_reorder] = EBhDisable;
|
||||
extensionBehavior[E_GL_NV_displacement_micromap] = EBhDisable;
|
||||
|
||||
// ARM
|
||||
extensionBehavior[E_GL_ARM_shader_core_builtins] = EBhDisable;
|
||||
|
@ -359,6 +358,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||
extensionBehavior[E_GL_EXT_opacity_micromap] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_ray_tracing_position_fetch] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_shader_tile_image] = EBhDisable;
|
||||
extensionBehavior[E_GL_EXT_texture_shadow_lod] = EBhDisable;
|
||||
|
||||
// OVR extensions
|
||||
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
|
||||
|
|
|
@ -266,7 +266,12 @@ const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragmen
|
|||
const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives";
|
||||
const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint";
|
||||
const char* const E_GL_NV_mesh_shader = "GL_NV_mesh_shader";
|
||||
const char* const E_GL_NV_cooperative_matrix = "GL_NV_cooperative_matrix";
|
||||
const char* const E_GL_NV_shader_sm_builtins = "GL_NV_shader_sm_builtins";
|
||||
const char* const E_GL_NV_integer_cooperative_matrix = "GL_NV_integer_cooperative_matrix";
|
||||
const char* const E_GL_NV_shader_invocation_reorder = "GL_NV_shader_invocation_reorder";
|
||||
const char* const E_GL_EXT_ray_tracing_position_fetch = "GL_EXT_ray_tracing_position_fetch";
|
||||
const char* const E_GL_NV_displacement_micromap = "GL_NV_displacement_micromap";
|
||||
|
||||
// ARM
|
||||
const char* const E_GL_ARM_shader_core_builtins = "GL_ARM_shader_core_builtins";
|
||||
|
@ -276,10 +281,6 @@ const char* const E_GL_ARM_shader_core_builtins = "GL_ARM_shader
|
|||
const char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_NV_viewport_array2 };
|
||||
const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]);
|
||||
|
||||
const char* const E_GL_NV_cooperative_matrix = "GL_NV_cooperative_matrix";
|
||||
const char* const E_GL_NV_shader_sm_builtins = "GL_NV_shader_sm_builtins";
|
||||
const char* const E_GL_NV_integer_cooperative_matrix = "GL_NV_integer_cooperative_matrix";
|
||||
const char* const E_GL_NV_shader_invocation_reorder = "GL_NV_shader_invocation_reorder";
|
||||
|
||||
const char* const E_GL_QCOM_image_processing = "GL_QCOM_image_processing";
|
||||
|
||||
|
@ -333,6 +334,8 @@ const char* const E_GL_EXT_shader_atomic_float2 = "GL_EXT_shader_atomic_float2";
|
|||
|
||||
const char* const E_GL_EXT_shader_tile_image = "GL_EXT_shader_tile_image";
|
||||
|
||||
const char* const E_GL_EXT_texture_shadow_lod = "GL_EXT_texture_shadow_lod";
|
||||
|
||||
// Arrays of extensions for the above AEP duplications
|
||||
|
||||
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };
|
||||
|
|
|
@ -123,6 +123,8 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const
|
|||
return EatPartialCount;
|
||||
else if (name == "subgroup_uniform_control_flow")
|
||||
return EatSubgroupUniformControlFlow;
|
||||
else if (name == "export")
|
||||
return EatExport;
|
||||
else
|
||||
return EatNone;
|
||||
}
|
||||
|
@ -355,6 +357,7 @@ void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttri
|
|||
|
||||
switch (it->name) {
|
||||
case EatSubgroupUniformControlFlow:
|
||||
requireExtensions(loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
intermediate.setSubgroupUniformControlFlow();
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -120,6 +120,7 @@ namespace glslang {
|
|||
EatNonWritable,
|
||||
EatNonReadable,
|
||||
EatSubgroupUniformControlFlow,
|
||||
EatExport,
|
||||
};
|
||||
|
||||
class TIntermAggregate;
|
||||
|
|
|
@ -941,24 +941,25 @@ identifier_list
|
|||
function_prototype
|
||||
: function_declarator RIGHT_PAREN {
|
||||
$$.function = $1;
|
||||
if (parseContext.compileOnly) $$.function->setExport();
|
||||
$$.loc = $2.loc;
|
||||
}
|
||||
| function_declarator RIGHT_PAREN attribute {
|
||||
$$.function = $1;
|
||||
if (parseContext.compileOnly) $$.function->setExport();
|
||||
$$.loc = $2.loc;
|
||||
parseContext.requireExtensions($2.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($2.loc, *$3);
|
||||
}
|
||||
| attribute function_declarator RIGHT_PAREN {
|
||||
$$.function = $2;
|
||||
if (parseContext.compileOnly) $$.function->setExport();
|
||||
$$.loc = $3.loc;
|
||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1);
|
||||
}
|
||||
| attribute function_declarator RIGHT_PAREN attribute {
|
||||
$$.function = $2;
|
||||
if (parseContext.compileOnly) $$.function->setExport();
|
||||
$$.loc = $3.loc;
|
||||
parseContext.requireExtensions($3.loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute");
|
||||
parseContext.handleFunctionAttributes($3.loc, *$1);
|
||||
parseContext.handleFunctionAttributes($3.loc, *$4);
|
||||
}
|
||||
|
@ -4088,6 +4089,7 @@ function_definition
|
|||
parseContext.error($1.loc, "function does not return a value:", "", $1.function->getName().c_str());
|
||||
parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]);
|
||||
$$ = parseContext.intermediate.growAggregate($1.intermNode, $3);
|
||||
$$->getAsAggregate()->setLinkType($1.function->getLinkType());
|
||||
parseContext.intermediate.setAggregateOperator($$, EOpFunction, $1.function->getType(), $1.loc);
|
||||
$$->getAsAggregate()->setName($1.function->getMangledName().c_str());
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -524,7 +524,7 @@ extern int yydebug;
|
|||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 97 "MachineIndependent/glslang.y"
|
||||
#line 72 "MachineIndependent/glslang.y"
|
||||
|
||||
struct {
|
||||
glslang::TSourceLoc loc;
|
||||
|
|
|
@ -1141,6 +1141,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||
case EOpHitObjectGetShaderBindingTableRecordIndexNV: out.debug << "HitObjectGetShaderBindingTableRecordIndexNV"; break;
|
||||
case EOpHitObjectGetShaderRecordBufferHandleNV: out.debug << "HitObjectReadShaderRecordBufferHandleNV"; break;
|
||||
case EOpReorderThreadNV: out.debug << "ReorderThreadNV"; break;
|
||||
case EOpFetchMicroTriangleVertexPositionNV: out.debug << "MicroTriangleVertexPositionNV"; break;
|
||||
case EOpFetchMicroTriangleVertexBarycentricNV: out.debug << "MicroTriangleVertexBarycentricNV"; break;
|
||||
|
||||
case EOpSpirvInst: out.debug << "spirv_instruction"; break;
|
||||
case EOpStencilAttachmentReadEXT: out.debug << "stencilAttachmentReadEXT"; break;
|
||||
|
|
|
@ -318,8 +318,8 @@ typedef void* ShHandle;
|
|||
// Driver calls these to create and destroy compiler/linker
|
||||
// objects.
|
||||
//
|
||||
GLSLANG_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader
|
||||
GLSLANG_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair
|
||||
GLSLANG_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int /*debugOptions unused*/); // one per shader
|
||||
GLSLANG_EXPORT ShHandle ShConstructLinker(const EShExecutable, int /*debugOptions unused*/); // one per shader pair
|
||||
GLSLANG_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object)
|
||||
GLSLANG_EXPORT void ShDestruct(ShHandle);
|
||||
|
||||
|
@ -330,18 +330,13 @@ GLSLANG_EXPORT void ShDestruct(ShHandle);
|
|||
// The info-log should be written by ShCompile into
|
||||
// ShHandle, so it can answer future queries.
|
||||
//
|
||||
GLSLANG_EXPORT int ShCompile(
|
||||
const ShHandle,
|
||||
const char* const shaderStrings[],
|
||||
const int numStrings,
|
||||
const int* lengths,
|
||||
const EShOptimizationLevel,
|
||||
const TBuiltInResource *resources,
|
||||
int debugOptions,
|
||||
int defaultVersion = 110, // use 100 for ES environment, overridden by #version in shader
|
||||
bool forwardCompatible = false, // give errors for use of deprecated features
|
||||
EShMessages messages = EShMsgDefault // warnings and errors
|
||||
);
|
||||
GLSLANG_EXPORT int ShCompile(const ShHandle, const char* const shaderStrings[], const int numStrings,
|
||||
const int* lengths, const EShOptimizationLevel, const TBuiltInResource* resources,
|
||||
int, // debugOptions unused
|
||||
int defaultVersion = 110, // use 100 for ES environment, overridden by #version in shader
|
||||
bool forwardCompatible = false, // give errors for use of deprecated features
|
||||
EShMessages messages = EShMsgDefault // warnings and errors
|
||||
);
|
||||
|
||||
GLSLANG_EXPORT int ShLinkExt(
|
||||
const ShHandle, // linker object
|
||||
|
@ -573,6 +568,9 @@ public:
|
|||
void setEnvInputVulkanRulesRelaxed() { environment.input.vulkanRulesRelaxed = true; }
|
||||
bool getEnvInputVulkanRulesRelaxed() const { return environment.input.vulkanRulesRelaxed; }
|
||||
|
||||
void setCompileOnly() { compileOnly = true; }
|
||||
bool getCompileOnly() const { return compileOnly; }
|
||||
|
||||
// Interface to #include handlers.
|
||||
//
|
||||
// To support #include, a client of Glslang does the following:
|
||||
|
@ -722,6 +720,9 @@ protected:
|
|||
|
||||
TEnvironment environment;
|
||||
|
||||
// Indicates this shader is meant to be used without linking
|
||||
bool compileOnly = false;
|
||||
|
||||
friend class TProgram;
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue