Web: Remove unused stage functionality, SPIR-V logger, and hex_utils

Saves another 20K.
This commit is contained in:
John Kessenich 2019-08-08 23:29:20 -06:00
parent 39697cdb9d
commit 155d351f86
20 changed files with 450 additions and 390 deletions

View File

@ -248,6 +248,10 @@ protected:
// Translate glslang profile to SPIR-V source language. // Translate glslang profile to SPIR-V source language.
spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile profile) spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile profile)
{ {
#ifdef GLSLANG_WEB
return spv::SourceLanguageESSL;
#endif
switch (source) { switch (source) {
case glslang::EShSourceGlsl: case glslang::EShSourceGlsl:
switch (profile) { switch (profile) {
@ -601,6 +605,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
{ {
switch (builtIn) { switch (builtIn) {
case glslang::EbvPointSize: case glslang::EbvPointSize:
#ifndef GLSLANG_WEB
// Defer adding the capability until the built-in is actually used. // Defer adding the capability until the built-in is actually used.
if (! memberDeclaration) { if (! memberDeclaration) {
switch (glslangIntermediate->getStage()) { switch (glslangIntermediate->getStage()) {
@ -615,6 +620,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI
break; break;
} }
} }
#endif
return spv::BuiltInPointSize; return spv::BuiltInPointSize;
case glslang::EbvPosition: return spv::BuiltInPosition; case glslang::EbvPosition: return spv::BuiltInPosition;
@ -1664,6 +1670,7 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
builder.setAccessChainLValue(id); builder.setAccessChainLValue(id);
} }
#ifndef GLSLANG_WEB
// Process linkage-only nodes for any special additional interface work. // Process linkage-only nodes for any special additional interface work.
if (linkageOnly) { if (linkageOnly) {
if (glslangIntermediate->getHlslFunctionality1()) { if (glslangIntermediate->getHlslFunctionality1()) {
@ -1695,6 +1702,7 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol)
} }
} }
} }
#endif
} }
bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node) bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node)
@ -2151,12 +2159,14 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI
return false; return false;
#ifndef GLSLANG_WEB
case glslang::EOpEmitStreamVertex: case glslang::EOpEmitStreamVertex:
builder.createNoResultOp(spv::OpEmitStreamVertex, operand); builder.createNoResultOp(spv::OpEmitStreamVertex, operand);
return false; return false;
case glslang::EOpEndStreamPrimitive: case glslang::EOpEndStreamPrimitive:
builder.createNoResultOp(spv::OpEndStreamPrimitive, operand); builder.createNoResultOp(spv::OpEndStreamPrimitive, operand);
return false; return false;
#endif
default: default:
logger->missingFunctionality("unknown glslang unary"); logger->missingFunctionality("unknown glslang unary");
@ -4123,8 +4133,12 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF
std::vector<std::vector<spv::Decoration>> paramDecorations; // list of decorations per parameter std::vector<std::vector<spv::Decoration>> paramDecorations; // list of decorations per parameter
glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence(); glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence();
#ifdef ENABLE_HLSL
bool implicitThis = (int)parameters.size() > 0 && parameters[0]->getAsSymbolNode()->getName() == bool implicitThis = (int)parameters.size() > 0 && parameters[0]->getAsSymbolNode()->getName() ==
glslangIntermediate->implicitThisName; glslangIntermediate->implicitThisName;
#else
bool implicitThis = false;
#endif
paramDecorations.resize(parameters.size()); paramDecorations.resize(parameters.size());
for (int p = 0; p < (int)parameters.size(); ++p) { for (int p = 0; p < (int)parameters.size(); ++p) {
@ -7396,11 +7410,11 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv::
// Intrinsics with no arguments (or no return value, and no precision). // Intrinsics with no arguments (or no return value, and no precision).
spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId) spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId)
{ {
#ifndef GLSLANG_WEB
// GLSL memory barriers use queuefamily scope in new model, device scope in old model // GLSL memory barriers use queuefamily scope in new model, device scope in old model
spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice; spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice;
switch (op) { switch (op) {
#ifndef GLSLANG_WEB
case glslang::EOpEmitVertex: case glslang::EOpEmitVertex:
builder.createNoResultOp(spv::OpEmitVertex); builder.createNoResultOp(spv::OpEmitVertex);
return 0; return 0;
@ -7538,11 +7552,14 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv:
builder.addCapability(spv::CapabilityShaderClockKHR); builder.addCapability(spv::CapabilityShaderClockKHR);
return builder.createOp(spv::OpReadClockKHR, typeId, args); return builder.createOp(spv::OpReadClockKHR, typeId, args);
} }
#endif
default: default:
logger->missingFunctionality("unknown operation with no arguments"); break;
return 0;
} }
#endif
logger->missingFunctionality("unknown operation with no arguments");
return 0;
} }
spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol) spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol)
@ -7745,6 +7762,7 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n
// We now know we have a specialization constant to build // We now know we have a specialization constant to build
#ifndef GLSLANG_WEB
// gl_WorkGroupSize is a special case until the front-end handles hierarchical specialization constants, // gl_WorkGroupSize is a special case until the front-end handles hierarchical specialization constants,
// even then, it's specialization ids are handled by special case syntax in GLSL: layout(local_size_x = ... // even then, it's specialization ids are handled by special case syntax in GLSL: layout(local_size_x = ...
if (node.getType().getQualifier().builtIn == glslang::EbvWorkGroupSize) { if (node.getType().getQualifier().builtIn == glslang::EbvWorkGroupSize) {
@ -7759,6 +7777,7 @@ spv::Id TGlslangToSpvTraverser::createSpvConstant(const glslang::TIntermTyped& n
} }
return builder.makeCompositeConstant(builder.makeVectorType(builder.makeUintType(32), 3), dimConstId, true); return builder.makeCompositeConstant(builder.makeVectorType(builder.makeUintType(32), 3), dimConstId, true);
} }
#endif
// An AST node labelled as specialization constant should be a symbol node. // An AST node labelled as specialization constant should be a symbol node.
// Its initializer should either be a sub tree with constant nodes, or a constant union array. // Its initializer should either be a sub tree with constant nodes, or a constant union array.
@ -8114,6 +8133,7 @@ void OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName)
// Write SPIR-V out to a text file with 32-bit hexadecimal words // Write SPIR-V out to a text file with 32-bit hexadecimal words
void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName) void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName)
{ {
#ifndef GLSLANG_WEB
std::ofstream out; std::ofstream out;
out.open(baseName, std::ios::binary | std::ios::out); out.open(baseName, std::ios::binary | std::ios::out);
if (out.fail()) if (out.fail())
@ -8141,6 +8161,7 @@ void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName,
out << "};"; out << "};";
} }
out.close(); out.close();
#endif
} }
// //

View File

@ -32,6 +32,8 @@
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE. // POSSIBILITY OF SUCH DAMAGE.
#ifndef GLSLANG_WEB
#include "Logger.h" #include "Logger.h"
#include <algorithm> #include <algorithm>
@ -66,3 +68,5 @@ std::string SpvBuildLogger::getAllMessages() const {
} }
} // end spv namespace } // end spv namespace
#endif

View File

