Updated glslang.

This commit is contained in:
Бранимир Караџић
2021-12-23 19:14:57 -08:00
parent aa79ba8a39
commit 3c07931ae5
13 changed files with 2544 additions and 2336 deletions

View File

@@ -1664,9 +1664,22 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
case EShLangCompute:
builder.addCapability(spv::CapabilityShader);
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
glslangIntermediate->getLocalSize(1),
glslangIntermediate->getLocalSize(2));
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
std::vector<spv::Id> dimConstId;
for (int dim = 0; dim < 3; ++dim) {
bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet);
dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst));
if (specConst) {
builder.addDecoration(dimConstId.back(), spv::DecorationSpecId,
glslangIntermediate->getLocalSizeSpecId(dim));
}
}
builder.addExecutionModeId(shaderEntry, spv::ExecutionModeLocalSizeId, dimConstId);
} else {
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
glslangIntermediate->getLocalSize(1),
glslangIntermediate->getLocalSize(2));
}
if (glslangIntermediate->getLayoutDerivativeModeNone() == glslang::LayoutDerivativeGroupQuads) {
builder.addCapability(spv::CapabilityComputeDerivativeGroupQuadsNV);
builder.addExecutionMode(shaderEntry, spv::ExecutionModeDerivativeGroupQuadsNV);
@@ -1770,9 +1783,22 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion,
case EShLangMeshNV:
builder.addCapability(spv::CapabilityMeshShadingNV);
builder.addExtension(spv::E_SPV_NV_mesh_shader);
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
glslangIntermediate->getLocalSize(1),
glslangIntermediate->getLocalSize(2));
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
std::vector<spv::Id> dimConstId;
for (int dim = 0; dim < 3; ++dim) {
bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet);
dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst));
if (specConst) {
builder.addDecoration(dimConstId.back(), spv::DecorationSpecId,
glslangIntermediate->getLocalSizeSpecId(dim));
}
}
builder.addExecutionModeId(shaderEntry, spv::ExecutionModeLocalSizeId, dimConstId);
} else {
builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0),
glslangIntermediate->getLocalSize(1),
glslangIntermediate->getLocalSize(2));
}
if (glslangIntermediate->getStage() == EShLangMeshNV) {
builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices,
glslangIntermediate->getVertices());
@@ -3779,7 +3805,16 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T
switch (node->getFlowOp()) {
case glslang::EOpKill:
builder.makeStatementTerminator(spv::OpKill, "post-discard");
if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
if (glslangIntermediate->getSource() == glslang::EShSourceHlsl) {
builder.addCapability(spv::CapabilityDemoteToHelperInvocation);
builder.createNoResultOp(spv::OpDemoteToHelperInvocationEXT);
} else {
builder.makeStatementTerminator(spv::OpTerminateInvocation, "post-terminate-invocation");
}
} else {
builder.makeStatementTerminator(spv::OpKill, "post-discard");
}
break;
case glslang::EOpTerminateInvocation:
builder.addExtension(spv::E_SPV_KHR_terminate_invocation);
@@ -8716,8 +8751,18 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
builder.addDecoration(id, spv::DecorationOffset, symbol->getQualifier().layoutOffset);
}
if (symbol->getQualifier().hasLocation())
builder.addDecoration(id, spv::DecorationLocation, symbol->getQualifier().layoutLocation);
if (symbol->getQualifier().hasLocation()) {
if (!(glslangIntermediate->isRayTracingStage() && glslangIntermediate->IsRequestedExtension(glslang::E_GL_EXT_ray_tracing)
&& (builder.getStorageClass(id) == spv::StorageClassRayPayloadKHR ||
builder.getStorageClass(id) == spv::StorageClassIncomingRayPayloadKHR ||
builder.getStorageClass(id) == spv::StorageClassCallableDataKHR ||
builder.getStorageClass(id) == spv::StorageClassIncomingCallableDataKHR))) {
// Location values are used to link TraceRayKHR and ExecuteCallableKHR to corresponding variables
// but are not valid in SPIRV since they are supported only for Input/Output Storage classes.
builder.addDecoration(id, spv::DecorationLocation, symbol->getQualifier().layoutLocation);
}
}
builder.addDecoration(id, TranslateInvariantDecoration(symbol->getType().getQualifier()));
if (symbol->getQualifier().hasStream() && glslangIntermediate->isMultiStream()) {
builder.addCapability(spv::CapabilityGeometryStreams);
@@ -8751,7 +8796,16 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol
// add built-in variable decoration
if (builtIn != spv::BuiltInMax) {
builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
// WorkgroupSize deprecated in spirv1.6
if (glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_6 ||
builtIn != spv::BuiltInWorkgroupSize)
builder.addDecoration(id, spv::DecorationBuiltIn, (int)builtIn);
}
// Add volatile decoration to HelperInvocation for spirv1.6 and beyond
if (builtIn == spv::BuiltInHelperInvocation &&
glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) {
builder.addDecoration(id, spv::DecorationVolatile);
}
#ifndef GLSLANG_WEB

View File

@@ -68,6 +68,26 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog
}
case glslang::EShTargetVulkan_1_2:
return spv_target_env::SPV_ENV_VULKAN_1_2;
case glslang::EShTargetUniversal:
switch (spvVersion.spv) {
case EShTargetSpv_1_0:
return spv_target_env::SPV_ENV_UNIVERSAL_1_0;
case EShTargetSpv_1_1:
return spv_target_env::SPV_ENV_UNIVERSAL_1_1;
case EShTargetSpv_1_2:
return spv_target_env::SPV_ENV_UNIVERSAL_1_2;
case EShTargetSpv_1_3:
return spv_target_env::SPV_ENV_UNIVERSAL_1_3;
case EShTargetSpv_1_4:
return spv_target_env::SPV_ENV_UNIVERSAL_1_4;
case EShTargetSpv_1_5:
return spv_target_env::SPV_ENV_UNIVERSAL_1_5;
case EShTargetSpv_1_6:
return spv_target_env::SPV_ENV_UNIVERSAL_1_6;
default:
logger->missingFunctionality("Target version for SPIRV-Tools validator");
return spv_target_env::SPV_ENV_UNIVERSAL_1_6;
}
default:
break;
}

