Add support for GLSL_EXT_ray_tracing

and SPV_KHR_ray_tracing
This commit is contained in:
Daniel Koch 2020-03-17 20:42:47 -04:00
parent f368dcbb7d
commit db32b243ff
69 changed files with 6912 additions and 4972 deletions

View file

@ -2032,11 +2032,11 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan
}
#ifndef GLSLANG_WEB
case EOpTraceNV:
case EOpTrace:
if (!(*argp)[10]->getAsConstantUnion())
error(loc, "argument must be compile-time constant", "payload number", "");
break;
case EOpExecuteCallableNV:
case EOpExecuteCallable:
if (!(*argp)[1]->getAsConstantUnion())
error(loc, "argument must be compile-time constant", "callable data number", "");
break;
@ -3228,14 +3228,14 @@ void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, co
error(loc, "atomic_uints can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str());
}
void TParseContext::accStructNVCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
void TParseContext::accStructCheck(const TSourceLoc& loc, const TType& type, const TString& identifier)
{
if (type.getQualifier().storage == EvqUniform)
return;
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAccStructNV))
if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtAccStruct))
error(loc, "non-uniform struct contains an accelerationStructureNV:", type.getBasicTypeString().c_str(), identifier.c_str());
else if (type.getBasicType() == EbtAccStructNV && type.getQualifier().storage != EvqUniform)
else if (type.getBasicType() == EbtAccStruct && type.getQualifier().storage != EvqUniform)
error(loc, "accelerationStructureNV can only be used in uniform variables or function parameters:",
type.getBasicTypeString().c_str(), identifier.c_str());
@ -3519,12 +3519,14 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
dst.precision = src.precision;
#ifndef GLSLANG_WEB
if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) ||
(src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)) ||
(src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent)) ||
(src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent)) ||
(src.subgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent)))) {
error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent qualifier allowed", GetPrecisionQualifierString(src.precision), "");
if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
(src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
(src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
(src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent || dst.shadercallcoherent)) ||
(src.subgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.shadercallcoherent)) ||
(src.shadercallcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)))) {
error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent/shadercallcoherent qualifier allowed",
GetPrecisionQualifierString(src.precision), "");
}
#endif
// Layout qualifiers
@ -3552,6 +3554,7 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons
MERGE_SINGLETON(queuefamilycoherent);
MERGE_SINGLETON(workgroupcoherent);
MERGE_SINGLETON(subgroupcoherent);
MERGE_SINGLETON(shadercallcoherent);
MERGE_SINGLETON(nonprivate);
MERGE_SINGLETON(volatil);
MERGE_SINGLETON(restrict);
@ -3989,7 +3992,7 @@ void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermType
}
// check for additional things allowed by GL_EXT_nonuniform_qualifier
if (base.getBasicType() == EbtSampler || base.getBasicType() == EbtAccStructNV ||
if (base.getBasicType() == EbtSampler || base.getBasicType() == EbtAccStruct ||
(base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer()))
requireExtensions(loc, 1, &E_GL_EXT_nonuniform_qualifier, "variable index");
else
@ -4493,6 +4496,7 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali
type.getQualifier().queuefamilycoherent = qualifier.queuefamilycoherent;
type.getQualifier().workgroupcoherent = qualifier.workgroupcoherent;
type.getQualifier().subgroupcoherent = qualifier.subgroupcoherent;
type.getQualifier().shadercallcoherent = qualifier.shadercallcoherent;
type.getQualifier().nonprivate = qualifier.nonprivate;
type.getQualifier().readonly = qualifier.readonly;
type.getQualifier().writeonly = qualifier.writeonly;
@ -5073,13 +5077,19 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi
return;
}
} else {
if (language == EShLangRayGenNV || language == EShLangIntersectNV ||
language == EShLangAnyHitNV || language == EShLangClosestHitNV ||
language == EShLangMissNV || language == EShLangCallableNV) {
if (id == "shaderrecordnv") {
publicType.qualifier.layoutShaderRecordNV = true;
if (language == EShLangRayGen || language == EShLangIntersect ||
language == EShLangAnyHit || language == EShLangClosestHit ||
language == EShLangMiss || language == EShLangCallable) {
if (id == "shaderrecordnv" || id == "shaderrecordext") {
if (id == "shaderrecordnv") {
requireExtensions(loc, 1, &E_GL_NV_ray_tracing, "shader record NV");
} else {
requireExtensions(loc, 1, &E_GL_EXT_ray_tracing, "shader record EXT");
}
publicType.qualifier.layoutShaderRecord = true;
return;
}
}
}
if (language == EShLangCompute) {
@ -5521,8 +5531,8 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie
dst.layoutViewportRelative = true;
if (src.layoutSecondaryViewportRelativeOffset != -2048)
dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset;
if (src.layoutShaderRecordNV)
dst.layoutShaderRecordNV = true;
if (src.layoutShaderRecord)
dst.layoutShaderRecord = true;
if (src.pervertexNV)
dst.pervertexNV = true;
#endif
@ -5590,7 +5600,7 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb
error(loc, "cannot specify on a variable declaration", "align", "");
if (qualifier.isPushConstant())
error(loc, "can only specify on a uniform block", "push_constant", "");
if (qualifier.isShaderRecordNV())
if (qualifier.isShaderRecord())
error(loc, "can only specify on a buffer block", "shaderRecordNV", "");
}
break;
@ -5664,11 +5674,11 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
error(loc, "cannot apply to uniform or buffer block", "location", "");
break;
#ifndef GLSLANG_WEB
case EvqPayloadNV:
case EvqPayloadInNV:
case EvqHitAttrNV:
case EvqCallableDataNV:
case EvqCallableDataInNV:
case EvqPayload:
case EvqPayloadIn:
case EvqHitAttr:
case EvqCallableData:
case EvqCallableDataIn:
break;
#endif
default:
@ -5763,7 +5773,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
if (spvVersion.spv > 0) {
if (qualifier.isUniformOrBuffer()) {
if (type.getBasicType() == EbtBlock && !qualifier.isPushConstant() &&
!qualifier.isShaderRecordNV() &&
!qualifier.isShaderRecord() &&
!qualifier.hasAttachment() &&
!qualifier.hasBufferReference())
error(loc, "uniform/buffer blocks require layout(binding=X)", "binding", "");
@ -5820,7 +5830,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type)
if (qualifier.hasBufferReference() && type.getBasicType() != EbtBlock)
error(loc, "can only be used with a block", "buffer_reference", "");
if (qualifier.isShaderRecordNV() && type.getBasicType() != EbtBlock)
if (qualifier.isShaderRecord() && type.getBasicType() != EbtBlock)
error(loc, "can only be used with a block", "shaderRecordNV", "");
// input attachment
@ -5965,7 +5975,7 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier
if (qualifier.storage != EvqBuffer)
error(loc, "can only be used with buffer", "buffer_reference", "");
}
if (qualifier.isShaderRecordNV()) {
if (qualifier.isShaderRecord()) {
if (qualifier.storage != EvqBuffer)
error(loc, "can only be used with a buffer", "shaderRecordNV", "");
if (qualifier.hasBinding())
@ -5974,7 +5984,7 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier
error(loc, "cannot be used with shaderRecordNV", "set", "");
}
if (qualifier.storage == EvqHitAttrNV && qualifier.hasLayout()) {
if (qualifier.storage == EvqHitAttr && qualifier.hasLayout()) {
error(loc, "cannot apply layout qualifiers to hitAttributeNV variable", "hitAttributeNV", "");
}
}
@ -6477,7 +6487,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
transparentOpaqueCheck(loc, type, identifier);
#ifndef GLSLANG_WEB
atomicUintCheck(loc, type, identifier);
accStructNVCheck(loc, type, identifier);
accStructCheck(loc, type, identifier);
checkAndResizeMeshViewDim(loc, type, /*isBlockMember*/ false);
#endif
if (type.getQualifier().storage == EvqConst && type.containsReference()) {
@ -7411,7 +7421,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
// Special case for "push_constant uniform", which has a default of std430,
// contrary to normal uniform defaults, and can't have a default tracked for it.
if ((currentBlockQualifier.isPushConstant() && !currentBlockQualifier.hasPacking()) ||
(currentBlockQualifier.isShaderRecordNV() && !currentBlockQualifier.hasPacking()))
(currentBlockQualifier.isShaderRecord() && !currentBlockQualifier.hasPacking()))
currentBlockQualifier.layoutPacking = ElpStd430;
// Special case for "taskNV in/out", which has a default of std430,
@ -7628,6 +7638,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con
// with a particular stage.
void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& qualifier)
{
const char *extsrt[2] = { E_GL_NV_ray_tracing, E_GL_EXT_ray_tracing };
switch (qualifier.storage) {
case EvqUniform:
profileRequires(loc, EEsProfile, 300, nullptr, "uniform block");
@ -7666,28 +7677,28 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
}
break;
#ifndef GLSLANG_WEB
case EvqPayloadNV:
profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV block");
requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask),
case EvqPayload:
profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadNV block");
requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask),
"rayPayloadNV block");
break;
case EvqPayloadInNV:
profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadInNV block");
requireStage(loc, (EShLanguageMask)(EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask),
case EvqPayloadIn:
profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadInNV block");
requireStage(loc, (EShLanguageMask)(EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask),
"rayPayloadInNV block");
break;
case EvqHitAttrNV:
profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV block");
requireStage(loc, (EShLanguageMask)(EShLangIntersectNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask), "hitAttributeNV block");
case EvqHitAttr:
profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "hitAttributeNV block");
requireStage(loc, (EShLanguageMask)(EShLangIntersectMask | EShLangAnyHitMask | EShLangClosestHitMask), "hitAttributeNV block");
break;
case EvqCallableDataNV:
profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "callableDataNV block");
requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangClosestHitNVMask | EShLangMissNVMask | EShLangCallableNVMask),
case EvqCallableData:
profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "callableDataNV block");
requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | EShLangMissMask | EShLangCallableMask),
"callableDataNV block");
break;
case EvqCallableDataInNV:
profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "callableDataInNV block");
requireStage(loc, (EShLanguageMask)(EShLangCallableNVMask), "callableDataInNV block");
case EvqCallableDataIn:
profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "callableDataInNV block");
requireStage(loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV block");
break;
#endif
default:
@ -7726,8 +7737,8 @@ void TParseContext::blockQualifierCheck(const TSourceLoc& loc, const TQualifier&
error(loc, "cannot use invariant qualifier on an interface block", "invariant", "");
if (qualifier.isPushConstant())
intermediate.addPushConstantCount();
if (qualifier.isShaderRecordNV())
intermediate.addShaderRecordNVCount();
if (qualifier.isShaderRecord())
intermediate.addShaderRecordCount();
if (qualifier.isTaskMemory())
intermediate.addTaskNVCount();
}
@ -8249,7 +8260,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con
error(loc, "cannot declare a default, can only be used on a block", "buffer_reference", "");
if (qualifier.hasSpecConstantId())
error(loc, "cannot declare a default, can only be used on a scalar", "constant_id", "");
if (qualifier.isShaderRecordNV())
if (qualifier.isShaderRecord())
error(loc, "cannot declare a default, can only be used on a block", "shaderRecordNV", "");
}