@ -46,6 +46,14 @@ class SpvBuildLogger {
public: public:
SpvBuildLogger() {} SpvBuildLogger() {}
#ifdef GLSLANG_WEB
void tbdFunctionality(const std::string& f) { }
void missingFunctionality(const std::string& f) { }
void warning(const std::string& w) { }
void error(const std::string& e) { errors.push_back(e); }
std::string getAllMessages() { return ""; }
#else
// Registers a TBD functionality. // Registers a TBD functionality.
void tbdFunctionality(const std::string& f); void tbdFunctionality(const std::string& f);
// Registers a missing functionality. // Registers a missing functionality.
@ -59,6 +67,7 @@ public:
// Returns all messages accumulated in the order of: // Returns all messages accumulated in the order of:
// TBD functionalities, missing functionalities, warnings, errors. // TBD functionalities, missing functionalities, warnings, errors.
std::string getAllMessages() const; std::string getAllMessages() const;
#endif
private: private:
SpvBuildLogger(const SpvBuildLogger&); SpvBuildLogger(const SpvBuildLogger&);

View File

@ -46,7 +46,9 @@
#include "SpvBuilder.h" #include "SpvBuilder.h"
#ifndef GLSLANG_WEB
#include "hex_float.h" #include "hex_float.h"
#endif
#ifndef _WIN32 #ifndef _WIN32
#include <cstdio> #include <cstdio>
@ -950,6 +952,10 @@ Id Builder::makeFloatConstant(float f, bool specConstant)
Id Builder::makeDoubleConstant(double d, bool specConstant) Id Builder::makeDoubleConstant(double d, bool specConstant)
{ {
#ifdef GLSLANG_WEB
assert(0);
return NoResult;
#else
Op opcode = specConstant ? OpSpecConstant : OpConstant; Op opcode = specConstant ? OpSpecConstant : OpConstant;
Id typeId = makeFloatType(64); Id typeId = makeFloatType(64);
union { double db; unsigned long long ull; } u; union { double db; unsigned long long ull; } u;
@ -974,10 +980,15 @@ Id Builder::makeDoubleConstant(double d, bool specConstant)
module.mapInstruction(c); module.mapInstruction(c);
return c->getResultId(); return c->getResultId();
#endif
} }
Id Builder::makeFloat16Constant(float f16, bool specConstant) Id Builder::makeFloat16Constant(float f16, bool specConstant)
{ {
#ifdef GLSLANG_WEB
assert(0);
return NoResult;
#else
Op opcode = specConstant ? OpSpecConstant : OpConstant; Op opcode = specConstant ? OpSpecConstant : OpConstant;
Id typeId = makeFloatType(16); Id typeId = makeFloatType(16);
@ -1002,6 +1013,7 @@ Id Builder::makeFloat16Constant(float f16, bool specConstant)
module.mapInstruction(c); module.mapInstruction(c);
return c->getResultId(); return c->getResultId();
#endif
} }
Id Builder::makeFpConstant(Id type, double d, bool specConstant) Id Builder::makeFpConstant(Id type, double d, bool specConstant)

View File

@ -41,8 +41,10 @@
#ifndef GLSLANG_SPV_TOOLS_H #ifndef GLSLANG_SPV_TOOLS_H
#define GLSLANG_SPV_TOOLS_H #define GLSLANG_SPV_TOOLS_H
#ifdef ENABLE_OPT
#include <vector> #include <vector>
#include <ostream> #include <ostream>
#endif
#include "../glslang/MachineIndependent/localintermediate.h" #include "../glslang/MachineIndependent/localintermediate.h"
#include "Logger.h" #include "Logger.h"
@ -59,7 +61,7 @@ struct SpvOptions {
bool validate; bool validate;
}; };
#if ENABLE_OPT #ifdef ENABLE_OPT
// Use the SPIRV-Tools disassembler to print SPIR-V. // Use the SPIRV-Tools disassembler to print SPIR-V.
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv); void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);

View File

@ -977,6 +977,7 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
shader->setPreamble(UserPreamble.get()); shader->setPreamble(UserPreamble.get());
shader->addProcesses(Processes); shader->addProcesses(Processes);
#ifndef GLSLANG_WEB
// Set IO mapper binding shift values // Set IO mapper binding shift values
for (int r = 0; r < glslang::EResCount; ++r) { for (int r = 0; r < glslang::EResCount; ++r) {
const glslang::TResourceType res = glslang::TResourceType(r); const glslang::TResourceType res = glslang::TResourceType(r);
@ -990,32 +991,33 @@ void CompileAndLinkShaderUnits(std::vector<ShaderCompUnit> compUnits)
i != baseBindingForSet[res][compUnit.stage].end(); ++i) i != baseBindingForSet[res][compUnit.stage].end(); ++i)
shader->setShiftBindingForSet(res, i->second, i->first); shader->setShiftBindingForSet(res, i->second, i->first);
} }
shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0); shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0);
shader->setNanMinMaxClamp(NaNClamp);
shader->setResourceSetBinding(baseResourceSetBinding[compUnit.stage]); shader->setResourceSetBinding(baseResourceSetBinding[compUnit.stage]);
#ifdef ENABLE_HLSL
if (Options & EOptionHlslIoMapping)
shader->setHlslIoMapping(true);
#endif
if (Options & EOptionAutoMapBindings) if (Options & EOptionAutoMapBindings)
shader->setAutoMapBindings(true); shader->setAutoMapBindings(true);
if (Options & EOptionAutoMapLocations) if (Options & EOptionAutoMapLocations)
shader->setAutoMapLocations(true); shader->setAutoMapLocations(true);
if (Options & EOptionInvertY)
shader->setInvertY(true);
for (auto& uniOverride : uniformLocationOverrides) { for (auto& uniOverride : uniformLocationOverrides) {
shader->addUniformLocationOverride(uniOverride.first.c_str(), shader->addUniformLocationOverride(uniOverride.first.c_str(),
uniOverride.second); uniOverride.second);
} }
shader->setUniformLocationBase(uniformBase); shader->setUniformLocationBase(uniformBase);
#endif
shader->setNanMinMaxClamp(NaNClamp);
#ifdef ENABLE_HLSL
shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0);
if (Options & EOptionHlslIoMapping)
shader->setHlslIoMapping(true);
#endif
if (Options & EOptionInvertY)
shader->setInvertY(true);
// Set up the environment, some subsettings take precedence over earlier // Set up the environment, some subsettings take precedence over earlier
// ways of setting things. // ways of setting things.

View File

@ -1 +1 @@
812032 ../build/install/bin/glslangValidator.exe 601088 ../build/install/bin/glslangValidator.exe

View File

@ -15,12 +15,12 @@ spv.hlslDebugInfo.vert
// OpModuleProcessed shift-UBO-binding 6 // OpModuleProcessed shift-UBO-binding 6
// OpModuleProcessed shift-ssbo-binding 3 // OpModuleProcessed shift-ssbo-binding 3
// OpModuleProcessed shift-uav-binding 5 // OpModuleProcessed shift-uav-binding 5
// OpModuleProcessed flatten-uniform-arrays
// OpModuleProcessed no-storage-format // OpModuleProcessed no-storage-format
// OpModuleProcessed resource-set-binding t0 0 0 // OpModuleProcessed resource-set-binding t0 0 0
// OpModuleProcessed hlsl-iomap
// OpModuleProcessed auto-map-bindings // OpModuleProcessed auto-map-bindings
// OpModuleProcessed auto-map-locations // OpModuleProcessed auto-map-locations
// OpModuleProcessed flatten-uniform-arrays
// OpModuleProcessed hlsl-iomap
// OpModuleProcessed client vulkan100 // OpModuleProcessed client vulkan100
// OpModuleProcessed target-env vulkan1.0 // OpModuleProcessed target-env vulkan1.0
// OpModuleProcessed source-entrypoint origMain // OpModuleProcessed source-entrypoint origMain

View File

@ -1,74 +1,62 @@
; SPIR-V ; SPIR-V
; Version: 1.0 ; Version: 1.0
; Generator: Khronos Glslang Reference Front End; 7 ; Generator: Khronos Glslang Reference Front End; 7
; Bound: 42 ; Bound: 33
; Schema: 0 ; Schema: 0
OpCapability Shader OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450" %1 = OpExtInstImport "GLSL.std.450"
OpMemoryModel Logical GLSL450 OpMemoryModel Logical GLSL450
OpEntryPoint Vertex %main "main" %_ %ps %gl_VertexIndex %gl_InstanceIndex OpEntryPoint Vertex %main "main" %gl_Position %ps %gl_VertexIndex %gl_PointSize %gl_InstanceIndex
OpSource ESSL 310 OpSource ESSL 310
OpName %main "main" OpName %main "main"
OpName %gl_PerVertex "gl_PerVertex" OpName %gl_Position "gl_Position"
OpMemberName %gl_PerVertex 0 "gl_Position"
OpMemberName %gl_PerVertex 1 "gl_PointSize"
OpName %_ ""
OpName %ps "ps" OpName %ps "ps"
OpName %gl_VertexIndex "gl_VertexIndex" OpName %gl_VertexIndex "gl_VertexIndex"
OpName %gl_PointSize "gl_PointSize"
OpName %gl_InstanceIndex "gl_InstanceIndex" OpName %gl_InstanceIndex "gl_InstanceIndex"
OpMemberDecorate %gl_PerVertex 0 Invariant OpDecorate %gl_Position Invariant
OpMemberDecorate %gl_PerVertex 0 BuiltIn Position OpDecorate %gl_Position BuiltIn Position
OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize
OpDecorate %gl_PerVertex Block
OpDecorate %ps RelaxedPrecision OpDecorate %ps RelaxedPrecision
OpDecorate %ps Location 0 OpDecorate %ps Location 0
OpDecorate %15 RelaxedPrecision OpDecorate %12 RelaxedPrecision
OpDecorate %gl_VertexIndex BuiltIn VertexIndex OpDecorate %gl_VertexIndex BuiltIn VertexIndex
OpDecorate %30 RelaxedPrecision OpDecorate %gl_PointSize BuiltIn PointSize
OpDecorate %25 RelaxedPrecision
OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex
%void = OpTypeVoid %void = OpTypeVoid
%3 = OpTypeFunction %void %3 = OpTypeFunction %void
%float = OpTypeFloat 32 %float = OpTypeFloat 32
%v4float = OpTypeVector %float 4 %v4float = OpTypeVector %float 4
%gl_PerVertex = OpTypeStruct %v4float %float %_ptr_Output_v4float = OpTypePointer Output %v4float
%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex %gl_Position = OpVariable %_ptr_Output_v4float Output
%_ = OpVariable %_ptr_Output_gl_PerVertex Output
%int = OpTypeInt 32 1
%int_0 = OpConstant %int 0
%_ptr_Input_float = OpTypePointer Input %float %_ptr_Input_float = OpTypePointer Input %float
%ps = OpVariable %_ptr_Input_float Input %ps = OpVariable %_ptr_Input_float Input
%_ptr_Output_v4float = OpTypePointer Output %v4float %int = OpTypeInt 32 1
%int_4 = OpConstant %int 4 %int_4 = OpConstant %int 4
%_ptr_Input_int = OpTypePointer Input %int %_ptr_Input_int = OpTypePointer Input %int
%gl_VertexIndex = OpVariable %_ptr_Input_int Input %gl_VertexIndex = OpVariable %_ptr_Input_int Input
%int_1 = OpConstant %int 1
%_ptr_Output_float = OpTypePointer Output %float %_ptr_Output_float = OpTypePointer Output %float
%gl_PointSize = OpVariable %_ptr_Output_float Output
%int_5 = OpConstant %int 5 %int_5 = OpConstant %int 5
%gl_InstanceIndex = OpVariable %_ptr_Input_int Input %gl_InstanceIndex = OpVariable %_ptr_Input_int Input
%main = OpFunction %void None %3 %main = OpFunction %void None %3
%5 = OpLabel %5 = OpLabel
%15 = OpLoad %float %ps %12 = OpLoad %float %ps
%16 = OpCompositeConstruct %v4float %15 %15 %15 %15 %13 = OpCompositeConstruct %v4float %12 %12 %12 %12
%18 = OpAccessChain %_ptr_Output_v4float %_ %int_0 OpStore %gl_Position %13
OpStore %18 %16 %18 = OpLoad %int %gl_VertexIndex
%22 = OpLoad %int %gl_VertexIndex %19 = OpISub %int %int_4 %18
%23 = OpISub %int %int_4 %22 %20 = OpConvertSToF %float %19
%24 = OpConvertSToF %float %23 %21 = OpLoad %v4float %gl_Position
%25 = OpAccessChain %_ptr_Output_v4float %_ %int_0 %22 = OpVectorTimesScalar %v4float %21 %20
%26 = OpLoad %v4float %25 OpStore %gl_Position %22
%27 = OpVectorTimesScalar %v4float %26 %24 %25 = OpLoad %float %ps
%28 = OpAccessChain %_ptr_Output_v4float %_ %int_0 OpStore %gl_PointSize %25
OpStore %28 %27 %28 = OpLoad %int %gl_InstanceIndex
%30 = OpLoad %float %ps %29 = OpISub %int %int_5 %28
%32 = OpAccessChain %_ptr_Output_float %_ %int_1 %30 = OpConvertSToF %float %29
OpStore %32 %30 %31 = OpLoad %float %gl_PointSize
%35 = OpLoad %int %gl_InstanceIndex %32 = OpFMul %float %31 %30
%36 = OpISub %int %int_5 %35 OpStore %gl_PointSize %32
%37 = OpConvertSToF %float %36
%38 = OpAccessChain %_ptr_Output_float %_ %int_1
%39 = OpLoad %float %38
%40 = OpFMul %float %39 %37
%41 = OpAccessChain %_ptr_Output_float %_ %int_1
OpStore %41 %40
OpReturn OpReturn
OpFunctionEnd OpFunctionEnd