File diff suppressed because it is too large Load Diff

View File

@@ -788,9 +788,13 @@ void ProcessArguments(std::vector<std::unique_ptr<glslang::TWorkItem>>& workItem
} else if (strcmp(argv[1], "spirv1.5") == 0) {
TargetLanguage = glslang::EShTargetSpv;
TargetVersion = glslang::EShTargetSpv_1_5;
} else if (strcmp(argv[1], "spirv1.6") == 0) {
TargetLanguage = glslang::EShTargetSpv;
TargetVersion = glslang::EShTargetSpv_1_6;
} else
Error("--target-env expected one of: vulkan1.0, vulkan1.1, vulkan1.2, opengl,\n"
"spirv1.0, spirv1.1, spirv1.2, spirv1.3, spirv1.4, or spirv1.5");
Error("--target-env expected one of: vulkan1.0, vulkan1.1, vulkan1.2,\n"
"opengl, spirv1.0, spirv1.1, spirv1.2, spirv1.3,\n"
"spirv1.4, spirv1.5 or spirv1.6");
}
bumpArg();
} else if (lowerword == "undef-macro" ||
@@ -1930,8 +1934,9 @@ void usage()
" --sep synonym for --source-entrypoint\n"
" --stdin read from stdin instead of from a file;\n"
" requires providing the shader stage using -S\n"
" --target-env {vulkan1.0 | vulkan1.1 | vulkan1.2 | opengl | \n"
" spirv1.0 | spirv1.1 | spirv1.2 | spirv1.3 | spirv1.4 | spirv1.5}\n"
" --target-env {vulkan1.0 | vulkan1.1 | vulkan1.2 | opengl |\n"
" spirv1.0 | spirv1.1 | spirv1.2 | spirv1.3 | spirv1.4 |\n"
" spirv1.5 | spirv1.6}\n"
" Set the execution environment that the\n"
" generated code will be executed in.\n"
" Defaults to:\n"

View File

@@ -244,6 +244,8 @@ c_shader_target_language_version(glslang_target_language_version_t target_langua
return glslang::EShTargetSpv_1_4;
case GLSLANG_TARGET_SPV_1_5:
return glslang::EShTargetSpv_1_5;
case GLSLANG_TARGET_SPV_1_6:
return glslang::EShTargetSpv_1_6;
default:
break;
}
@@ -346,6 +348,34 @@ GLSLANG_EXPORT glslang_shader_t* glslang_shader_create(const glslang_input_t* in
return shader;
}
GLSLANG_EXPORT void glslang_shader_shift_binding(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base)
{
const glslang::TResourceType res_type = glslang::TResourceType(res);
shader->shader->setShiftBinding(res_type, base);
}
GLSLANG_EXPORT void glslang_shader_shift_binding_for_set(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base, unsigned int set)
{
const glslang::TResourceType res_type = glslang::TResourceType(res);
shader->shader->setShiftBindingForSet(res_type, base, set);
}
GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int options)
{
if (options & GLSLANG_SHADER_AUTO_MAP_BINDINGS) {
shader->shader->setAutoMapBindings(true);
}
if (options & GLSLANG_SHADER_AUTO_MAP_LOCATIONS) {
shader->shader->setAutoMapLocations(true);
}
if (options & GLSLANG_SHADER_VULKAN_RULES_RELAXED) {
shader->shader->setEnvInputVulkanRulesRelaxed();
}
}
GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader)
{
return shader->preprocessedGLSL.c_str();
@@ -419,6 +449,11 @@ GLSLANG_EXPORT int glslang_program_link(glslang_program_t* program, int messages
return (int)program->program->link((EShMessages)messages);
}
GLSLANG_EXPORT int glslang_program_map_io(glslang_program_t* program)
{
return (int)program->program->mapIO();
}
GLSLANG_EXPORT const char* glslang_program_get_info_log(glslang_program_t* program)
{
return program->program->getInfoLog();

View File

@@ -2465,6 +2465,62 @@ void HlslParseContext::handleFunctionArgument(TFunction* function,
arguments = newArg;
}
// FragCoord may require special loading: we can optionally reciprocate W.
TIntermTyped* HlslParseContext::assignFromFragCoord(const TSourceLoc& loc, TOperator op,
TIntermTyped* left, TIntermTyped* right)
{
// If we are not asked for reciprocal W, use a plain old assign.
if (!intermediate.getDxPositionW())
return intermediate.addAssign(op, left, right, loc);
// If we get here, we should reciprocate W.
TIntermAggregate* assignList = nullptr;
// If this is a complex rvalue, we don't want to dereference it many times. Create a temporary.
TVariable* rhsTempVar = nullptr;
rhsTempVar = makeInternalVariable("@fragcoord", right->getType());
rhsTempVar->getWritableType().getQualifier().makeTemporary();
{
TIntermTyped* rhsTempSym = intermediate.addSymbol(*rhsTempVar, loc);
assignList = intermediate.growAggregate(assignList,
intermediate.addAssign(EOpAssign, rhsTempSym, right, loc), loc);
}
// tmp.w = 1.0 / tmp.w
{
const int W = 3;
TIntermTyped* tempSymL = intermediate.addSymbol(*rhsTempVar, loc);
TIntermTyped* tempSymR = intermediate.addSymbol(*rhsTempVar, loc);
TIntermTyped* index = intermediate.addConstantUnion(W, loc);
TIntermTyped* lhsElement = intermediate.addIndex(EOpIndexDirect, tempSymL, index, loc);
TIntermTyped* rhsElement = intermediate.addIndex(EOpIndexDirect, tempSymR, index, loc);
const TType derefType(right->getType(), 0);
lhsElement->setType(derefType);
rhsElement->setType(derefType);
auto one = intermediate.addConstantUnion(1.0, EbtFloat, loc);
auto recip_w = intermediate.addBinaryMath(EOpDiv, one, rhsElement, loc);
assignList = intermediate.growAggregate(assignList, intermediate.addAssign(EOpAssign, lhsElement, recip_w, loc));
}
// Assign the rhs temp (now with W reciprocal) to the final output
{
TIntermTyped* rhsTempSym = intermediate.addSymbol(*rhsTempVar, loc);
assignList = intermediate.growAggregate(assignList, intermediate.addAssign(op, left, rhsTempSym, loc));
}
assert(assignList != nullptr);
assignList->setOperator(EOpSequence);
return assignList;
}
// Position may require special handling: we can optionally invert Y.
// See: https://github.com/KhronosGroup/glslang/issues/1173
// https://github.com/KhronosGroup/glslang/issues/494
@@ -3084,6 +3140,10 @@ TIntermTyped* HlslParseContext::handleAssign(const TSourceLoc& loc, TOperator op
subSplitLeft, subSplitRight);
assignList = intermediate.growAggregate(assignList, clipCullAssign, loc);
} else if (subSplitRight->getType().getQualifier().builtIn == EbvFragCoord) {
// FragCoord can require special handling: see comment above assignFromFragCoord
TIntermTyped* fragCoordAssign = assignFromFragCoord(loc, op, subSplitLeft, subSplitRight);
assignList = intermediate.growAggregate(assignList, fragCoordAssign, loc);
} else if (assignsClipPos(subSplitLeft)) {
// Position can require special handling: see comment above assignPosition
TIntermTyped* positionAssign = assignPosition(loc, op, subSplitLeft, subSplitRight);

View File

@@ -94,6 +94,7 @@ public:
TIntermTyped* handleFunctionCall(const TSourceLoc&, TFunction*, TIntermTyped*);
TIntermAggregate* assignClipCullDistance(const TSourceLoc&, TOperator, int semanticId, TIntermTyped* left, TIntermTyped* right);
TIntermTyped* assignPosition(const TSourceLoc&, TOperator, TIntermTyped* left, TIntermTyped* right);
TIntermTyped* assignFromFragCoord(const TSourceLoc&, TOperator, TIntermTyped* left, TIntermTyped* right);
void decomposeIntrinsic(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
void decomposeSampleMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);
void decomposeStructBufferMethods(const TSourceLoc&, TIntermTyped*& node, TIntermNode* arguments);

View File

@@ -1865,10 +1865,12 @@ public:
bool isAtomic() const { return false; }
bool isCoopMat() const { return false; }
bool isReference() const { return false; }
bool isSpirvType() const { return false; }
#else
bool isAtomic() const { return basicType == EbtAtomicUint; }
bool isCoopMat() const { return coopmat; }
bool isReference() const { return getBasicType() == EbtReference; }
bool isSpirvType() const { return getBasicType() == EbtSpirvType; }
#endif
// return true if this type contains any subtype which satisfies the given predicate.

View File

@@ -224,6 +224,9 @@ GLSLANG_EXPORT void glslang_finalize_process();
GLSLANG_EXPORT glslang_shader_t* glslang_shader_create(const glslang_input_t* input);
GLSLANG_EXPORT void glslang_shader_delete(glslang_shader_t* shader);
GLSLANG_EXPORT void glslang_shader_shift_binding(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base);
GLSLANG_EXPORT void glslang_shader_shift_binding_for_set(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base, unsigned int set);
GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int options); // glslang_shader_options_t
GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input);
GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_input_t* input);
GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader);
@@ -234,6 +237,7 @@ GLSLANG_EXPORT glslang_program_t* glslang_program_create();
GLSLANG_EXPORT void glslang_program_delete(glslang_program_t* program);
GLSLANG_EXPORT void glslang_program_add_shader(glslang_program_t* program, glslang_shader_t* shader);
GLSLANG_EXPORT int glslang_program_link(glslang_program_t* program, int messages); // glslang_messages_t
GLSLANG_EXPORT int glslang_program_map_io(glslang_program_t* program);
GLSLANG_EXPORT void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage);
GLSLANG_EXPORT size_t glslang_program_SPIRV_get_size(glslang_program_t* program);
GLSLANG_EXPORT void glslang_program_SPIRV_get(glslang_program_t* program, unsigned int*);

