diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 12c6e491..a91f1807 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -248,6 +248,10 @@ protected: // Translate glslang profile to SPIR-V source language. spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile profile) { +#ifdef GLSLANG_WEB + return spv::SourceLanguageESSL; +#endif + switch (source) { case glslang::EShSourceGlsl: switch (profile) { @@ -601,6 +605,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI { switch (builtIn) { case glslang::EbvPointSize: +#ifndef GLSLANG_WEB // Defer adding the capability until the built-in is actually used. if (! memberDeclaration) { switch (glslangIntermediate->getStage()) { @@ -615,6 +620,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI break; } } +#endif return spv::BuiltInPointSize; case glslang::EbvPosition: return spv::BuiltInPosition; @@ -1664,6 +1670,7 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) builder.setAccessChainLValue(id); } +#ifndef GLSLANG_WEB // Process linkage-only nodes for any special additional interface work. if (linkageOnly) { if (glslangIntermediate->getHlslFunctionality1()) { @@ -1695,6 +1702,7 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) } } } +#endif } bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::TIntermBinary* node) @@ -2151,12 +2159,14 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI return false; +#ifndef GLSLANG_WEB case glslang::EOpEmitStreamVertex: builder.createNoResultOp(spv::OpEmitStreamVertex, operand); return false; case glslang::EOpEndStreamPrimitive: builder.createNoResultOp(spv::OpEndStreamPrimitive, operand); return false; +#endif default: logger->missingFunctionality("unknown glslang unary"); @@ -4123,8 +4133,12 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF std::vector> paramDecorations; // list of decorations per parameter glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence(); +#ifdef ENABLE_HLSL bool implicitThis = (int)parameters.size() > 0 && parameters[0]->getAsSymbolNode()->getName() == glslangIntermediate->implicitThisName; +#else + bool implicitThis = false; +#endif paramDecorations.resize(parameters.size()); 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). 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 spv::Scope memoryBarrierScope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice; switch (op) { -#ifndef GLSLANG_WEB case glslang::EOpEmitVertex: builder.createNoResultOp(spv::OpEmitVertex); return 0; @@ -7538,11 +7552,14 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv: builder.addCapability(spv::CapabilityShaderClockKHR); return builder.createOp(spv::OpReadClockKHR, typeId, args); } -#endif default: - logger->missingFunctionality("unknown operation with no arguments"); - return 0; + break; } +#endif + + logger->missingFunctionality("unknown operation with no arguments"); + + return 0; } 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 +#ifndef GLSLANG_WEB // 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 = ... 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); } +#endif // 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. @@ -8114,6 +8133,7 @@ void OutputSpvBin(const std::vector& spirv, const char* baseName) // Write SPIR-V out to a text file with 32-bit hexadecimal words void OutputSpvHex(const std::vector& spirv, const char* baseName, const char* varName) { +#ifndef GLSLANG_WEB std::ofstream out; out.open(baseName, std::ios::binary | std::ios::out); if (out.fail()) @@ -8141,6 +8161,7 @@ void OutputSpvHex(const std::vector& spirv, const char* baseName, out << "};"; } out.close(); +#endif } // diff --git a/SPIRV/Logger.cpp b/SPIRV/Logger.cpp index 48bd4e3a..7ea0c634 100644 --- a/SPIRV/Logger.cpp +++ b/SPIRV/Logger.cpp @@ -32,6 +32,8 @@ // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +#ifndef GLSLANG_WEB + #include "Logger.h" #include @@ -66,3 +68,5 @@ std::string SpvBuildLogger::getAllMessages() const { } } // end spv namespace + +#endif \ No newline at end of file diff --git a/SPIRV/Logger.h b/SPIRV/Logger.h index 2e4ddaf5..411367c0 100644 --- a/SPIRV/Logger.h +++ b/SPIRV/Logger.h @@ -46,6 +46,14 @@ class SpvBuildLogger { public: 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. void tbdFunctionality(const std::string& f); // Registers a missing functionality. @@ -59,6 +67,7 @@ public: // Returns all messages accumulated in the order of: // TBD functionalities, missing functionalities, warnings, errors. std::string getAllMessages() const; +#endif private: SpvBuildLogger(const SpvBuildLogger&); diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index d64f8cda..b0d56d47 100644 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -46,7 +46,9 @@ #include "SpvBuilder.h" +#ifndef GLSLANG_WEB #include "hex_float.h" +#endif #ifndef _WIN32 #include @@ -950,6 +952,10 @@ Id Builder::makeFloatConstant(float f, bool specConstant) Id Builder::makeDoubleConstant(double d, bool specConstant) { +#ifdef GLSLANG_WEB + assert(0); + return NoResult; +#else Op opcode = specConstant ? OpSpecConstant : OpConstant; Id typeId = makeFloatType(64); union { double db; unsigned long long ull; } u; @@ -974,10 +980,15 @@ Id Builder::makeDoubleConstant(double d, bool specConstant) module.mapInstruction(c); return c->getResultId(); +#endif } Id Builder::makeFloat16Constant(float f16, bool specConstant) { +#ifdef GLSLANG_WEB + assert(0); + return NoResult; +#else Op opcode = specConstant ? OpSpecConstant : OpConstant; Id typeId = makeFloatType(16); @@ -1002,6 +1013,7 @@ Id Builder::makeFloat16Constant(float f16, bool specConstant) module.mapInstruction(c); return c->getResultId(); +#endif } Id Builder::makeFpConstant(Id type, double d, bool specConstant) diff --git a/SPIRV/SpvTools.h b/SPIRV/SpvTools.h index cf8fc859..7422d012 100644 --- a/SPIRV/SpvTools.h +++ b/SPIRV/SpvTools.h @@ -41,8 +41,10 @@ #ifndef GLSLANG_SPV_TOOLS_H #define GLSLANG_SPV_TOOLS_H +#ifdef ENABLE_OPT #include #include +#endif #include "../glslang/MachineIndependent/localintermediate.h" #include "Logger.h" @@ -59,7 +61,7 @@ struct SpvOptions { bool validate; }; -#if ENABLE_OPT +#ifdef ENABLE_OPT // Use the SPIRV-Tools disassembler to print SPIR-V. void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv); diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 17561a20..44d3ccca 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -977,6 +977,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) shader->setPreamble(UserPreamble.get()); shader->addProcesses(Processes); +#ifndef GLSLANG_WEB // Set IO mapper binding shift values for (int r = 0; r < glslang::EResCount; ++r) { const glslang::TResourceType res = glslang::TResourceType(r); @@ -990,32 +991,33 @@ void CompileAndLinkShaderUnits(std::vector compUnits) i != baseBindingForSet[res][compUnit.stage].end(); ++i) shader->setShiftBindingForSet(res, i->second, i->first); } - - shader->setFlattenUniformArrays((Options & EOptionFlattenUniformArrays) != 0); shader->setNoStorageFormat((Options & EOptionNoStorageFormat) != 0); - shader->setNanMinMaxClamp(NaNClamp); shader->setResourceSetBinding(baseResourceSetBinding[compUnit.stage]); -#ifdef ENABLE_HLSL - if (Options & EOptionHlslIoMapping) - shader->setHlslIoMapping(true); -#endif - if (Options & EOptionAutoMapBindings) shader->setAutoMapBindings(true); if (Options & EOptionAutoMapLocations) shader->setAutoMapLocations(true); - if (Options & EOptionInvertY) - shader->setInvertY(true); - for (auto& uniOverride : uniformLocationOverrides) { shader->addUniformLocationOverride(uniOverride.first.c_str(), uniOverride.second); } 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 // ways of setting things. diff --git a/Test/baseResults/size b/Test/baseResults/size index 4115f7f8..6de1c4d3 100644 --- a/Test/baseResults/size +++ b/Test/baseResults/size @@ -1 +1 @@ -812032 ../build/install/bin/glslangValidator.exe +601088 ../build/install/bin/glslangValidator.exe diff --git a/Test/baseResults/spv.hlslDebugInfo.frag.out b/Test/baseResults/spv.hlslDebugInfo.frag.out index 9912d4e4..35a6a4d9 100644 --- a/Test/baseResults/spv.hlslDebugInfo.frag.out +++ b/Test/baseResults/spv.hlslDebugInfo.frag.out @@ -15,12 +15,12 @@ spv.hlslDebugInfo.vert // OpModuleProcessed shift-UBO-binding 6 // OpModuleProcessed shift-ssbo-binding 3 // OpModuleProcessed shift-uav-binding 5 -// OpModuleProcessed flatten-uniform-arrays // OpModuleProcessed no-storage-format // OpModuleProcessed resource-set-binding t0 0 0 -// OpModuleProcessed hlsl-iomap // OpModuleProcessed auto-map-bindings // OpModuleProcessed auto-map-locations +// OpModuleProcessed flatten-uniform-arrays +// OpModuleProcessed hlsl-iomap // OpModuleProcessed client vulkan100 // OpModuleProcessed target-env vulkan1.0 // OpModuleProcessed source-entrypoint origMain diff --git a/Test/baseResults/web.builtins.vert.out b/Test/baseResults/web.builtins.vert.out index 379035f8..9ea66726 100644 --- a/Test/baseResults/web.builtins.vert.out +++ b/Test/baseResults/web.builtins.vert.out @@ -1,74 +1,62 @@ ; SPIR-V ; Version: 1.0 ; Generator: Khronos Glslang Reference Front End; 7 -; Bound: 42 +; Bound: 33 ; Schema: 0 OpCapability Shader %1 = OpExtInstImport "GLSL.std.450" 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 OpName %main "main" - OpName %gl_PerVertex "gl_PerVertex" - OpMemberName %gl_PerVertex 0 "gl_Position" - OpMemberName %gl_PerVertex 1 "gl_PointSize" - OpName %_ "" + OpName %gl_Position "gl_Position" OpName %ps "ps" OpName %gl_VertexIndex "gl_VertexIndex" + OpName %gl_PointSize "gl_PointSize" OpName %gl_InstanceIndex "gl_InstanceIndex" - OpMemberDecorate %gl_PerVertex 0 Invariant - OpMemberDecorate %gl_PerVertex 0 BuiltIn Position - OpMemberDecorate %gl_PerVertex 1 BuiltIn PointSize - OpDecorate %gl_PerVertex Block + OpDecorate %gl_Position Invariant + OpDecorate %gl_Position BuiltIn Position OpDecorate %ps RelaxedPrecision OpDecorate %ps Location 0 - OpDecorate %15 RelaxedPrecision + OpDecorate %12 RelaxedPrecision OpDecorate %gl_VertexIndex BuiltIn VertexIndex - OpDecorate %30 RelaxedPrecision + OpDecorate %gl_PointSize BuiltIn PointSize + OpDecorate %25 RelaxedPrecision OpDecorate %gl_InstanceIndex BuiltIn InstanceIndex %void = OpTypeVoid %3 = OpTypeFunction %void %float = OpTypeFloat 32 %v4float = OpTypeVector %float 4 -%gl_PerVertex = OpTypeStruct %v4float %float -%_ptr_Output_gl_PerVertex = OpTypePointer Output %gl_PerVertex - %_ = OpVariable %_ptr_Output_gl_PerVertex Output - %int = OpTypeInt 32 1 - %int_0 = OpConstant %int 0 +%_ptr_Output_v4float = OpTypePointer Output %v4float +%gl_Position = OpVariable %_ptr_Output_v4float Output %_ptr_Input_float = OpTypePointer Input %float %ps = OpVariable %_ptr_Input_float Input -%_ptr_Output_v4float = OpTypePointer Output %v4float + %int = OpTypeInt 32 1 %int_4 = OpConstant %int 4 %_ptr_Input_int = OpTypePointer Input %int %gl_VertexIndex = OpVariable %_ptr_Input_int Input - %int_1 = OpConstant %int 1 %_ptr_Output_float = OpTypePointer Output %float +%gl_PointSize = OpVariable %_ptr_Output_float Output %int_5 = OpConstant %int 5 %gl_InstanceIndex = OpVariable %_ptr_Input_int Input %main = OpFunction %void None %3 %5 = OpLabel - %15 = OpLoad %float %ps - %16 = OpCompositeConstruct %v4float %15 %15 %15 %15 - %18 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %18 %16 - %22 = OpLoad %int %gl_VertexIndex - %23 = OpISub %int %int_4 %22 - %24 = OpConvertSToF %float %23 - %25 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - %26 = OpLoad %v4float %25 - %27 = OpVectorTimesScalar %v4float %26 %24 - %28 = OpAccessChain %_ptr_Output_v4float %_ %int_0 - OpStore %28 %27 - %30 = OpLoad %float %ps - %32 = OpAccessChain %_ptr_Output_float %_ %int_1 - OpStore %32 %30 - %35 = OpLoad %int %gl_InstanceIndex - %36 = OpISub %int %int_5 %35 - %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 + %12 = OpLoad %float %ps + %13 = OpCompositeConstruct %v4float %12 %12 %12 %12 + OpStore %gl_Position %13 + %18 = OpLoad %int %gl_VertexIndex + %19 = OpISub %int %int_4 %18 + %20 = OpConvertSToF %float %19 + %21 = OpLoad %v4float %gl_Position + %22 = OpVectorTimesScalar %v4float %21 %20 + OpStore %gl_Position %22 + %25 = OpLoad %float %ps + OpStore %gl_PointSize %25 + %28 = OpLoad %int %gl_InstanceIndex + %29 = OpISub %int %int_5 %28 + %30 = OpConvertSToF %float %29 + %31 = OpLoad %float %gl_PointSize + %32 = OpFMul %float %31 %30 + OpStore %gl_PointSize %32 OpReturn OpFunctionEnd diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 87d32583..9fa47faa 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -778,9 +778,13 @@ public: layoutLocation = layoutLocationEnd; layoutComponent = layoutComponentEnd; layoutIndex = layoutIndexEnd; +#ifndef GLSLANG_WEB clearStreamLayout(); clearXfbLayout(); +#endif } + +#ifndef GLSLANG_WEB void clearStreamLayout() { layoutStream = layoutStreamEnd; @@ -791,6 +795,7 @@ public: layoutXfbStride = layoutXfbStrideEnd; layoutXfbOffset = layoutXfbOffsetEnd; } +#endif bool hasNonXfbLayout() const { diff --git a/glslang/MachineIndependent/Initialize.cpp b/glslang/MachineIndependent/Initialize.cpp index 4b3d2671..6e0090cc 100644 --- a/glslang/MachineIndependent/Initialize.cpp +++ b/glslang/MachineIndependent/Initialize.cpp @@ -403,6 +403,10 @@ void TBuiltIns::addTabledBuiltins(int version, EProfile profile, const SpvVersio forEachFunction(commonBuiltins, BaseFunctions); forEachFunction(stageBuiltins[EShLangFragment], DerivativeFunctions); +#ifdef GLSLANG_WEB + return; +#endif + if ((profile == EEsProfile && version >= 320) || (profile != EEsProfile && version >= 450)) forEachFunction(stageBuiltins[EShLangCompute], DerivativeFunctions); } @@ -1298,13 +1302,14 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV commonBuiltins.append( "mediump vec2 unpackHalf2x16(highp uint);" "\n"); - } else if (profile != EEsProfile && version >= 420) { + } +#ifndef GLSLANG_WEB + else if (profile != EEsProfile && version >= 420) { commonBuiltins.append( " vec2 unpackHalf2x16(highp uint);" "\n"); } -#ifndef GLSLANG_WEB if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 400)) { commonBuiltins.append( @@ -5405,22 +5410,25 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "mediump float gl_PointSize;" // needs qualifier fixed later ); } else { -#endif if (spvVersion.vulkan == 0) stageBuiltins[EShLangVertex].append( "in highp int gl_VertexID;" // needs qualifier fixed later "in highp int gl_InstanceID;" // needs qualifier fixed later ); if (spvVersion.vulkan > 0) +#endif stageBuiltins[EShLangVertex].append( "in highp int gl_VertexIndex;" "in highp int gl_InstanceIndex;" ); +#ifndef GLSLANG_WEB if (version < 310) +#endif stageBuiltins[EShLangVertex].append( "highp vec4 gl_Position;" // needs qualifier fixed later "highp float gl_PointSize;" // needs qualifier fixed later ); +#ifndef GLSLANG_WEB else stageBuiltins[EShLangVertex].append( "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 "};" ); -#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 // 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 #ifdef GLSLANG_WEB const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint }; const int image = 0; + bool skipBuffer = true; + bool skipCubeArrayed = true; #else const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint, EbtFloat16 }; 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 { 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) { case EShLangVertex: + if (spvVersion.vulkan > 0) { + BuiltInVariable("gl_VertexIndex", EbvVertexIndex, symbolTable); + BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable); + } + #ifndef GLSLANG_WEB + if (spvVersion.vulkan == 0) { + SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable); + SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable); + } + if (profile != EEsProfile) { if (version >= 440) { 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("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 */) { symbolTable.setVariableExtensions("gl_ViewID_OVR", Num_OVR_multiview_EXTs, OVR_multiview_EXTs); 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("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers); } -#endif // Fall through case EShLangTessControl: - -#ifndef GLSLANG_WEB if (profile == EEsProfile && version >= 310) { BuiltInVariable("gl_BoundingBoxEXT", EbvBoundingBox, symbolTable); symbolTable.setVariableExtensions("gl_BoundingBoxEXT", 1, @@ -7818,11 +7821,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_BoundingBox", EbvBoundingBox, symbolTable); } } -#endif // Fall through case EShLangTessEvaluation: case EShLangGeometry: +#endif SpecialQualifier("gl_Position", EvqPosition, EbvPosition, symbolTable); SpecialQualifier("gl_PointSize", EvqPointSize, EbvPointSize, symbolTable); diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index 45385d94..fcc509dc 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -3815,7 +3815,7 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC case EbtFloat: PROMOTE(setDConst, double, Get); break; \ case EbtInt: PROMOTE(setIConst, 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; \ } #else diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index da221c11..aa888e51 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -83,6 +83,7 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b globalInputDefaults.clear(); globalOutputDefaults.clear(); +#ifndef GLSLANG_WEB // "Shaders in the transform // feedback capturing mode have an initial global default of // layout(xfb_buffer = 0) out;" @@ -94,6 +95,7 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b if (language == EShLangGeometry) globalOutputDefaults.layoutStream = 0; +#endif if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "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& tokens) { +#ifndef GLSLANG_WEB if (pragmaCallback) pragmaCallback(loc.line, tokens); @@ -287,6 +290,7 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& warn(loc, "not implemented", "#pragma once", ""); } else if (tokens[0].compare("glslang_binary_double_output") == 0) 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. void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op) { +#ifndef GLSLANG_WEB switch (op) { case EOpBarrier: if (language == EShLangTessControl) { @@ -1448,6 +1453,7 @@ void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op) default: break; } +#endif } #ifndef GLSLANG_WEB @@ -2467,6 +2473,7 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt bool errorReturn = false; switch(binaryNode->getOp()) { +#ifndef GLSLANG_WEB case EOpIndexDirect: case EOpIndexIndirect: // ... 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", "[]", ""); } } - - break; // left node is checked by base class - case EOpIndexDirectStruct: break; // left node is checked by base class +#endif case EOpVectorSwizzle: errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft()); if (!errorReturn) { @@ -3319,18 +3324,6 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali if (qualifier.isAuxiliary() || qualifier.isInterpolation() || qualifier.isMemory() || qualifier.invariant) error(loc, "vertex input cannot be further qualified", "", ""); 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: if (publicType.userDef) { 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"); } break; - - case EShLangCompute: +#ifndef GLSLANG_WEB + case EShLangCompute: if (! symbolTable.atBuiltInLevel()) error(loc, "global storage input qualifier cannot be used in a compute shader", "in", ""); break; - + case EShLangTessControl: + if (qualifier.patch) + error(loc, "can only use on output in tessellation-control shader", "patch", ""); + break; +#endif default: break; } @@ -3364,18 +3361,6 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali } 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: profileRequires(loc, EEsProfile, 300, nullptr, "fragment shader output"); 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), ""); break; +#ifndef GLSLANG_WEB case EShLangCompute: error(loc, "global storage output qualifier cannot be used in a compute shader", "out", ""); break; - + case EShLangTessEvaluation: + if (qualifier.patch) + error(loc, "can only use on input in tessellation-evaluation shader", "patch", ""); + break; +#endif default: break; } @@ -6407,9 +6397,7 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden if (symbol == nullptr) reservedErrorCheck(loc, identifier); -#ifndef GLSLANG_WEB inheritGlobalDefaults(type.getQualifier()); -#endif // Declare the variable 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. void TParseContext::inheritGlobalDefaults(TQualifier& dst) const { +#ifndef GLSLANG_WEB if (dst.storage == EvqVaryingOut) { if (! dst.hasStream() && language == EShLangGeometry) dst.layoutStream = globalOutputDefaults.layoutStream; if (! dst.hasXfbBuffer()) dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; } +#endif } // @@ -7411,6 +7401,7 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q if (currentBlockQualifier.layoutPacking == ElpStd430 && ! currentBlockQualifier.isPushConstant()) requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "std430 requires the buffer storage qualifier"); break; +#ifndef GLSLANG_WEB case EvqBuffer: requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "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) { 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()) { error(loc, "input blocks cannot be used in a mesh shader", "out", ""); } -#endif break; case EvqVaryingOut: 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", ""); } break; -#ifndef GLSLANG_WEB case EvqPayloadNV: profileRequires(loc, ~EEsProfile, 460, E_GL_NV_ray_tracing, "rayPayloadNV block"); requireStage(loc, (EShLanguageMask)(EShLangRayGenNVMask | EShLangAnyHitNVMask | EShLangClosestHitNVMask | EShLangMissNVMask), diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index ec01050d..b01cbe3a 100755 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -1755,6 +1755,11 @@ void TShader::addProcesses(const std::vector& 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 void TShader::setShiftBinding(TResourceType res, unsigned int base) { intermediate->setShiftBinding(res, base); @@ -1782,7 +1787,7 @@ void TShader::setShiftSsboBinding(unsigned int base) { setShiftBinding(EResSs // Enables binding automapping using TIoMapper void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); } // 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 void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); } void TShader::addUniformLocationOverride(const char* name, int loc) @@ -1793,15 +1798,16 @@ void TShader::setUniformLocationBase(int 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::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); } void TShader::setResourceSetBinding(const std::vector& base) { intermediate->setResourceSetBinding(base); } 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. diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index 17cc2245..05ace4d2 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -524,10 +524,11 @@ const char* StageName(EShLanguage stage) { switch(stage) { case EShLangVertex: return "vertex"; + case EShLangFragment: return "fragment"; +#ifndef GLSLANG_WEB case EShLangTessControl: return "tessellation control"; case EShLangTessEvaluation: return "tessellation evaluation"; case EShLangGeometry: return "geometry"; - case EShLangFragment: return "fragment"; case EShLangCompute: return "compute"; case EShLangRayGenNV: return "ray-generation"; case EShLangIntersectNV: return "intersection"; @@ -537,6 +538,7 @@ const char* StageName(EShLanguage stage) case EShLangCallableNV: return "callable"; case EShLangMeshNV: return "mesh"; case EShLangTaskNV: return "task"; +#endif default: return "unknown stage"; } } diff --git a/glslang/MachineIndependent/glslang.m4 b/glslang/MachineIndependent/glslang.m4 index aef15f65..1bc12d2b 100644 --- a/glslang/MachineIndependent/glslang.m4 +++ b/glslang/MachineIndependent/glslang.m4 @@ -1361,6 +1361,7 @@ storage_qualifier $$.init($1.loc); $$.qualifier.storage = EvqUniform; } +GLSLANG_WEB_EXCLUDE_ON | SHARED { parseContext.globalCheck($1.loc, "shared"); parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); @@ -1369,7 +1370,6 @@ storage_qualifier $$.init($1.loc); $$.qualifier.storage = EvqShared; } -GLSLANG_WEB_EXCLUDE_ON | BUFFER { parseContext.globalCheck($1.loc, "buffer"); $$.init($1.loc); diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index ca0bff13..bc32ade8 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -1361,6 +1361,7 @@ storage_qualifier $$.init($1.loc); $$.qualifier.storage = EvqUniform; } + | SHARED { parseContext.globalCheck($1.loc, "shared"); parseContext.profileRequires($1.loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); @@ -1369,7 +1370,6 @@ storage_qualifier $$.init($1.loc); $$.qualifier.storage = EvqShared; } - | BUFFER { parseContext.globalCheck($1.loc, "buffer"); $$.init($1.loc); diff --git a/glslang/MachineIndependent/glslang_tab.cpp b/glslang/MachineIndependent/glslang_tab.cpp index 0fb7f77a..499b20f3 100644 --- a/glslang/MachineIndependent/glslang_tab.cpp +++ b/glslang/MachineIndependent/glslang_tab.cpp @@ -958,7 +958,7 @@ static const yytype_uint16 yyrline[] = 1143, 1170, 1179, 1186, 1194, 1201, 1208, 1216, 1226, 1233, 1244, 1250, 1253, 1260, 1264, 1268, 1277, 1287, 1290, 1301, 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, 1487, 1491, 1495, 1499, 1505, 1516, 1523, 1526, 1535, 1540, 1550, 1555, 1563, 1567, 1577, 1580, 1586, 1592, 1599, 1609, @@ -5796,7 +5796,7 @@ yyreduce: break; 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.profileRequires((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index da51ebaf..12939232 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -614,11 +614,11 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) // overlap/alias/missing I/O, etc. inOutLocationCheck(infoSink); +#ifndef GLSLANG_WEB // invocations if (invocations == TQualifier::layoutNotSet) invocations = 1; -#ifndef GLSLANG_WEB if (inIoAccessed("gl_ClipDistance") && inIoAccessed("gl_ClipVertex")) error(infoSink, "Can only use one of gl_ClipDistance or gl_ClipVertex (gl_ClipDistance is preferred)"); 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. int collision = -1; // no collision +#ifndef GLSLANG_WEB if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 && (qualifier.isPipeInput() || qualifier.isPipeOutput())) { // 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) usedIo[set].push_back(range2); } - } else { + } else +#endif + { // Not a dvec3 in/out split across two locations, generic path. // Need a single IO-range block. diff --git a/glslang/MachineIndependent/localintermediate.h b/glslang/MachineIndependent/localintermediate.h index b2ac7379..2dcacff6 100644 --- a/glslang/MachineIndependent/localintermediate.h +++ b/glslang/MachineIndependent/localintermediate.h @@ -226,45 +226,48 @@ enum ComputeDerivativeMode { class TIntermediate { public: explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : - implicitThisName("@this"), implicitCounterName("@count"), language(l), #ifdef ENABLE_HLSL + implicitThisName("@this"), implicitCounterName("@count"), source(EShSourceNone), #endif profile(p), version(v), treeRoot(0), 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), inputPrimitive(ElgNone), outputPrimitive(ElgNone), pixelCenterInteger(false), originUpperLeft(false), vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false), - postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false), + postDepthCoverage(false), depthLayout(EldNone), hlslFunctionality1(false), blendEquations(0), xfbMode(false), multiStream(false), -#ifndef GLSLANG_WEB layoutOverrideCoverage(false), geoPassthroughEXT(false), numShaderRecordNVBlocks(0), computeDerivativeMode(LayoutDerivativeNone), primitives(TQualifier::layoutNotSet), numTaskNVBlocks(0), -#endif autoMapBindings(false), autoMapLocations(false), - invertY(false), flattenUniformArrays(false), useUnknownFormat(false), hlslOffsets(false), - useStorageBuffer(false), - useVulkanMemoryModel(false), hlslIoMapping(false), useVariablePointers(false), textureSamplerTransformMode(EShTexSampTransKeep), needToLegalize(false), binaryDoubleOutput(false), usePhysicalStorageBuffer(false), - uniformLocationBase(0), - nanMinMaxClamp(false) + uniformLocationBase(0) +#endif { +#ifndef GLSLANG_WEB localSize[0] = 1; localSize[1] = 1; localSize[2] = 1; @@ -272,147 +275,9 @@ public: localSizeSpecId[1] = TQualifier::layoutNotSet; localSizeSpecId[2] = TQualifier::layoutNotSet; xfbBuffers.resize(TQualifier::layoutXfbBufferEnd); - 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 - 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& 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& 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 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; } int getVersion() const { return version; } @@ -476,14 +341,35 @@ public: int getNumEntryPoints() const { return numEntryPoints; } int getNumErrors() const { return numErrors; } void addPushConstantCount() { ++numPushConstants; } -#ifdef GLSLANG_WEB - int getNumPushConstants() const { return 0; } - void addShaderRecordNVCount() { } - void addTaskNVCount() { } + void setLimits(const TBuiltInResource& r) { resources = r; } + + bool postProcess(TIntermNode*, EShLanguage); + 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 - int getNumPushConstants() const { return numPushConstants; } - void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; } - void addTaskNVCount() { ++numTaskNVBlocks; } + void setSource(EShSource s) { assert(s == EShSourceGlsl); } + EShSource getSource() const { return EShSourceGlsl; } #endif bool isRecursive() const { return recursive; } @@ -562,6 +448,143 @@ public: void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); 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& 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& 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 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) { if (invocations != TQualifier::layoutNotSet) @@ -631,7 +654,6 @@ public: return true; } int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; } - void setXfbMode() { xfbMode = true; } bool getXfbMode() const { return xfbMode; } void setMultiStream() { multiStream = true; } @@ -644,14 +666,10 @@ public: return true; } 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; } bool getPostDepthCoverage() const { return postDepthCoverage; } + void setEarlyFragmentTests() { earlyFragmentTests = true; } + bool getEarlyFragmentTests() const { return earlyFragmentTests; } bool setDepth(TLayoutDepth d) { if (depthLayout != EldNone) @@ -660,8 +678,66 @@ public: return true; } TLayoutDepth getDepth() const { return depthLayout; } - void setDepthReplacing() { depthReplacing = true; } - bool isDepthReplacing() const { return depthReplacing; } + void setOriginUpperLeft() { originUpperLeft = true; } + 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 void setHlslFunctionality1() { hlslFunctionality1 = true; } @@ -686,9 +762,6 @@ public: bool usingHlslIoMapping() { return false; } #endif - void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); } - unsigned int getBlendEquations() const { return blendEquations; } - void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee); void merge(TInfoSink&, TIntermediate&); void finalCheck(TInfoSink&, bool keepUncalled); @@ -703,19 +776,6 @@ public: static int computeTypeLocationSize(const TType&, EShLanguage); 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 getBaseAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, 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 computeBufferReferenceTypeSize(const TType&); bool promote(TIntermOperator*); - -#ifndef GLSLANG_WEB - 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 setNanMinMaxClamp(bool setting) { nanMinMaxClamp = setting; } + bool getNanMinMaxClamp() const { return nanMinMaxClamp; } void setSourceFile(const char* file) { if (file != nullptr) sourceFile = file; } const std::string& getSourceFile() const { return sourceFile; } @@ -764,37 +804,6 @@ public: void addProcessArgument(const std::string& arg) { processes.addArgument(arg); } const std::vector& 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 #ifdef GLSLANG_WEB bool getArithemeticInt8Enabled() const { return false; } @@ -849,19 +858,25 @@ protected: bool isConversionAllowed(TOperator op, TIntermTyped* node) const; TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const; std::tuple getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const; -#ifdef GLSLANG_WEB - bool extensionRequested(const char *extension) const { return false; } -#else - // I think this function should go away. + + // JohnK: I think this function should go away. // This data structure is just a log to pass on to back ends. // Versioning and extensions are handled in Version.cpp, with a rich // 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();} #endif + static const char* getResourceName(TResourceType); const EShLanguage language; // stage, known at construction time #ifdef ENABLE_HLSL +public: + const char* const implicitThisName; + const char* const implicitCounterName; +protected: EShSource source; // source language, known a bit later #endif std::string entryPointName; @@ -879,6 +894,12 @@ protected: int numErrors; int numPushConstants; 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 vertices; TLayoutGeometry inputPrimitive; @@ -894,21 +915,17 @@ protected: bool earlyFragmentTests; bool postDepthCoverage; TLayoutDepth depthLayout; - bool depthReplacing; bool hlslFunctionality1; int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift bool xfbMode; std::vector xfbBuffers; // all the data we need to track per xfb buffer bool multiStream; - -#ifndef GLSLANG_WEB bool layoutOverrideCoverage; bool geoPassthroughEXT; int numShaderRecordNVBlocks; ComputeDerivativeMode computeDerivativeMode; int primitives; int numTaskNVBlocks; -#endif // Base shift values std::array shiftBinding; @@ -919,23 +936,29 @@ protected: std::vector resourceSetBinding; bool autoMapBindings; bool autoMapLocations; - bool invertY; bool flattenUniformArrays; bool useUnknownFormat; bool hlslOffsets; - bool useStorageBuffer; - bool useVulkanMemoryModel; bool hlslIoMapping; bool useVariablePointers; - std::set ioAccessed; // set of names of statically read/written I/O that might need extra checking - std::vector usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers - std::vector usedAtomics; // sets of bindings used by atomic counters - std::unordered_set usedConstantId; // specialization constant ids used std::set semanticNameSet; EShTextureSamplerTransformMode textureSamplerTransformMode; + bool needToLegalize; + bool binaryDoubleOutput; + bool usePhysicalStorageBuffer; + + std::unordered_map uniformLocationOverrides; + int uniformLocationBase; +#endif + + std::unordered_set usedConstantId; // specialization constant ids used + std::vector usedAtomics; // sets of bindings used by atomic counters + std::vector 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 ioAccessed; // source code of shader, useful as part of debug information std::string sourceFile; std::string sourceText; @@ -946,14 +969,6 @@ protected: // for OpModuleProcessed, or equivalent TProcesses processes; - bool needToLegalize; - bool binaryDoubleOutput; - bool usePhysicalStorageBuffer; - - std::unordered_map uniformLocationOverrides; - int uniformLocationBase; - bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN - private: void operator=(TIntermediate&); // prevent assignments };