View File

@ -778,9 +778,13 @@ public:
layoutLocation = layoutLocationEnd; layoutLocation = layoutLocationEnd;
layoutComponent = layoutComponentEnd; layoutComponent = layoutComponentEnd;
layoutIndex = layoutIndexEnd; layoutIndex = layoutIndexEnd;
#ifndef GLSLANG_WEB
clearStreamLayout(); clearStreamLayout();
clearXfbLayout(); clearXfbLayout();
#endif
} }
#ifndef GLSLANG_WEB
void clearStreamLayout() void clearStreamLayout()
{ {
layoutStream = layoutStreamEnd; layoutStream = layoutStreamEnd;
@ -791,6 +795,7 @@ public:
layoutXfbStride = layoutXfbStrideEnd; layoutXfbStride = layoutXfbStrideEnd;
layoutXfbOffset = layoutXfbOffsetEnd; layoutXfbOffset = layoutXfbOffsetEnd;
} }
#endif
bool hasNonXfbLayout() const bool hasNonXfbLayout() const
{ {

View File

@ -403,6 +403,10 @@ void TBuiltIns::addTabledBuiltins(int version, EProfile profile, const SpvVersio
forEachFunction(commonBuiltins, BaseFunctions); forEachFunction(commonBuiltins, BaseFunctions);
forEachFunction(stageBuiltins[EShLangFragment], DerivativeFunctions); forEachFunction(stageBuiltins[EShLangFragment], DerivativeFunctions);
#ifdef GLSLANG_WEB
return;
#endif
if ((profile == EEsProfile && version >= 320) || (profile != EEsProfile && version >= 450)) if ((profile == EEsProfile && version >= 320) || (profile != EEsProfile && version >= 450))
forEachFunction(stageBuiltins[EShLangCompute], DerivativeFunctions); forEachFunction(stageBuiltins[EShLangCompute], DerivativeFunctions);
} }
@ -1298,13 +1302,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
commonBuiltins.append( commonBuiltins.append(
"mediump vec2 unpackHalf2x16(highp uint);" "mediump vec2 unpackHalf2x16(highp uint);"
"\n"); "\n");
} else if (profile != EEsProfile && version >= 420) { }
#ifndef GLSLANG_WEB
else if (profile != EEsProfile && version >= 420) {
commonBuiltins.append( commonBuiltins.append(
" vec2 unpackHalf2x16(highp uint);" " vec2 unpackHalf2x16(highp uint);"
"\n"); "\n");
} }
#ifndef GLSLANG_WEB
if ((profile == EEsProfile && version >= 310) || if ((profile == EEsProfile && version >= 310) ||
(profile != EEsProfile && version >= 400)) { (profile != EEsProfile && version >= 400)) {
commonBuiltins.append( commonBuiltins.append(
@ -5405,22 +5410,25 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"mediump float gl_PointSize;" // needs qualifier fixed later "mediump float gl_PointSize;" // needs qualifier fixed later
); );
} else { } else {
#endif
if (spvVersion.vulkan == 0) if (spvVersion.vulkan == 0)
stageBuiltins[EShLangVertex].append( stageBuiltins[EShLangVertex].append(
"in highp int gl_VertexID;" // needs qualifier fixed later "in highp int gl_VertexID;" // needs qualifier fixed later
"in highp int gl_InstanceID;" // needs qualifier fixed later "in highp int gl_InstanceID;" // needs qualifier fixed later
); );
if (spvVersion.vulkan > 0) if (spvVersion.vulkan > 0)
#endif
stageBuiltins[EShLangVertex].append( stageBuiltins[EShLangVertex].append(
"in highp int gl_VertexIndex;" "in highp int gl_VertexIndex;"
"in highp int gl_InstanceIndex;" "in highp int gl_InstanceIndex;"
); );
#ifndef GLSLANG_WEB
if (version < 310) if (version < 310)
#endif
stageBuiltins[EShLangVertex].append( stageBuiltins[EShLangVertex].append(
"highp vec4 gl_Position;" // needs qualifier fixed later "highp vec4 gl_Position;" // needs qualifier fixed later
"highp float gl_PointSize;" // needs qualifier fixed later "highp float gl_PointSize;" // needs qualifier fixed later
); );
#ifndef GLSLANG_WEB
else else
stageBuiltins[EShLangVertex].append( stageBuiltins[EShLangVertex].append(
"out gl_PerVertex {" "out gl_PerVertex {"
@ -5428,7 +5436,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV
"highp float gl_PointSize;" // needs qualifier fixed later "highp float gl_PointSize;" // needs qualifier fixed later
"};" "};"
); );
#ifndef GLSLANG_WEB
} }
} }
@ -6155,16 +6162,18 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c
// In this function proper, enumerate the types, then calls the next set of functions // In this function proper, enumerate the types, then calls the next set of functions
// to enumerate all the uses for that type. // to enumerate all the uses for that type.
// //
bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140);
bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130);
// enumerate all the types // enumerate all the types
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint }; const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint };
const int image = 0; const int image = 0;
bool skipBuffer = true;
bool skipCubeArrayed = true;
#else #else
const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint, EbtFloat16 }; const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint, EbtFloat16 };
for (int image = 0; image <= 1; ++image) // loop over "bool" image vs sampler for (int image = 0; image <= 1; ++image) // loop over "bool" image vs sampler
bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140);
bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130);
#endif #endif
{ {
for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not
@ -7652,7 +7661,17 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
switch(language) { switch(language) {
case EShLangVertex: case EShLangVertex:
if (spvVersion.vulkan > 0) {
BuiltInVariable("gl_VertexIndex", EbvVertexIndex, symbolTable);
BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable);
}
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
if (spvVersion.vulkan == 0) {
SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable);
SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable);
}
if (profile != EEsProfile) { if (profile != EEsProfile) {
if (version >= 440) { if (version >= 440) {
symbolTable.setVariableExtensions("gl_BaseVertexARB", 1, &E_GL_ARB_shader_draw_parameters); symbolTable.setVariableExtensions("gl_BaseVertexARB", 1, &E_GL_ARB_shader_draw_parameters);
@ -7777,20 +7796,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("imageAtomicExchange", 1, &E_GL_OES_shader_image_atomic); symbolTable.setFunctionExtensions("imageAtomicExchange", 1, &E_GL_OES_shader_image_atomic);
symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic); symbolTable.setFunctionExtensions("imageAtomicCompSwap", 1, &E_GL_OES_shader_image_atomic);
} }
#endif
if (spvVersion.vulkan == 0) {
SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable);
SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable);
}
if (spvVersion.vulkan > 0) {
BuiltInVariable("gl_VertexIndex", EbvVertexIndex, symbolTable);
BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable);
}
#ifndef GLSLANG_WEB
if (version >= 300 /* both ES and non-ES */) { if (version >= 300 /* both ES and non-ES */) {
symbolTable.setVariableExtensions("gl_ViewID_OVR", Num_OVR_multiview_EXTs, OVR_multiview_EXTs); symbolTable.setVariableExtensions("gl_ViewID_OVR", Num_OVR_multiview_EXTs, OVR_multiview_EXTs);
BuiltInVariable("gl_ViewID_OVR", EbvViewIndex, symbolTable); BuiltInVariable("gl_ViewID_OVR", EbvViewIndex, symbolTable);
@ -7800,12 +7806,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
symbolTable.setFunctionExtensions("shadow2DEXT", 1, &E_GL_EXT_shadow_samplers); symbolTable.setFunctionExtensions("shadow2DEXT", 1, &E_GL_EXT_shadow_samplers);
symbolTable.setFunctionExtensions("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers); symbolTable.setFunctionExtensions("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers);
} }
#endif
// Fall through // Fall through
case EShLangTessControl: case EShLangTessControl:
#ifndef GLSLANG_WEB
if (profile == EEsProfile && version >= 310) { if (profile == EEsProfile && version >= 310) {
BuiltInVariable("gl_BoundingBoxEXT", EbvBoundingBox, symbolTable); BuiltInVariable("gl_BoundingBoxEXT", EbvBoundingBox, symbolTable);
symbolTable.setVariableExtensions("gl_BoundingBoxEXT", 1, symbolTable.setVariableExtensions("gl_BoundingBoxEXT", 1,
@ -7818,11 +7821,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion
BuiltInVariable("gl_BoundingBox", EbvBoundingBox, symbolTable); BuiltInVariable("gl_BoundingBox", EbvBoundingBox, symbolTable);
} }
} }
#endif
// Fall through // Fall through
case EShLangTessEvaluation: case EShLangTessEvaluation:
case EShLangGeometry: case EShLangGeometry:
#endif
SpecialQualifier("gl_Position", EvqPosition, EbvPosition, symbolTable); SpecialQualifier("gl_Position", EvqPosition, EbvPosition, symbolTable);
SpecialQualifier("gl_PointSize", EvqPointSize, EbvPointSize, symbolTable); SpecialQualifier("gl_PointSize", EvqPointSize, EbvPointSize, symbolTable);