View File

@@ -113,7 +113,8 @@ typedef enum {
GLSLANG_TARGET_SPV_1_3 = (1 << 16) | (3 << 8),
GLSLANG_TARGET_SPV_1_4 = (1 << 16) | (4 << 8),
GLSLANG_TARGET_SPV_1_5 = (1 << 16) | (5 << 8),
LAST_ELEMENT_MARKER(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT = 6),
GLSLANG_TARGET_SPV_1_6 = (1 << 16) | (6 << 8),
LAST_ELEMENT_MARKER(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT = 7),
} glslang_target_language_version_t;
/* EShExecutable counterpart */
@@ -181,6 +182,26 @@ typedef enum {
LAST_ELEMENT_MARKER(GLSLANG_PROFILE_COUNT),
} glslang_profile_t;
/* Shader options */
typedef enum {
GLSLANG_SHADER_DEFAULT_BIT = 0,
GLSLANG_SHADER_AUTO_MAP_BINDINGS = (1 << 0),
GLSLANG_SHADER_AUTO_MAP_LOCATIONS = (1 << 1),
GLSLANG_SHADER_VULKAN_RULES_RELAXED = (1 << 2),
LAST_ELEMENT_MARKER(GLSLANG_SHADER_COUNT),
} glslang_shader_options_t;
/* TResourceType counterpart */
typedef enum {
GLSLANG_RESOURCE_TYPE_SAMPLER,
GLSLANG_RESOURCE_TYPE_TEXTURE,
GLSLANG_RESOURCE_TYPE_IMAGE,
GLSLANG_RESOURCE_TYPE_UBO,
GLSLANG_RESOURCE_TYPE_SSBO,
GLSLANG_RESOURCE_TYPE_UAV,
LAST_ELEMENT_MARKER(GLSLANG_RESOURCE_TYPE_COUNT),
} glslang_resource_type_t;
#undef LAST_ELEMENT_MARKER
#endif