View File

@ -3815,7 +3815,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC
case EbtFloat: PROMOTE(setDConst, double, Get); break; \ case EbtFloat: PROMOTE(setDConst, double, Get); break; \
case EbtInt: PROMOTE(setIConst, int, Get); break; \ case EbtInt: PROMOTE(setIConst, int, Get); break; \
case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \ case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \
case EbtBool: PROMOTE(setBConst, bool, Get); break; \ case EbtBool: PROMOTE_TO_BOOL(Get); break; \
default: return node; \ default: return node; \
} }
#else #else

View File

@ -83,6 +83,7 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b
globalInputDefaults.clear(); globalInputDefaults.clear();
globalOutputDefaults.clear(); globalOutputDefaults.clear();
#ifndef GLSLANG_WEB
// "Shaders in the transform // "Shaders in the transform
// feedback capturing mode have an initial global default of // feedback capturing mode have an initial global default of
// layout(xfb_buffer = 0) out;" // layout(xfb_buffer = 0) out;"
@ -94,6 +95,7 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b
if (language == EShLangGeometry) if (language == EShLangGeometry)
globalOutputDefaults.layoutStream = 0; globalOutputDefaults.layoutStream = 0;
#endif
if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "main") if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "main")
infoSink.info.message(EPrefixError, "Source entry point must be \"main\""); infoSink.info.message(EPrefixError, "Source entry point must be \"main\"");
@ -215,6 +217,7 @@ void TParseContext::parserError(const char* s)
void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens) void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>& tokens)
{ {
#ifndef GLSLANG_WEB
if (pragmaCallback) if (pragmaCallback)
pragmaCallback(loc.line, tokens); pragmaCallback(loc.line, tokens);
@ -287,6 +290,7 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector<TString>&
warn(loc, "not implemented", "#pragma once", ""); warn(loc, "not implemented", "#pragma once", "");
} else if (tokens[0].compare("glslang_binary_double_output") == 0) } else if (tokens[0].compare("glslang_binary_double_output") == 0)
intermediate.setBinaryDoubleOutput(); intermediate.setBinaryDoubleOutput();
#endif
} }
// //
@ -1396,6 +1400,7 @@ TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermType
// See if the operation is being done in an illegal location. // See if the operation is being done in an illegal location.
void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op) void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
{ {
#ifndef GLSLANG_WEB
switch (op) { switch (op) {
case EOpBarrier: case EOpBarrier:
if (language == EShLangTessControl) { if (language == EShLangTessControl) {
@ -1448,6 +1453,7 @@ void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op)
default: default:
break; break;
} }
#endif
} }
#ifndef GLSLANG_WEB #ifndef GLSLANG_WEB
@ -2467,6 +2473,7 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt
bool errorReturn = false; bool errorReturn = false;
switch(binaryNode->getOp()) { switch(binaryNode->getOp()) {
#ifndef GLSLANG_WEB
case EOpIndexDirect: case EOpIndexDirect:
case EOpIndexIndirect: case EOpIndexIndirect:
// ... tessellation control shader ... // ... tessellation control shader ...
@ -2482,10 +2489,8 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt
error(loc, "tessellation-control per-vertex output l-value must be indexed with gl_InvocationID", "[]", ""); error(loc, "tessellation-control per-vertex output l-value must be indexed with gl_InvocationID", "[]", "");
} }
} }
break; // left node is checked by base class
case EOpIndexDirectStruct:
break; // left node is checked by base class break; // left node is checked by base class
#endif
case EOpVectorSwizzle: case EOpVectorSwizzle:
errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft()); errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft());
if (!errorReturn) { if (!errorReturn) {
@ -3319,18 +3324,6 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant) if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant)
error(loc, "vertex input cannot be further qualified", "", ""); error(loc, "vertex input cannot be further qualified", "", "");
break; break;
case EShLangTessControl:
if (qualifier.patch)
error(loc, "can only use on output in tessellation-control shader", "patch", "");
break;
case EShLangTessEvaluation:
break;
case EShLangGeometry:
break;
case EShLangFragment: case EShLangFragment:
if (publicType.userDef) { if (publicType.userDef) {
profileRequires(loc, EEsProfile, 300, nullptr, "fragment-shader struct input"); profileRequires(loc, EEsProfile, 300, nullptr, "fragment-shader struct input");
@ -3341,12 +3334,16 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing an array"); requireProfile(loc, ~EEsProfile, "fragment-shader struct input containing an array");
} }
break; break;
#ifndef GLSLANG_WEB
case EShLangCompute: case EShLangCompute:
if (! symbolTable.atBuiltInLevel()) if (! symbolTable.atBuiltInLevel())
error(loc, "global storage input qualifier cannot be used in a compute shader", "in", ""); error(loc, "global storage input qualifier cannot be used in a compute shader", "in", "");
break; break;
case EShLangTessControl:
if (qualifier.patch)
error(loc, "can only use on output in tessellation-control shader", "patch", "");
break;
#endif
default: default:
break; break;
} }
@ -3364,18 +3361,6 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
} }
break; break;
case EShLangTessControl:
break;
case EShLangTessEvaluation:
if (qualifier.patch)
error(loc, "can only use on input in tessellation-evaluation shader", "patch", "");
break;
case EShLangGeometry:
break;
case EShLangFragment: case EShLangFragment:
profileRequires(loc, EEsProfile, 300, nullptr, "fragment shader output"); profileRequires(loc, EEsProfile, 300, nullptr, "fragment shader output");
if (publicType.basicType == EbtStruct) { if (publicType.basicType == EbtStruct) {
@ -3394,10 +3379,15 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali
error(loc, "cannot contain a double, int64, or uint64", GetStorageQualifierString(qualifier.storage), ""); error(loc, "cannot contain a double, int64, or uint64", GetStorageQualifierString(qualifier.storage), "");
break; break;
#ifndef GLSLANG_WEB
case EShLangCompute: case EShLangCompute:
error(loc, "global storage output qualifier cannot be used in a compute shader", "out", ""); error(loc, "global storage output qualifier cannot be used in a compute shader", "out", "");
break; break;
case EShLangTessEvaluation:
if (qualifier.patch)
error(loc, "can only use on input in tessellation-evaluation shader", "patch", "");
break;
#endif
default: default:
break; break;
} }
@ -6407,9 +6397,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
if (symbol == nullptr) if (symbol == nullptr)
reservedErrorCheck(loc, identifier); reservedErrorCheck(loc, identifier);
#ifndef GLSLANG_WEB
inheritGlobalDefaults(type.getQualifier()); inheritGlobalDefaults(type.getQualifier());
#endif
// Declare the variable // Declare the variable
if (type.isArray()) { if (type.isArray()) {
@ -6457,12 +6445,14 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden
// Pick up global defaults from the provide global defaults into dst. // Pick up global defaults from the provide global defaults into dst.
void TParseContext::inheritGlobalDefaults(TQualifier& dst) const void TParseContext::inheritGlobalDefaults(TQualifier& dst) const
{ {
#ifndef GLSLANG_WEB
if (dst.storage == EvqVaryingOut) { if (dst.storage == EvqVaryingOut) {
if (! dst.hasStream() && language == EShLangGeometry) if (! dst.hasStream() && language == EShLangGeometry)
dst.layoutStream = globalOutputDefaults.layoutStream; dst.layoutStream = globalOutputDefaults.layoutStream;
if (! dst.hasXfbBuffer()) if (! dst.hasXfbBuffer())
dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer;
} }
#endif
} }
// //
@ -7411,6 +7401,7 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.isPushConstant()) if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.isPushConstant())
requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "std430 requires the buffer storage qualifier"); requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "std430 requires the buffer storage qualifier");
break; break;
#ifndef GLSLANG_WEB
case EvqBuffer: case EvqBuffer:
requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block"); requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "buffer block");
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "buffer block"); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, nullptr, "buffer block");
@ -7425,11 +7416,9 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
if (language == EShLangFragment) { if (language == EShLangFragment) {
profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block"); profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block");
} }
#ifndef GLSLANG_WEB
else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) { else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) {
error(loc, "input blocks cannot be used in a mesh shader", "out", ""); error(loc, "input blocks cannot be used in a mesh shader", "out", "");
} }
#endif
break; break;
case EvqVaryingOut: case EvqVaryingOut:
profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "output block"); profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "output block");
@ -7446,7 +7435,6 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q
error(loc, "output blocks cannot be used in a task shader", "out", ""); error(loc, "output blocks cannot be used in a task shader", "out", "");
} }
break; break;
#ifndef GLSLANG_WEB
case EvqPayloadNV: case EvqPayloadNV:
profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV block"); profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV block");
requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask), requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask),