View File

@@ -845,7 +845,7 @@ int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
}
// no locations added if already present, a built-in variable, a block, or an opaque
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
type.isAtomic() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
type.isAtomic() || type.isSpirvType() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
return ent.newLocation = -1;
}
// no locations on blocks of built-in variables
@@ -873,8 +873,8 @@ int TDefaultIoResolverBase::resolveInOutLocation(EShLanguage stage, TVarEntryInf
return ent.newLocation = -1;
}
// no locations added if already present, or a built-in variable
if (type.getQualifier().hasLocation() || type.isBuiltIn()) {
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
return ent.newLocation = -1;
}
@@ -960,8 +960,8 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf
if (type.getQualifier().hasLocation()) {
return ent.newLocation = type.getQualifier().layoutLocation;
}
// no locations added if already present, or a built-in variable
if (type.isBuiltIn()) {
// no locations added if already present, a built-in variable, or a variable with SPIR-V decorate
if (type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) {
return ent.newLocation = -1;
}
// no locations on blocks of built-in variables
@@ -1042,7 +1042,8 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn
} else {
// no locations added if already present, a built-in variable, a block, or an opaque
if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock ||
type.isAtomic() || (type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
type.isAtomic() || type.isSpirvType() ||
(type.containsOpaque() && referenceIntermediate.getSpv().openGl == 0)) {
return ent.newLocation = -1;
}
// no locations on blocks of built-in variables

View File

@@ -398,6 +398,9 @@ public:
case EShTargetSpv_1_5:
processes.addProcess("target-env spirv1.5");
break;
case EShTargetSpv_1_6:
processes.addProcess("target-env spirv1.6");
break;
default:
processes.addProcess("target-env spirvUnknown");
break;

View File

@@ -163,6 +163,7 @@ typedef enum {
} EShTargetLanguage;
typedef enum {
EShTargetUniversal = 0, // Universal
EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0
EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1
EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2
@@ -179,7 +180,8 @@ typedef enum {
EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3
EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4
EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5
LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount = 6),
EShTargetSpv_1_6 = (1 << 16) | (6 << 8), // SPIR-V 1.6
LAST_ELEMENT_MARKER(EShTargetLanguageVersionCount = 7),
} EShTargetLanguageVersion;
struct TInputLanguage {