View File

@ -1755,6 +1755,11 @@ void TShader::addProcesses(const std::vector<std::string>& p)
intermediate->addProcesses(p); intermediate->addProcesses(p);
} }
void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); }
#ifndef GLSLANG_WEB
// Set binding base for given resource type // Set binding base for given resource type
void TShader::setShiftBinding(TResourceType res, unsigned int base) { void TShader::setShiftBinding(TResourceType res, unsigned int base) {
intermediate->setShiftBinding(res, base); intermediate->setShiftBinding(res, base);
@ -1782,7 +1787,7 @@ void TShader::setShiftSsboBinding(unsigned int base) { setShiftBinding(EResSs
// Enables binding automapping using TIoMapper // Enables binding automapping using TIoMapper
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); } void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
// Enables position.Y output negation in vertex shader // Enables position.Y output negation in vertex shader
void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
// Fragile: currently within one stage: simple auto-assignment of location // Fragile: currently within one stage: simple auto-assignment of location
void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); } void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); }
void TShader::addUniformLocationOverride(const char* name, int loc) void TShader::addUniformLocationOverride(const char* name, int loc)
@ -1793,15 +1798,16 @@ void TShader::setUniformLocationBase(int base)
{ {
intermediate->setUniformLocationBase(base); intermediate->setUniformLocationBase(base);
} }
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
#ifdef ENABLE_HLSL
void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
#endif
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); } void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); }
void TShader::setResourceSetBinding(const std::vector<std::string>& base) { intermediate->setResourceSetBinding(base); } void TShader::setResourceSetBinding(const std::vector<std::string>& base) { intermediate->setResourceSetBinding(base); }
void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); } void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
#endif
#ifdef ENABLE_HLSL
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
#endif
// //
// Turn the shader strings into a parse tree in the TIntermediate. // Turn the shader strings into a parse tree in the TIntermediate.

View File

@ -524,10 +524,11 @@ const char* StageName(EShLanguage stage)
{ {
switch(stage) { switch(stage) {
case EShLangVertex: return "vertex"; case EShLangVertex: return "vertex";
case EShLangFragment: return "fragment";
#ifndef GLSLANG_WEB
case EShLangTessControl: return "tessellation control"; case EShLangTessControl: return "tessellation control";
case EShLangTessEvaluation: return "tessellation evaluation"; case EShLangTessEvaluation: return "tessellation evaluation";
case EShLangGeometry: return "geometry"; case EShLangGeometry: return "geometry";
case EShLangFragment: return "fragment";
case EShLangCompute: return "compute"; case EShLangCompute: return "compute";
case EShLangRayGenNV: return "ray-generation"; case EShLangRayGenNV: return "ray-generation";
case EShLangIntersectNV: return "intersection"; case EShLangIntersectNV: return "intersection";
@ -537,6 +538,7 @@ const char* StageName(EShLanguage stage)
case EShLangCallableNV: return "callable"; case EShLangCallableNV: return "callable";
case EShLangMeshNV: return "mesh"; case EShLangMeshNV: return "mesh";
case EShLangTaskNV: return "task"; case EShLangTaskNV: return "task";
#endif
default: return "unknown stage"; default: return "unknown stage";
} }
} }

View File

@ -1361,6 +1361,7 @@ storage_qualifier
$$.init($1.loc); $$.init($1.loc);
$$.qualifier.storage = EvqUniform; $$.qualifier.storage = EvqUniform;
} }
GLSLANG_WEB_EXCLUDE_ON
| SHARED { | SHARED {
parseContext.globalCheck($1.loc, "shared"); parseContext.globalCheck($1.loc, "shared");
parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared");
@ -1369,7 +1370,6 @@ storage_qualifier
$$.init($1.loc); $$.init($1.loc);
$$.qualifier.storage = EvqShared; $$.qualifier.storage = EvqShared;
} }
GLSLANG_WEB_EXCLUDE_ON
| BUFFER { | BUFFER {
parseContext.globalCheck($1.loc, "buffer"); parseContext.globalCheck($1.loc, "buffer");
$$.init($1.loc); $$.init($1.loc);

View File

@ -1361,6 +1361,7 @@ storage_qualifier
$$.init($1.loc); $$.init($1.loc);
$$.qualifier.storage = EvqUniform; $$.qualifier.storage = EvqUniform;
} }
| SHARED { | SHARED {
parseContext.globalCheck($1.loc, "shared"); parseContext.globalCheck($1.loc, "shared");
parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared");
@ -1369,7 +1370,6 @@ storage_qualifier
$$.init($1.loc); $$.init($1.loc);
$$.qualifier.storage = EvqShared; $$.qualifier.storage = EvqShared;
} }
| BUFFER { | BUFFER {
parseContext.globalCheck($1.loc, "buffer"); parseContext.globalCheck($1.loc, "buffer");
$$.init($1.loc); $$.init($1.loc);

View File

@ -958,7 +958,7 @@ static const yytype_uint16 yyrline[] =
1143, 1170, 1179, 1186, 1194, 1201, 1208, 1216, 1226, 1233, 1143, 1170, 1179, 1186, 1194, 1201, 1208, 1216, 1226, 1233,
1244, 1250, 1253, 1260, 1264, 1268, 1277, 1287, 1290, 1301, 1244, 1250, 1253, 1260, 1264, 1268, 1277, 1287, 1290, 1301,
1304, 1307, 1311, 1315, 1320, 1324, 1331, 1335, 1340, 1346, 1304, 1307, 1311, 1315, 1320, 1324, 1331, 1335, 1340, 1346,
1352, 1359, 1364, 1373, 1378, 1390, 1404, 1410, 1415, 1423, 1352, 1359, 1365, 1373, 1378, 1390, 1404, 1410, 1415, 1423,
1431, 1439, 1447, 1454, 1458, 1463, 1468, 1473, 1478, 1483, 1431, 1439, 1447, 1454, 1458, 1463, 1468, 1473, 1478, 1483,
1487, 1491, 1495, 1499, 1505, 1516, 1523, 1526, 1535, 1540, 1487, 1491, 1495, 1499, 1505, 1516, 1523, 1526, 1535, 1540,
1550, 1555, 1563, 1567, 1577, 1580, 1586, 1592, 1599, 1609, 1550, 1555, 1563, 1567, 1577, 1580, 1586, 1592, 1599, 1609,
@ -5796,7 +5796,7 @@ yyreduce:
break; break;
case 162: case 162:
#line 1364 "MachineIndependent/glslang.y" /* yacc.c:1646 */ #line 1365 "MachineIndependent/glslang.y" /* yacc.c:1646 */
{ {
parseContext.globalCheck((yyvsp[0].lex).loc, "shared"); parseContext.globalCheck((yyvsp[0].lex).loc, "shared");
parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared");

View File

@ -614,11 +614,11 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
// overlap/alias/missing I/O, etc. // overlap/alias/missing I/O, etc.
inOutLocationCheck(infoSink); inOutLocationCheck(infoSink);
#ifndef GLSLANG_WEB
// invocations // invocations
if (invocations == TQualifier::layoutNotSet) if (invocations == TQualifier::layoutNotSet)
invocations = 1; invocations = 1;
#ifndef GLSLANG_WEB
if (inIoAccessed("gl_ClipDistance") && inIoAccessed("gl_ClipVertex")) if (inIoAccessed("gl_ClipDistance") && inIoAccessed("gl_ClipVertex"))
error(infoSink, "Can only use one of gl_ClipDistance or gl_ClipVertex (gl_ClipDistance is preferred)"); error(infoSink, "Can only use one of gl_ClipDistance or gl_ClipVertex (gl_ClipDistance is preferred)");
if (inIoAccessed("gl_CullDistance") && inIoAccessed("gl_ClipVertex")) if (inIoAccessed("gl_CullDistance") && inIoAccessed("gl_ClipVertex"))
@ -1045,6 +1045,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
// So, for the case of dvec3, we need two independent ioRanges. // So, for the case of dvec3, we need two independent ioRanges.
int collision = -1; // no collision int collision = -1; // no collision
#ifndef GLSLANG_WEB
if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 && if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 &&
(qualifier.isPipeInput() || qualifier.isPipeOutput())) { (qualifier.isPipeInput() || qualifier.isPipeOutput())) {
// Dealing with dvec3 in/out split across two locations. // Dealing with dvec3 in/out split across two locations.
@ -1071,7 +1072,9 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
if (collision < 0) if (collision < 0)
usedIo[set].push_back(range2); usedIo[set].push_back(range2);
} }
} else { } else
#endif
{
// Not a dvec3 in/out split across two locations, generic path. // Not a dvec3 in/out split across two locations, generic path.
// Need a single IO-range block. // Need a single IO-range block.

View File

@ -226,45 +226,48 @@ enum ComputeDerivativeMode {
class TIntermediate { class TIntermediate {
public: public:
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
implicitThisName("@this"), implicitCounterName("@count"),
language(l), language(l),
#ifdef ENABLE_HLSL #ifdef ENABLE_HLSL
implicitThisName("@this"), implicitCounterName("@count"),
source(EShSourceNone), source(EShSourceNone),
#endif #endif
profile(p), version(v), treeRoot(0), profile(p), version(v), treeRoot(0),
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false), numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
invertY(false),
useStorageBuffer(false),
nanMinMaxClamp(false),
depthReplacing(false)
#ifndef GLSLANG_WEB
,
useVulkanMemoryModel(false),
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet), invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
inputPrimitive(ElgNone), outputPrimitive(ElgNone), inputPrimitive(ElgNone), outputPrimitive(ElgNone),
pixelCenterInteger(false), originUpperLeft(false), pixelCenterInteger(false), originUpperLeft(false),
vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false), vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false), postDepthCoverage(false), depthLayout(EldNone),
hlslFunctionality1(false), hlslFunctionality1(false),
blendEquations(0), xfbMode(false), multiStream(false), blendEquations(0), xfbMode(false), multiStream(false),
#ifndef GLSLANG_WEB
layoutOverrideCoverage(false), layoutOverrideCoverage(false),
geoPassthroughEXT(false), geoPassthroughEXT(false),
numShaderRecordNVBlocks(0), numShaderRecordNVBlocks(0),
computeDerivativeMode(LayoutDerivativeNone), computeDerivativeMode(LayoutDerivativeNone),
primitives(TQualifier::layoutNotSet), primitives(TQualifier::layoutNotSet),
numTaskNVBlocks(0), numTaskNVBlocks(0),
#endif
autoMapBindings(false), autoMapBindings(false),
autoMapLocations(false), autoMapLocations(false),
invertY(false),
flattenUniformArrays(false), flattenUniformArrays(false),
useUnknownFormat(false), useUnknownFormat(false),
hlslOffsets(false), hlslOffsets(false),
useStorageBuffer(false),
useVulkanMemoryModel(false),
hlslIoMapping(false), hlslIoMapping(false),
useVariablePointers(false), useVariablePointers(false),
textureSamplerTransformMode(EShTexSampTransKeep), textureSamplerTransformMode(EShTexSampTransKeep),
needToLegalize(false), needToLegalize(false),
binaryDoubleOutput(false), binaryDoubleOutput(false),
usePhysicalStorageBuffer(false), usePhysicalStorageBuffer(false),
uniformLocationBase(0), uniformLocationBase(0)
nanMinMaxClamp(false) #endif
{ {
#ifndef GLSLANG_WEB
localSize[0] = 1; localSize[0] = 1;
localSize[1] = 1; localSize[1] = 1;
localSize[2] = 1; localSize[2] = 1;
@ -272,147 +275,9 @@ public:
localSizeSpecId[1] = TQualifier::layoutNotSet; localSizeSpecId[1] = TQualifier::layoutNotSet;
localSizeSpecId[2] = TQualifier::layoutNotSet; localSizeSpecId[2] = TQualifier::layoutNotSet;
xfbBuffers.resize(TQualifier::layoutXfbBufferEnd); xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
shiftBinding.fill(0); shiftBinding.fill(0);
}
void setLimits(const TBuiltInResource& r) { resources = r; }
bool postProcess(TIntermNode*, EShLanguage);
#ifdef GLSLANG_WEB
void output(TInfoSink&, bool tree) { }
#else
void output(TInfoSink&, bool tree);
#endif #endif
void removeTree();
#ifdef ENABLE_HLSL
void setSource(EShSource s) { source = s; }
EShSource getSource() const { return source; }
#else
void setSource(EShSource s) { assert(s == EShSourceGlsl); }
EShSource getSource() const { return EShSourceGlsl; }
#endif
void setEntryPointName(const char* ep)
{
entryPointName = ep;
processes.addProcess("entry-point");
processes.addArgument(entryPointName);
} }
void setEntryPointMangledName(const char* ep) { entryPointMangledName = ep; }
const std::string& getEntryPointName() const { return entryPointName; }
const std::string& getEntryPointMangledName() const { return entryPointMangledName; }
void setShiftBinding(TResourceType res, unsigned int shift)
{
shiftBinding[res] = shift;
const char* name = getResourceName(res);
if (name != nullptr)
processes.addIfNonZero(name, shift);
}
unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; }
void setShiftBindingForSet(TResourceType res, unsigned int shift, unsigned int set)
{
if (shift == 0) // ignore if there's no shift: it's a no-op.
return;
shiftBindingForSet[res][set] = shift;
const char* name = getResourceName(res);
if (name != nullptr) {
processes.addProcess(name);
processes.addArgument(shift);
processes.addArgument(set);
}
}
int getShiftBindingForSet(TResourceType res, unsigned int set) const
{
const auto shift = shiftBindingForSet[res].find(set);
return shift == shiftBindingForSet[res].end() ? -1 : shift->second;
}
bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); }
void setResourceSetBinding(const std::vector<std::string>& shift)
{
resourceSetBinding = shift;
if (shift.size() > 0) {
processes.addProcess("resource-set-binding");
for (int s = 0; s < (int)shift.size(); ++s)
processes.addArgument(shift[s]);
}
}
const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
void setAutoMapBindings(bool map)
{
autoMapBindings = map;
if (autoMapBindings)
processes.addProcess("auto-map-bindings");
}
bool getAutoMapBindings() const { return autoMapBindings; }
void setAutoMapLocations(bool map)
{
autoMapLocations = map;
if (autoMapLocations)
processes.addProcess("auto-map-locations");
}
bool getAutoMapLocations() const { return autoMapLocations; }
void setInvertY(bool invert)
{
invertY = invert;
if (invertY)
processes.addProcess("invert-y");
}
bool getInvertY() const { return invertY; }
void setFlattenUniformArrays(bool flatten)
{
flattenUniformArrays = flatten;
if (flattenUniformArrays)
processes.addProcess("flatten-uniform-arrays");
}
bool getFlattenUniformArrays() const { return flattenUniformArrays; }
void setNoStorageFormat(bool b)
{
useUnknownFormat = b;
if (useUnknownFormat)
processes.addProcess("no-storage-format");
}
bool getNoStorageFormat() const { return useUnknownFormat; }
void setUseStorageBuffer()
{
useStorageBuffer = true;
processes.addProcess("use-storage-buffer");
}
bool usingStorageBuffer() const { return useStorageBuffer; }
void setUseVulkanMemoryModel()
{
useVulkanMemoryModel = true;
processes.addProcess("use-vulkan-memory-model");
}
bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; }
void setUsePhysicalStorageBuffer()
{
usePhysicalStorageBuffer = true;
}
bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
void setUseVariablePointers()
{
useVariablePointers = true;
processes.addProcess("use-variable-pointers");
}
bool usingVariablePointers() const { return useVariablePointers; }
template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
bool hasCounterBufferName(const TString& name) const {
size_t len = strlen(implicitCounterName);
return name.size() > len &&
name.compare(name.size() - len, len, implicitCounterName) == 0;
}
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
void setVersion(int v) { version = v; } void setVersion(int v) { version = v; }
int getVersion() const { return version; } int getVersion() const { return version; }
@ -476,14 +341,35 @@ public:
int getNumEntryPoints() const { return numEntryPoints; } int getNumEntryPoints() const { return numEntryPoints; }
int getNumErrors() const { return numErrors; } int getNumErrors() const { return numErrors; }
void addPushConstantCount() { ++numPushConstants; } void addPushConstantCount() { ++numPushConstants; }
#ifdef GLSLANG_WEB void setLimits(const TBuiltInResource& r) { resources = r; }
int getNumPushConstants() const { return 0; }
void addShaderRecordNVCount() { } bool postProcess(TIntermNode*, EShLanguage);
void addTaskNVCount() { } void removeTree();
void setEntryPointName(const char* ep)
{
entryPointName = ep;
processes.addProcess("entry-point");
processes.addArgument(entryPointName);
}
void setEntryPointMangledName(const char* ep) { entryPointMangledName = ep; }
const std::string& getEntryPointName() const { return entryPointName; }
const std::string& getEntryPointMangledName() const { return entryPointMangledName; }
void setInvertY(bool invert)
{
invertY = invert;
if (invertY)
processes.addProcess("invert-y");
}
bool getInvertY() const { return invertY; }
#ifdef ENABLE_HLSL
void setSource(EShSource s) { source = s; }
EShSource getSource() const { return source; }
#else #else
int getNumPushConstants() const { return numPushConstants; } void setSource(EShSource s) { assert(s == EShSourceGlsl); }
void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; } EShSource getSource() const { return EShSourceGlsl; }
void addTaskNVCount() { ++numTaskNVBlocks; }
#endif #endif
bool isRecursive() const { return recursive; } bool isRecursive() const { return recursive; }
@ -562,6 +448,143 @@ public:
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&); void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
void setUseStorageBuffer()
{
useStorageBuffer = true;
processes.addProcess("use-storage-buffer");
}
bool usingStorageBuffer() const { return useStorageBuffer; }
void setDepthReplacing() { depthReplacing = true; }
bool isDepthReplacing() const { return depthReplacing; }
#ifdef GLSLANG_WEB
void output(TInfoSink&, bool tree) { }
bool getXfbMode() const { return false; }
bool isMultiStream() const { return false; }
TLayoutGeometry getOutputPrimitive() const { return ElgNone; }
bool getPostDepthCoverage() const { return false; }
bool getEarlyFragmentTests() const { return false; }
TLayoutDepth getDepth() const { return EldNone; }
bool getPixelCenterInteger() const { return false; }
void setOriginUpperLeft() { }
bool getOriginUpperLeft() const { return true; }
TInterlockOrdering getInterlockOrdering() const { return EioNone; }
bool getAutoMapBindings() const { return false; }
bool getAutoMapLocations() const { return false; }
int getNumPushConstants() const { return 0; }
void addShaderRecordNVCount() { }
void addTaskNVCount() { }
void setUseVulkanMemoryModel() { }
bool usingVulkanMemoryModel() const { return false; }
bool usingPhysicalStorageBuffer() const { return false; }
bool usingVariablePointers() const { return false; }
#else
void output(TInfoSink&, bool tree);
void setShiftBinding(TResourceType res, unsigned int shift)
{
shiftBinding[res] = shift;
const char* name = getResourceName(res);
if (name != nullptr)
processes.addIfNonZero(name, shift);
}
unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; }
void setShiftBindingForSet(TResourceType res, unsigned int shift, unsigned int set)
{
if (shift == 0) // ignore if there's no shift: it's a no-op.
return;
shiftBindingForSet[res][set] = shift;
const char* name = getResourceName(res);
if (name != nullptr) {
processes.addProcess(name);
processes.addArgument(shift);
processes.addArgument(set);
}
}
int getShiftBindingForSet(TResourceType res, unsigned int set) const
{
const auto shift = shiftBindingForSet[res].find(set);
return shift == shiftBindingForSet[res].end() ? -1 : shift->second;
}
bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); }
void setResourceSetBinding(const std::vector<std::string>& shift)
{
resourceSetBinding = shift;
if (shift.size() > 0) {
processes.addProcess("resource-set-binding");
for (int s = 0; s < (int)shift.size(); ++s)
processes.addArgument(shift[s]);
}
}
const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
void setAutoMapBindings(bool map)
{
autoMapBindings = map;
if (autoMapBindings)
processes.addProcess("auto-map-bindings");
}
bool getAutoMapBindings() const { return autoMapBindings; }
void setAutoMapLocations(bool map)
{
autoMapLocations = map;
if (autoMapLocations)
processes.addProcess("auto-map-locations");
}
bool getAutoMapLocations() const { return autoMapLocations; }
void setFlattenUniformArrays(bool flatten)
{
flattenUniformArrays = flatten;
if (flattenUniformArrays)
processes.addProcess("flatten-uniform-arrays");
}
bool getFlattenUniformArrays() const { return flattenUniformArrays; }
void setNoStorageFormat(bool b)
{
useUnknownFormat = b;
if (useUnknownFormat)
processes.addProcess("no-storage-format");
}
bool getNoStorageFormat() const { return useUnknownFormat; }
void setUseVulkanMemoryModel()
{
useVulkanMemoryModel = true;
processes.addProcess("use-vulkan-memory-model");
}
bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; }
void setUsePhysicalStorageBuffer()
{
usePhysicalStorageBuffer = true;
}
bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
void setUseVariablePointers()
{
useVariablePointers = true;
processes.addProcess("use-variable-pointers");
}
bool usingVariablePointers() const { return useVariablePointers; }
template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
bool hasCounterBufferName(const TString& name) const {
size_t len = strlen(implicitCounterName);
return name.size() > len &&
name.compare(name.size() - len, len, implicitCounterName) == 0;
}
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
int getNumPushConstants() const { return numPushConstants; }
void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; }
void addTaskNVCount() { ++numTaskNVBlocks; }
bool setInvocations(int i) bool setInvocations(int i)
{ {
if (invocations != TQualifier::layoutNotSet) if (invocations != TQualifier::layoutNotSet)
@ -631,7 +654,6 @@ public:
return true; return true;
} }
int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; } int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; }
void setXfbMode() { xfbMode = true; } void setXfbMode() { xfbMode = true; }
bool getXfbMode() const { return xfbMode; } bool getXfbMode() const { return xfbMode; }
void setMultiStream() { multiStream = true; } void setMultiStream() { multiStream = true; }
@ -644,14 +666,10 @@ public:
return true; return true;
} }
TLayoutGeometry getOutputPrimitive() const { return outputPrimitive; } TLayoutGeometry getOutputPrimitive() const { return outputPrimitive; }
void setOriginUpperLeft() { originUpperLeft = true; }
bool getOriginUpperLeft() const { return originUpperLeft; }
void setPixelCenterInteger() { pixelCenterInteger = true; }
bool getPixelCenterInteger() const { return pixelCenterInteger; }
void setEarlyFragmentTests() { earlyFragmentTests = true; }
bool getEarlyFragmentTests() const { return earlyFragmentTests; }
void setPostDepthCoverage() { postDepthCoverage = true; } void setPostDepthCoverage() { postDepthCoverage = true; }
bool getPostDepthCoverage() const { return postDepthCoverage; } bool getPostDepthCoverage() const { return postDepthCoverage; }
void setEarlyFragmentTests() { earlyFragmentTests = true; }
bool getEarlyFragmentTests() const { return earlyFragmentTests; }
bool setDepth(TLayoutDepth d) bool setDepth(TLayoutDepth d)
{ {
if (depthLayout != EldNone) if (depthLayout != EldNone)
@ -660,8 +678,66 @@ public:
return true; return true;
} }
TLayoutDepth getDepth() const { return depthLayout; } TLayoutDepth getDepth() const { return depthLayout; }
void setDepthReplacing() { depthReplacing = true; } void setOriginUpperLeft() { originUpperLeft = true; }
bool isDepthReplacing() const { return depthReplacing; } bool getOriginUpperLeft() const { return originUpperLeft; }
void setPixelCenterInteger() { pixelCenterInteger = true; }
bool getPixelCenterInteger() const { return pixelCenterInteger; }
void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
unsigned int getBlendEquations() const { return blendEquations; }
bool setXfbBufferStride(int buffer, unsigned stride)
{
if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd)
return xfbBuffers[buffer].stride == stride;
xfbBuffers[buffer].stride = stride;
return true;
}
unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
int addXfbBufferOffset(const TType&);
unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const;
unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) const;
void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
bool setPrimitives(int m)
{
if (primitives != TQualifier::layoutNotSet)
return primitives == m;
primitives = m;
return true;
}
int getPrimitives() const { return primitives; }
const char* addSemanticName(const TString& name)
{
return semanticNameSet.insert(name).first->c_str();
}
void addUniformLocationOverride(const char* nameStr, int location)
{
std::string name = nameStr;
uniformLocationOverrides[name] = location;
}
int getUniformLocationOverride(const char* nameStr) const
{
std::string name = nameStr;
auto pos = uniformLocationOverrides.find(name);
if (pos == uniformLocationOverrides.end())
return -1;
else
return pos->second;
}
void setUniformLocationBase(int base) { uniformLocationBase = base; }
int getUniformLocationBase() const { return uniformLocationBase; }
void setNeedsLegalization() { needToLegalize = true; }
bool needsLegalization() const { return needToLegalize; }
void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
#endif
#ifdef ENABLE_HLSL #ifdef ENABLE_HLSL
void setHlslFunctionality1() { hlslFunctionality1 = true; } void setHlslFunctionality1() { hlslFunctionality1 = true; }
@ -686,9 +762,6 @@ public:
bool usingHlslIoMapping() { return false; } bool usingHlslIoMapping() { return false; }
#endif #endif
void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
unsigned int getBlendEquations() const { return blendEquations; }
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee); void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
void merge(TInfoSink&, TIntermediate&); void merge(TInfoSink&, TIntermediate&);
void finalCheck(TInfoSink&, bool keepUncalled); void finalCheck(TInfoSink&, bool keepUncalled);
@ -703,19 +776,6 @@ public:
static int computeTypeLocationSize(const TType&, EShLanguage); static int computeTypeLocationSize(const TType&, EShLanguage);
static int computeTypeUniformLocationSize(const TType&); static int computeTypeUniformLocationSize(const TType&);
#ifndef GLSLANG_WEB
bool setXfbBufferStride(int buffer, unsigned stride)
{
if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd)
return xfbBuffers[buffer].stride == stride;
xfbBuffers[buffer].stride = stride;
return true;
}
unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
int addXfbBufferOffset(const TType&);
unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const;
unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) const;
#endif
static int getBaseAlignmentScalar(const TType&, int& size); static int getBaseAlignmentScalar(const TType&, int& size);
static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor); static int getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor); static int getScalarAlignment(const TType&, int& size, int& stride, bool rowMajor);
@ -726,28 +786,8 @@ public:
static int getBlockSize(const TType& blockType); static int getBlockSize(const TType& blockType);
static int computeBufferReferenceTypeSize(const TType&); static int computeBufferReferenceTypeSize(const TType&);
bool promote(TIntermOperator*); bool promote(TIntermOperator*);
void setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; }
#ifndef GLSLANG_WEB bool getNanMinMaxClamp() const { return nanMinMaxClamp; }
void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
bool setPrimitives(int m)
{
if (primitives != TQualifier::layoutNotSet)
return primitives == m;
primitives = m;
return true;
}
int getPrimitives() const { return primitives; }
#endif
const char* addSemanticName(const TString& name)
{
return semanticNameSet.insert(name).first->c_str();
}
void setSourceFile(const char* file) { if (file != nullptr) sourceFile = file; } void setSourceFile(const char* file) { if (file != nullptr) sourceFile = file; }
const std::string& getSourceFile() const { return sourceFile; } const std::string& getSourceFile() const { return sourceFile; }
@ -764,37 +804,6 @@ public:
void addProcessArgument(const std::string& arg) { processes.addArgument(arg); } void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); } const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); }
void addUniformLocationOverride(const char* nameStr, int location)
{
std::string name = nameStr;
uniformLocationOverrides[name] = location;
}
int getUniformLocationOverride(const char* nameStr) const
{
std::string name = nameStr;
auto pos = uniformLocationOverrides.find(name);
if (pos == uniformLocationOverrides.end())
return -1;
else
return pos->second;
}
void setUniformLocationBase(int base) { uniformLocationBase = base; }
int getUniformLocationBase() const { return uniformLocationBase; }
void setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; }
bool getNanMinMaxClamp() const { return nanMinMaxClamp; }
void setNeedsLegalization() { needToLegalize = true; }
bool needsLegalization() const { return needToLegalize; }
void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
const char* const implicitThisName;
const char* const implicitCounterName;
// Certain explicit conversions are allowed conditionally // Certain explicit conversions are allowed conditionally
#ifdef GLSLANG_WEB #ifdef GLSLANG_WEB
bool getArithemeticInt8Enabled() const { return false; } bool getArithemeticInt8Enabled() const { return false; }
@ -849,19 +858,25 @@ protected:
bool isConversionAllowed(TOperator op, TIntermTyped* node) const; bool isConversionAllowed(TOperator op, TIntermTyped* node) const;
TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const; TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const;
std::tuple<TBasicType, TBasicType> getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const; std::tuple<TBasicType, TBasicType> getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const;
#ifdef GLSLANG_WEB
bool extensionRequested(const char *extension) const { return false; } // JohnK: I think this function should go away.
#else
// I think this function should go away.
// This data structure is just a log to pass on to back ends. // This data structure is just a log to pass on to back ends.
// Versioning and extensions are handled in Version.cpp, with a rich // Versioning and extensions are handled in Version.cpp, with a rich
// set of functions for querying stages, versions, extension enable/disabled, etc. // set of functions for querying stages, versions, extension enable/disabled, etc.
#ifdef GLSLANG_WEB
bool extensionRequested(const char *extension) const { return false; }
#else
bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();} bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();}
#endif #endif
static const char* getResourceName(TResourceType); static const char* getResourceName(TResourceType);
const EShLanguage language; // stage, known at construction time const EShLanguage language; // stage, known at construction time
#ifdef ENABLE_HLSL #ifdef ENABLE_HLSL
public:
const char* const implicitThisName;
const char* const implicitCounterName;
protected:
EShSource source; // source language, known a bit later EShSource source; // source language, known a bit later
#endif #endif
std::string entryPointName; std::string entryPointName;
@ -879,6 +894,12 @@ protected:
int numErrors; int numErrors;
int numPushConstants; int numPushConstants;
bool recursive; bool recursive;
bool invertY;
bool useStorageBuffer;
bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
bool depthReplacing;
#ifndef GLSLANG_WEB
bool useVulkanMemoryModel;
int invocations; int invocations;
int vertices; int vertices;
TLayoutGeometry inputPrimitive; TLayoutGeometry inputPrimitive;
@ -894,21 +915,17 @@ protected:
bool earlyFragmentTests; bool earlyFragmentTests;
bool postDepthCoverage; bool postDepthCoverage;
TLayoutDepth depthLayout; TLayoutDepth depthLayout;
bool depthReplacing;
bool hlslFunctionality1; bool hlslFunctionality1;
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
bool xfbMode; bool xfbMode;
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
bool multiStream; bool multiStream;
#ifndef GLSLANG_WEB
bool layoutOverrideCoverage; bool layoutOverrideCoverage;
bool geoPassthroughEXT; bool geoPassthroughEXT;
int numShaderRecordNVBlocks; int numShaderRecordNVBlocks;
ComputeDerivativeMode computeDerivativeMode; ComputeDerivativeMode computeDerivativeMode;
int primitives; int primitives;
int numTaskNVBlocks; int numTaskNVBlocks;
#endif
// Base shift values // Base shift values
std::array<unsigned int, EResCount> shiftBinding; std::array<unsigned int, EResCount> shiftBinding;
@ -919,23 +936,29 @@ protected:
std::vector<std::string> resourceSetBinding; std::vector<std::string> resourceSetBinding;
bool autoMapBindings; bool autoMapBindings;
bool autoMapLocations; bool autoMapLocations;
bool invertY;
bool flattenUniformArrays; bool flattenUniformArrays;
bool useUnknownFormat; bool useUnknownFormat;
bool hlslOffsets; bool hlslOffsets;
bool useStorageBuffer;
bool useVulkanMemoryModel;
bool hlslIoMapping; bool hlslIoMapping;
bool useVariablePointers; bool useVariablePointers;
std::set<TString> ioAccessed; // set of names of statically read/written I/O that might need extra checking
std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
std::unordered_set<int> usedConstantId; // specialization constant ids used
std::set<TString> semanticNameSet; std::set<TString> semanticNameSet;
EShTextureSamplerTransformMode textureSamplerTransformMode; EShTextureSamplerTransformMode textureSamplerTransformMode;
bool needToLegalize;
bool binaryDoubleOutput;
bool usePhysicalStorageBuffer;
std::unordered_map<std::string, int> uniformLocationOverrides;
int uniformLocationBase;
#endif
std::unordered_set<int> usedConstantId; // specialization constant ids used
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers
// set of names of statically read/written I/O that might need extra checking
std::set<TString> ioAccessed;
// source code of shader, useful as part of debug information // source code of shader, useful as part of debug information
std::string sourceFile; std::string sourceFile;
std::string sourceText; std::string sourceText;
@ -946,14 +969,6 @@ protected:
// for OpModuleProcessed, or equivalent // for OpModuleProcessed, or equivalent
TProcesses processes; TProcesses processes;
bool needToLegalize;
bool binaryDoubleOutput;
bool usePhysicalStorageBuffer;
std::unordered_map<std::string, int> uniformLocationOverrides;
int uniformLocationBase;
bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
private: private:
void operator=(TIntermediate&); // prevent assignments void operator=(TIntermediate&); // prevent assignments
}; };