diff --git a/SPIRV/GlslangToSpv.cpp b/SPIRV/GlslangToSpv.cpp index 4a073234..fb578f21 100644 --- a/SPIRV/GlslangToSpv.cpp +++ b/SPIRV/GlslangToSpv.cpp @@ -390,9 +390,9 @@ void TranslateMemoryDecoration(const glslang::TQualifier& qualifier, std::vector } if (qualifier.restrict) memory.push_back(spv::DecorationRestrict); - if (qualifier.readonly) + if (qualifier.isReadOnly()) memory.push_back(spv::DecorationNonWritable); - if (qualifier.writeonly) + if (qualifier.isWriteOnly()) memory.push_back(spv::DecorationNonReadable); #endif } @@ -1180,20 +1180,16 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T if (glslangIntermediate->getSource() != glslang::EShSourceHlsl || type.getQualifier().storage == glslang::EvqUniform) { -#ifndef GLSLANG_WEB - if (type.getBasicType() == glslang::EbtAtomicUint) + if (type.isAtomic()) return spv::StorageClassAtomicCounter; -#endif if (type.containsOpaque()) return spv::StorageClassUniformConstant; } -#ifndef GLSLANG_WEB if (type.getQualifier().isUniformOrBuffer() && - type.getQualifier().layoutShaderRecordNV) { + type.getQualifier().isShaderRecordNV()) { return spv::StorageClassShaderRecordBufferNV; } -#endif if (glslangIntermediate->usingStorageBuffer() && type.getQualifier().storage == glslang::EvqBuffer) { addPre13Extension(spv::E_SPV_KHR_storage_buffer_storage_class); @@ -1201,10 +1197,8 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T } if (type.getQualifier().isUniformOrBuffer()) { -#ifndef GLSLANG_WEB if (type.getQualifier().isPushConstant()) return spv::StorageClassPushConstant; -#endif if (type.getBasicType() == glslang::EbtBlock) return spv::StorageClassUniform; return spv::StorageClassUniformConstant; @@ -1215,7 +1209,7 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T case glslang::EvqConstReadOnly: return spv::StorageClassFunction; case glslang::EvqTemporary: return spv::StorageClassFunction; #ifndef GLSLANG_WEB - case glslang::EvqShared: return spv::StorageClassWorkgroup; + case glslang::EvqShared: return spv::StorageClassWorkgroup; case glslang::EvqPayloadNV: return spv::StorageClassRayPayloadNV; case glslang::EvqPayloadInNV: return spv::StorageClassIncomingRayPayloadNV; case glslang::EvqHitAttrNV: return spv::StorageClassHitAttributeNV; diff --git a/SPIRV/SpvBuilder.cpp b/SPIRV/SpvBuilder.cpp index 4a6f30be..bd208952 100644 --- a/SPIRV/SpvBuilder.cpp +++ b/SPIRV/SpvBuilder.cpp @@ -2315,7 +2315,7 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector& Instruction* instr = module.getInstruction(componentTypeId); #ifdef GLSLANG_WEB const unsigned bitCount = 32; - assert(bitcount == instr->getImmediateOperand(0)); + assert(bitCount == instr->getImmediateOperand(0)); #else const unsigned bitCount = instr->getImmediateOperand(0); #endif diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index 44d3ccca..9fa311bc 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -1040,6 +1040,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) DirStackFileIncluder includer; std::for_each(IncludeDirectoryList.rbegin(), IncludeDirectoryList.rend(), [&includer](const std::string& dir) { includer.pushExternalLocalDirectory(dir); }); +#ifndef GLSLANG_WEB if (Options & EOptionOutputPreprocessed) { std::string str; if (shader->preprocess(&Resources, defaultVersion, ENoProfile, false, false, messages, &str, includer)) { @@ -1051,6 +1052,7 @@ void CompileAndLinkShaderUnits(std::vector compUnits) StderrIfNonEmpty(shader->getInfoDebugLog()); continue; } +#endif if (! shader->parse(&Resources, defaultVersion, false, messages, includer)) CompileFailed = true; diff --git a/Test/baseResults/glspv.vert.out b/Test/baseResults/glspv.vert.out index f2fe53b2..d5192628 100644 --- a/Test/baseResults/glspv.vert.out +++ b/Test/baseResults/glspv.vert.out @@ -2,12 +2,14 @@ glspv.vert ERROR: 0:3: 'push_constant' : only allowed when using GLSL for Vulkan ERROR: 0:6: 'descriptor set' : only allowed when using GLSL for Vulkan ERROR: 0:8: 'shared' : not allowed when generating SPIR-V +ERROR: 0:8: 'binding' : uniform/buffer blocks require layout(binding=X) ERROR: 0:9: 'packed' : not allowed when generating SPIR-V +ERROR: 0:9: 'binding' : uniform/buffer blocks require layout(binding=X) ERROR: 0:13: 'gl_VertexIndex' : undeclared identifier ERROR: 0:14: 'gl_InstanceIndex' : undeclared identifier ERROR: 0:17: 'gl_DepthRangeParameters' : undeclared identifier ERROR: 0:20: '' : syntax error, unexpected IDENTIFIER, expecting LEFT_BRACE or COMMA or SEMICOLON -ERROR: 8 compilation errors. No code generated. +ERROR: 10 compilation errors. No code generated. SPIR-V is not generated for failed compile or link diff --git a/Test/baseResults/link1.vk.frag.out b/Test/baseResults/link1.vk.frag.out index a24246a6..094a50d8 100644 --- a/Test/baseResults/link1.vk.frag.out +++ b/Test/baseResults/link1.vk.frag.out @@ -42,8 +42,8 @@ gl_FragCoord origin is upper left 0:? 'b' ( global 5-element array of highp int) 0:? 'c' ( global unsized 4-element array of highp int) 0:? 'i' ( global highp int) -0:? 'anon@0' (layout( column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float r}) -0:? 'anon@1' (layout( column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float m}) +0:? 'anon@0' (layout( binding=0 column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float r}) +0:? 'anon@1' (layout( binding=1 column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float m}) link2.vk.frag Shader version: 450 @@ -99,8 +99,8 @@ gl_FragCoord origin is upper left 0:? 'b' ( global unsized 3-element array of highp int) 0:? 'c' ( global 7-element array of highp int) 0:? 'i' ( global highp int) -0:? 'anon@0' (layout( column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float r}) -0:? 'anon@1' (layout( column_major std430) buffer block{layout( column_major std430) buffer 4-element array of highp float m}) +0:? 'anon@0' (layout( binding=0 column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float r}) +0:? 'anon@1' (layout( binding=1 column_major std430) buffer block{layout( column_major std430) buffer 4-element array of highp float m}) Linked fragment stage: @@ -192,8 +192,8 @@ gl_FragCoord origin is upper left 0:? 'b' ( global 5-element array of highp int) 0:? 'c' ( global 7-element array of highp int) 0:? 'i' ( global highp int) -0:? 'anon@0' (layout( column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float r}) -0:? 'anon@1' (layout( column_major std430) buffer block{layout( column_major std430) buffer 4-element array of highp float m}) +0:? 'anon@0' (layout( binding=0 column_major std430) buffer block{layout( column_major std430) buffer unsized 1-element array of highp float r}) +0:? 'anon@1' (layout( binding=1 column_major std430) buffer block{layout( column_major std430) buffer 4-element array of highp float m}) 0:? 's2D' (layout( binding=1) uniform highp sampler2D) // Module Version 10000 @@ -233,7 +233,7 @@ gl_FragCoord origin is upper left MemberDecorate 67(bnameImplicit) 0 Offset 0 Decorate 67(bnameImplicit) BufferBlock Decorate 69 DescriptorSet 0 - Decorate 69 Binding 0 + Decorate 69 Binding 1 2: TypeVoid 3: TypeFunction 2 6: TypeFloat 32 diff --git a/Test/baseResults/size b/Test/baseResults/size index c870190a..48487765 100644 --- a/Test/baseResults/size +++ b/Test/baseResults/size @@ -1 +1 @@ -409600 ../build/install/bin/glslangValidator.exe +388096 ../build/install/bin/glslangValidator.exe diff --git a/Test/baseResults/spv.debugInfo.1.1.frag.out b/Test/baseResults/spv.debugInfo.1.1.frag.out index afd8cfdf..e2120892 100644 --- a/Test/baseResults/spv.debugInfo.1.1.frag.out +++ b/Test/baseResults/spv.debugInfo.1.1.frag.out @@ -81,6 +81,7 @@ void main() Name 97 "i" ModuleProcessed "no-storage-format" ModuleProcessed "resource-set-binding 3" + ModuleProcessed "auto-map-bindings" ModuleProcessed "auto-map-locations" ModuleProcessed "client opengl100" ModuleProcessed "target-env spirv1.3" @@ -99,7 +100,7 @@ void main() Decorate 56 Binding 0 Decorate 67(s2d) Location 0 Decorate 67(s2d) DescriptorSet 3 - Decorate 67(s2d) Binding 0 + Decorate 67(s2d) Binding 1 3: TypeVoid 4: TypeFunction 3 7: TypeInt 32 1 diff --git a/Test/baseResults/spv.hlslOffsets.vert.out b/Test/baseResults/spv.hlslOffsets.vert.out index 84dc47b2..72367546 100644 --- a/Test/baseResults/spv.hlslOffsets.vert.out +++ b/Test/baseResults/spv.hlslOffsets.vert.out @@ -4,7 +4,7 @@ Shader version: 450 0:27 Function Definition: main( ( global void) 0:27 Function Parameters: 0:? Linker Objects -0:? 'anon@0' (layout( column_major std430) buffer block{layout( column_major std430) buffer highp float m0, layout( column_major std430) buffer highp 3-component vector of float m4, layout( column_major std430) buffer highp float m16, layout( column_major std430 offset=20) buffer highp 3-component vector of float m20, layout( column_major std430) buffer highp 3-component vector of float m32, layout( column_major std430) buffer highp 2-component vector of float m48, layout( column_major std430) buffer highp 2-component vector of float m56, layout( column_major std430) buffer highp float m64, layout( column_major std430) buffer highp 2-component vector of float m68, layout( column_major std430) buffer highp float m76, layout( column_major std430) buffer highp float m80, layout( column_major std430 offset=88) buffer highp 2-component vector of float m88, layout( column_major std430) buffer highp 2-component vector of float m96, layout( column_major std430) buffer 2-component vector of double m112}) +0:? 'anon@0' (layout( binding=0 column_major std430) buffer block{layout( column_major std430) buffer highp float m0, layout( column_major std430) buffer highp 3-component vector of float m4, layout( column_major std430) buffer highp float m16, layout( column_major std430 offset=20) buffer highp 3-component vector of float m20, layout( column_major std430) buffer highp 3-component vector of float m32, layout( column_major std430) buffer highp 2-component vector of float m48, layout( column_major std430) buffer highp 2-component vector of float m56, layout( column_major std430) buffer highp float m64, layout( column_major std430) buffer highp 2-component vector of float m68, layout( column_major std430) buffer highp float m76, layout( column_major std430) buffer highp float m80, layout( column_major std430 offset=88) buffer highp 2-component vector of float m88, layout( column_major std430) buffer highp 2-component vector of float m96, layout( column_major std430) buffer 2-component vector of double m112}) Linked vertex stage: @@ -15,7 +15,7 @@ Shader version: 450 0:27 Function Definition: main( ( global void) 0:27 Function Parameters: 0:? Linker Objects -0:? 'anon@0' (layout( column_major std430) buffer block{layout( column_major std430) buffer highp float m0, layout( column_major std430) buffer highp 3-component vector of float m4, layout( column_major std430) buffer highp float m16, layout( column_major std430 offset=20) buffer highp 3-component vector of float m20, layout( column_major std430) buffer highp 3-component vector of float m32, layout( column_major std430) buffer highp 2-component vector of float m48, layout( column_major std430) buffer highp 2-component vector of float m56, layout( column_major std430) buffer highp float m64, layout( column_major std430) buffer highp 2-component vector of float m68, layout( column_major std430) buffer highp float m76, layout( column_major std430) buffer highp float m80, layout( column_major std430 offset=88) buffer highp 2-component vector of float m88, layout( column_major std430) buffer highp 2-component vector of float m96, layout( column_major std430) buffer 2-component vector of double m112}) +0:? 'anon@0' (layout( binding=0 column_major std430) buffer block{layout( column_major std430) buffer highp float m0, layout( column_major std430) buffer highp 3-component vector of float m4, layout( column_major std430) buffer highp float m16, layout( column_major std430 offset=20) buffer highp 3-component vector of float m20, layout( column_major std430) buffer highp 3-component vector of float m32, layout( column_major std430) buffer highp 2-component vector of float m48, layout( column_major std430) buffer highp 2-component vector of float m56, layout( column_major std430) buffer highp float m64, layout( column_major std430) buffer highp 2-component vector of float m68, layout( column_major std430) buffer highp float m76, layout( column_major std430) buffer highp float m80, layout( column_major std430 offset=88) buffer highp 2-component vector of float m88, layout( column_major std430) buffer highp 2-component vector of float m96, layout( column_major std430) buffer 2-component vector of double m112}) // Module Version 10000 // Generated by (magic number): 80007 diff --git a/Test/baseResults/web.array.frag.out b/Test/baseResults/web.array.frag.out new file mode 100644 index 00000000..df70be12 --- /dev/null +++ b/Test/baseResults/web.array.frag.out @@ -0,0 +1,102 @@ +; SPIR-V +; Version: 1.0 +; Generator: Khronos Glslang Reference Front End; 7 +; Bound: 74 +; Schema: 0 + OpCapability Shader + %1 = OpExtInstImport "GLSL.std.450" + OpMemoryModel Logical GLSL450 + OpEntryPoint Fragment %main "main" %colorOut + OpExecutionMode %main OriginUpperLeft + OpSource ESSL 310 + OpName %main "main" + OpName %foo_f1_5__ "foo(f1[5];" + OpName %a "a" + OpName %g4 "g4" + OpName %g5 "g5" + OpName %param "param" + OpName %u "u" + OpName %param_0 "param" + OpName %colorOut "colorOut" + OpDecorate %colorOut Location 0 + %void = OpTypeVoid + %3 = OpTypeFunction %void + %float = OpTypeFloat 32 + %uint = OpTypeInt 32 0 + %uint_5 = OpConstant %uint 5 +%_arr_float_uint_5 = OpTypeArray %float %uint_5 +%_ptr_Function__arr_float_uint_5 = OpTypePointer Function %_arr_float_uint_5 + %uint_4 = OpConstant %uint 4 +%_arr_float_uint_4 = OpTypeArray %float %uint_4 + %13 = OpTypeFunction %_arr_float_uint_4 %_ptr_Function__arr_float_uint_5 + %int = OpTypeInt 32 1 + %int_0 = OpConstant %int 0 +%_ptr_Function_float = OpTypePointer Function %float + %int_1 = OpConstant %int 1 + %int_2 = OpConstant %int 2 + %int_3 = OpConstant %int 3 +%_ptr_Private__arr_float_uint_4 = OpTypePointer Private %_arr_float_uint_4 + %g4 = OpVariable %_ptr_Private__arr_float_uint_4 Private +%_ptr_Private__arr_float_uint_5 = OpTypePointer Private %_arr_float_uint_5 + %g5 = OpVariable %_ptr_Private__arr_float_uint_5 Private + %float_1 = OpConstant %float 1 + %float_2 = OpConstant %float 2 + %float_3 = OpConstant %float 3 + %float_4 = OpConstant %float 4 + %45 = OpConstantComposite %_arr_float_uint_4 %float_1 %float_2 %float_3 %float_4 + %bool = OpTypeBool + %v2float = OpTypeVector %float 2 +%_ptr_Output_v2float = OpTypePointer Output %v2float + %colorOut = OpVariable %_ptr_Output_v2float Output + %float_5 = OpConstant %float 5 + %73 = OpConstantComposite %v2float %float_4 %float_5 + %main = OpFunction %void None %3 + %5 = OpLabel + %param = OpVariable %_ptr_Function__arr_float_uint_5 Function + %u = OpVariable %_ptr_Function__arr_float_uint_5 Function + %param_0 = OpVariable %_ptr_Function__arr_float_uint_5 Function + %39 = OpLoad %_arr_float_uint_5 %g5 + OpStore %param %39 + %40 = OpFunctionCall %_arr_float_uint_4 %foo_f1_5__ %param + OpStore %g4 %40 + %46 = OpLoad %_arr_float_uint_4 %g4 + %48 = OpCompositeExtract %float %45 0 + %49 = OpCompositeExtract %float %46 0 + %50 = OpFOrdEqual %bool %48 %49 + %51 = OpCompositeExtract %float %45 1 + %52 = OpCompositeExtract %float %46 1 + %53 = OpFOrdEqual %bool %51 %52 + %54 = OpLogicalAnd %bool %50 %53 + %55 = OpCompositeExtract %float %45 2 + %56 = OpCompositeExtract %float %46 2 + %57 = OpFOrdEqual %bool %55 %56 + %58 = OpLogicalAnd %bool %54 %57 + %59 = OpCompositeExtract %float %45 3 + %60 = OpCompositeExtract %float %46 3 + %61 = OpFOrdEqual %bool %59 %60 + %62 = OpLogicalAnd %bool %58 %61 + OpSelectionMerge %64 None + OpBranchConditional %62 %63 %64 + %63 = OpLabel + OpBranch %64 + %64 = OpLabel + %67 = OpLoad %_arr_float_uint_5 %u + OpStore %param_0 %67 + %68 = OpFunctionCall %_arr_float_uint_4 %foo_f1_5__ %param_0 + OpStore %colorOut %73 + OpReturn + OpFunctionEnd + %foo_f1_5__ = OpFunction %_arr_float_uint_4 None %13 + %a = OpFunctionParameter %_ptr_Function__arr_float_uint_5 + %16 = OpLabel + %20 = OpAccessChain %_ptr_Function_float %a %int_0 + %21 = OpLoad %float %20 + %23 = OpAccessChain %_ptr_Function_float %a %int_1 + %24 = OpLoad %float %23 + %26 = OpAccessChain %_ptr_Function_float %a %int_2 + %27 = OpLoad %float %26 + %29 = OpAccessChain %_ptr_Function_float %a %int_3 + %30 = OpLoad %float %29 + %31 = OpCompositeConstruct %_arr_float_uint_4 %21 %24 %27 %30 + OpReturnValue %31 + OpFunctionEnd diff --git a/Test/link1.vk.frag b/Test/link1.vk.frag index 167e78ee..c860f647 100644 --- a/Test/link1.vk.frag +++ b/Test/link1.vk.frag @@ -10,8 +10,8 @@ int b[5]; int c[]; int i; -buffer bnameRuntime { float r[]; }; -buffer bnameImplicit { float m[]; }; +layout (binding = 0) buffer bnameRuntime { float r[]; }; +layout (binding = 1) buffer bnameImplicit { float m[]; }; void main() { diff --git a/Test/link2.vk.frag b/Test/link2.vk.frag index b80402ca..b83f8694 100644 --- a/Test/link2.vk.frag +++ b/Test/link2.vk.frag @@ -8,8 +8,8 @@ int b[]; int c[7]; int i; -buffer bnameRuntime { float r[]; }; -buffer bnameImplicit { float m[4]; }; +layout (binding = 0) buffer bnameRuntime { float r[]; }; +layout (binding = 1) buffer bnameImplicit { float m[4]; }; vec4 getColor() { diff --git a/Test/runtests b/Test/runtests index cf947a6b..8e31c069 100755 --- a/Test/runtests +++ b/Test/runtests @@ -145,7 +145,7 @@ echo Testing SPV Debug Information $EXE -g --relaxed-errors --suppress-warnings --aml --amb --hlsl-offsets --nsf --spirv-val \ -G -H spv.debugInfo.frag --rsb frag 3 > $TARGETDIR/spv.debugInfo.frag.out diff -b $BASEDIR/spv.debugInfo.frag.out $TARGETDIR/spv.debugInfo.frag.out || HASERROR=1 -$EXE -g -Od --target-env vulkan1.1 --relaxed-errors --suppress-warnings --aml --hlsl-offsets --nsf --spirv-val \ +$EXE -g -Od --target-env vulkan1.1 --relaxed-errors --suppress-warnings --aml --amb --hlsl-offsets --nsf --spirv-val \ -G -H spv.debugInfo.frag --rsb frag 3 > $TARGETDIR/spv.debugInfo.1.1.frag.out diff -b $BASEDIR/spv.debugInfo.1.1.frag.out $TARGETDIR/spv.debugInfo.1.1.frag.out || HASERROR=1 $EXE -g -D -Od -e newMain -g --amb --aml --fua --hlsl-iomap --nsf --spirv-val --sib 1 --ssb 2 --sbb 3 --stb 4 --suavb 5 --sub 6 \ diff --git a/Test/spv.hlslOffsets.vert b/Test/spv.hlslOffsets.vert index 87e32a72..26950d93 100644 --- a/Test/spv.hlslOffsets.vert +++ b/Test/spv.hlslOffsets.vert @@ -1,6 +1,6 @@ #version 450 -buffer block { +layout(binding = 0) buffer block { float m0; vec3 m4; ////// diff --git a/Test/vulkan.vert b/Test/vulkan.vert index 99456b9f..7142691a 100644 --- a/Test/vulkan.vert +++ b/Test/vulkan.vert @@ -21,8 +21,8 @@ void main() } layout(binding = 0) uniform atomic_uint aui; // ERROR, no atomics in Vulkan -layout(shared) uniform ub1n { int a; } ub1i; // ERROR, no shared -layout(packed) uniform ub2n { int a; } ub2i; // ERROR, no packed +layout(shared, binding = 1) uniform ub1n { int a; } ub1i; // ERROR, no shared +layout(packed, binding = 2) uniform ub2n { int a; } ub2i; // ERROR, no packed layout(constant_id=222) const int arraySize = 4; diff --git a/Test/web.array.frag b/Test/web.array.frag new file mode 100644 index 00000000..8b8acdf5 --- /dev/null +++ b/Test/web.array.frag @@ -0,0 +1,26 @@ +#version 310 es + +precision highp float; + +float g4[4]; +float g5[5]; + +layout(location = 0) out vec2 colorOut; + +float[4] foo(float a[5]) +{ + return float[](a[0], a[1], a[2], a[3]); +} + +void main() +{ + g4 = foo(g5); + + if (float[4](1.0, 2.0, 3.0, 4.0) == g4) + ; + + float u[5]; + foo(u); + + colorOut = vec2(g4.length(), g5.length()); +} diff --git a/Test/web.testlist b/Test/web.testlist index b2d14741..fba92127 100644 --- a/Test/web.testlist +++ b/Test/web.testlist @@ -4,3 +4,4 @@ web.basic.vert web.controlFlow.frag web.operations.frag web.texture.frag +web.array.frag diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index fa26c8cb..3720de7a 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -578,6 +578,8 @@ public: bool nonUniform : 1; #ifdef GLSLANG_WEB + bool isWriteOnly() const { return false; } + bool isReadOnly() const { return false; } bool isSample() const { return false; } bool isMemory() const { return false; } bool isMemoryQualifierImageAndSSBOOnly() const { return false; } @@ -599,6 +601,8 @@ public: bool perTaskNV : 1; bool patch : 1; bool sample : 1; + bool isWriteOnly() const { return writeonly; } + bool isReadOnly() const { return readonly; } bool isSample() const { return sample; } bool isMemory() const { @@ -1035,11 +1039,13 @@ public: static const char* getLayoutPackingString(TLayoutPacking packing) { switch (packing) { + case ElpStd140: return "std140"; +#ifndef GLSLANG_WEB case ElpPacked: return "packed"; case ElpShared: return "shared"; - case ElpStd140: return "std140"; case ElpStd430: return "std430"; case ElpScalar: return "scalar"; +#endif default: return "none"; } } @@ -1332,6 +1338,12 @@ public: TSourceLoc loc; TArraySizes* typeParameters; +#ifdef GLSLANG_WEB + bool isCoopmat() const { return false; } +#else + bool isCoopmat() const { return coopmat; } +#endif + void initType(const TSourceLoc& l) { basicType = EbtVoid; @@ -1435,7 +1447,7 @@ public: } typeName = NewPoolTString(p.userDef->getTypeName().c_str()); } - if (p.coopmat && p.basicType == EbtFloat && + if (p.isCoopmat() && p.basicType == EbtFloat && p.typeParameters && p.typeParameters->getNumDims() > 0 && p.typeParameters->getDimSize(0) == 16) { basicType = EbtFloat16; @@ -1544,7 +1556,7 @@ public: referentType = copyOf.referentType; } typeParameters = copyOf.typeParameters; - coopmat = copyOf.coopmat; + coopmat = copyOf.isCoopMat(); } // Make complete copy of the whole type graph rooted at 'copyOf'. @@ -1658,9 +1670,11 @@ public: virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); } virtual bool isParameterized() const { return typeParameters != nullptr; } #ifdef GLSLANG_WEB + bool isAtomic() const { return false; } bool isCoopMat() const { return false; } bool isReference() const { return false; } #else + bool isAtomic() const { return basicType == EbtAtomicUint; } bool isCoopMat() const { return coopmat; } bool isReference() const { return getBasicType() == EbtReference; } #endif @@ -2240,7 +2254,7 @@ public: return true; } - bool sameReferenceType(const TType& right) const + bool sameReferenceType(const TType& right) const { if (isReference() != right.isReference()) return false; @@ -2257,7 +2271,7 @@ public: return *referentType == *right.referentType; } - // See if two types match, in all aspects except arrayness + // See if two types match, in all aspects except arrayness bool sameElementType(const TType& right) const { return basicType == right.basicType && sameElementShape(right); @@ -2292,7 +2306,7 @@ public: matrixCols == right.matrixCols && matrixRows == right.matrixRows && vector1 == right.vector1 && - coopmat == right.coopmat && + isCoopMat() == right.isCoopMat() && sameStructType(right) && sameReferenceType(right); } @@ -2301,7 +2315,7 @@ public: // an OK function parameter bool coopMatParameterOK(const TType& right) const { - return coopmat && right.coopmat && + return isCoopMat() && right.isCoopMat() && typeParameters == nullptr && right.typeParameters != nullptr; } @@ -2316,19 +2330,16 @@ public: return ! operator==(right); } -#ifdef GLSLANG_WEB - unsigned int getBufferReferenceAlignment() const { return 0; } -#else unsigned int getBufferReferenceAlignment() const { +#ifndef GLSLANG_WEB if (getBasicType() == glslang::EbtReference) { return getReferentType()->getQualifier().hasBufferReferenceAlign() ? (1u << getReferentType()->getQualifier().layoutBufferReferenceAlign) : 16u; - } else { - return 0; } - } #endif + return 0; + } protected: // Require consumer to pick between deep copy and shallow copy. diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index f2a015ad..3a7405ad 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -1089,7 +1089,8 @@ public: virtual bool isStruct() const { return type.isStruct(); } virtual bool isFloatingDomain() const { return type.isFloatingDomain(); } virtual bool isIntegerDomain() const { return type.isIntegerDomain(); } - virtual bool isReference() const { return type.isReference(); } + bool isAtomic() const { return type.isAtomic(); } + bool isReference() const { return type.isReference(); } TString getCompleteString() const { return type.getCompleteString(); } protected: diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index 966040ba..93d41f7d 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -383,18 +383,20 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, TSo // TBasicType newType = EbtVoid; switch (op) { - case EOpConstructInt8: newType = EbtInt8; break; - case EOpConstructUint8: newType = EbtUint8; break; - case EOpConstructInt16: newType = EbtInt16; break; - case EOpConstructUint16: newType = EbtUint16; break; - case EOpConstructInt: newType = EbtInt; break; - case EOpConstructUint: newType = EbtUint; break; - case EOpConstructInt64: newType = EbtInt64; break; - case EOpConstructUint64: newType = EbtUint64; break; case EOpConstructBool: newType = EbtBool; break; case EOpConstructFloat: newType = EbtFloat; break; + case EOpConstructInt: newType = EbtInt; break; + case EOpConstructUint: newType = EbtUint; break; +#ifndef GLSLANG_WEB + case EOpConstructInt8: newType = EbtInt8; break; + case EOpConstructUint8: newType = EbtUint8; break; + case EOpConstructInt16: newType = EbtInt16; break; + case EOpConstructUint16: newType = EbtUint16; break; + case EOpConstructInt64: newType = EbtInt64; break; + case EOpConstructUint64: newType = EbtUint64; break; case EOpConstructDouble: newType = EbtDouble; break; case EOpConstructFloat16: newType = EbtFloat16; break; +#endif default: break; // some compilers want this } @@ -1562,6 +1564,17 @@ bool TIntermediate::isFPConversion(TBasicType from, TBasicType to) const bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const { switch (from) { + case EbtInt: + case EbtUint: + switch(to) { + case EbtFloat: + case EbtDouble: + return true; + default: + break; + } + break; +#ifndef GLSLANG_WEB case EbtInt8: case EbtUint8: case EbtInt16: @@ -1575,23 +1588,13 @@ bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const break; } break; - case EbtInt: - case EbtUint: - switch(to) { - case EbtFloat: - case EbtDouble: - return true; - default: - break; - } - break; case EbtInt64: case EbtUint64: if (to == EbtDouble) { return true; } break; - +#endif default: break; } @@ -1709,7 +1712,7 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat case EbtFloat: return true; case EbtBool: - return (getSource() == EShSourceHlsl); + return getSource() == EShSourceHlsl; case EbtInt16: case EbtUint16: return extensionRequested(E_GL_AMD_gpu_shader_int16); diff --git a/glslang/MachineIndependent/ParseContextBase.cpp b/glslang/MachineIndependent/ParseContextBase.cpp index ccf010e3..282ecca0 100644 --- a/glslang/MachineIndependent/ParseContextBase.cpp +++ b/glslang/MachineIndependent/ParseContextBase.cpp @@ -155,7 +155,7 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, case EvqUniform: message = "can't modify a uniform"; break; #ifndef GLSLANG_WEB case EvqBuffer: - if (node->getQualifier().readonly) + if (node->getQualifier().isReadOnly()) message = "can't modify a readonly buffer"; if (node->getQualifier().isShaderRecordNV()) message = "can't modify a shaderrecordnv qualified buffer"; @@ -236,7 +236,7 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op, } TIntermSymbol* symNode = node->getAsSymbolNode(); - if (symNode && symNode->getQualifier().writeonly) + if (symNode && symNode->getQualifier().isWriteOnly()) error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str()); } diff --git a/glslang/MachineIndependent/ParseHelper.cpp b/glslang/MachineIndependent/ParseHelper.cpp index 1db615a2..9e19b279 100644 --- a/glslang/MachineIndependent/ParseHelper.cpp +++ b/glslang/MachineIndependent/ParseHelper.cpp @@ -56,8 +56,11 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b infoSink, forwardCompatible, messages, entryPoint), inMain(false), blockName(nullptr), - limits(resources.limits), + limits(resources.limits) +#ifndef GLSLANG_WEB + , atomicUintOffsets(nullptr), anyIndexLimits(false) +#endif { // decide whether precision qualifiers should be ignored or respected if (isEsProfile() || spvVersion.vulkan > 0) { @@ -103,7 +106,9 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b TParseContext::~TParseContext() { +#ifndef GLSLANG_WEB delete [] atomicUintOffsets; +#endif } // Set up all default precisions as needed by the current environment. @@ -855,8 +860,8 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm } } else if (base->isStruct() || base->isReference()) { const TTypeList* fields = base->isReference() ? - base->getType().getReferentType()->getStruct() : - base->getType().getStruct(); + base->getType().getReferentType()->getStruct() : + base->getType().getStruct(); bool fieldFound = false; int member; for (member = 0; member < (int)fields->size(); ++member) { @@ -1089,12 +1094,9 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction { TIntermTyped* result = nullptr; -#ifndef GLSLANG_WEB if (function->getBuiltInOp() == EOpArrayLength) result = handleLengthMethod(loc, function, arguments); - else -#endif - if (function->getBuiltInOp() != EOpNull) { + else if (function->getBuiltInOp() != EOpNull) { // // Then this should be a constructor. // Don't go through the symbol table for constructors. @@ -1147,7 +1149,6 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", ""); } TQualifier& argQualifier = arg->getAsTyped()->getQualifier(); -#ifndef GLSLANG_WEB if (argQualifier.isMemory()) { const char* message = "argument cannot drop memory qualifier when passed to formal parameter"; if (argQualifier.volatil && ! formalQualifier.volatil) @@ -1173,11 +1174,10 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction if (!builtIn && argQualifier.getFormat() != formalQualifier.getFormat()) { // we have mismatched formats, which should only be allowed if writeonly // and at least one format is unknown - if (!formalQualifier.writeonly || (formalQualifier.getFormat() != ElfNone && - argQualifier.getFormat() != ElfNone)) + if (!formalQualifier.isWriteOnly() || (formalQualifier.getFormat() != ElfNone && + argQualifier.getFormat() != ElfNone)) error(arguments->getLoc(), "image formats must match", "format", ""); } -#endif if (builtIn && arg->getAsTyped()->getType().contains16BitFloat()) requireFloat16Arithmetic(arguments->getLoc(), "built-in function", "float16 types can only be in uniform block or buffer storage"); if (builtIn && arg->getAsTyped()->getType().contains16BitInt()) @@ -1457,8 +1457,6 @@ void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op) #endif } -#ifndef GLSLANG_WEB - // Finish processing object.length(). This started earlier in handleDotDereference(), where // the ".length" part was recognized and semantically checked, and finished here where the // function syntax "()" is recognized. @@ -1474,6 +1472,7 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction const TType& type = intermNode->getAsTyped()->getType(); if (type.isArray()) { if (type.isUnsizedArray()) { +#ifndef GLSLANG_WEB if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) { // We could be between a layout declaration that gives a built-in io array implicit size and // a user redeclaration of that array, meaning we have to substitute its implicit size here @@ -1485,13 +1484,16 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction length = getIoArrayImplicitSize(type.getQualifier()); } } +#endif if (length == 0) { +#ifndef GLSLANG_WEB if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) error(loc, "", function->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier"); else if (isRuntimeLength(*intermNode->getAsTyped())) { // Create a unary op and let the back end handle it return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt)); } else +#endif error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method"); } } else if (type.getOuterArrayNode()) { @@ -1519,8 +1521,6 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction return intermediate.addConstantUnion(length, loc); } -#endif - // // Add any needed implicit conversions for function-call arguments to input parameters. // @@ -1804,7 +1804,6 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& } } - // // Do additional checking of built-in function calls that is not caught // by normal semantic checks on argument type, extension tagging, etc. @@ -2583,12 +2582,10 @@ void TParseContext::rValueErrorCheck(const TSourceLoc& loc, const char* op, TInt // Let the base class check errors TParseContextBase::rValueErrorCheck(loc, op, node); -#ifndef GLSLANG_WEB TIntermSymbol* symNode = node->getAsSymbolNode(); - if (!(symNode && symNode->getQualifier().writeonly)) // base class checks - if (symNode && symNode->getQualifier().explicitInterp) + if (!(symNode && symNode->getQualifier().isWriteOnly())) // base class checks + if (symNode && symNode->getQualifier().isExplicitInterpolation()) error(loc, "can't read from explicitly-interpolated object: ", op, symNode->getName().c_str()); -#endif } // @@ -3035,7 +3032,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T error(loc, "cannot convert a sampler", "constructor", ""); return true; } - if (op != EOpConstructStruct && typed->getBasicType() == EbtAtomicUint) { + if (op != EOpConstructStruct && typed->isAtomic()) { error(loc, "cannot convert an atomic_uint", "constructor", ""); return true; } @@ -3529,14 +3526,12 @@ void TParseContext::setDefaultPrecision(const TSourceLoc& loc, TPublicType& publ } } -#ifndef GLSLANG_WEB if (basicType == EbtAtomicUint) { if (qualifier != EpqHigh) error(loc, "can only apply highp to atomic_uint", "precision", ""); return; } -#endif error(loc, "cannot apply precision statement to this type; use 'float', 'int' or a sampler type", TType::getBasicString(basicType), ""); } @@ -3573,8 +3568,10 @@ void TParseContext::precisionQualifierCheck(const TSourceLoc& loc, TBasicType ba if (! obeyPrecisionQualifiers() || parsingBuiltins) return; +#ifndef GLSLANG_WEB if (baseType == EbtAtomicUint && qualifier.precision != EpqNone && qualifier.precision != EpqHigh) error(loc, "atomic counters can only be highp", "atomic_uint", ""); +#endif if (baseType == EbtFloat || baseType == EbtUint || baseType == EbtInt || baseType == EbtSampler || baseType == EbtAtomicUint) { if (qualifier.precision == EpqNone) { @@ -3756,16 +3753,15 @@ void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qua (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal && qualifier.storage != EvqShared && qualifier.storage != EvqConst)) error(loc, "only outermost dimension of an array of arrays can be a specialization constant", "[]", ""); - // desktop always allows outer-dimension-unsized variable arrays, +#ifndef GLSLANG_WEB + // desktop always allows outer-dimension-unsized variable arrays, if (!isEsProfile()) return; // for ES, if size isn't coming from an initializer, it has to be explicitly declared now, // with very few exceptions -#ifndef GLSLANG_WEB - // last member of ssbo block exception: if (qualifier.storage == EvqBuffer && lastMember) return; @@ -3780,13 +3776,13 @@ void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qua break; case EShLangTessControl: if ( qualifier.storage == EvqVaryingIn || - (qualifier.storage == EvqVaryingOut && ! qualifier.patch)) + (qualifier.storage == EvqVaryingOut && ! qualifier.isPatch())) if ((isEsProfile() && version >= 320) || extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader)) return; break; case EShLangTessEvaluation: - if ((qualifier.storage == EvqVaryingIn && ! qualifier.patch) || + if ((qualifier.storage == EvqVaryingIn && ! qualifier.isPatch()) || qualifier.storage == EvqVaryingOut) if ((isEsProfile() && version >= 320) || extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader)) @@ -4491,12 +4487,15 @@ void TParseContext::opaqueCheck(const TSourceLoc& loc, const TType& type, const void TParseContext::referenceCheck(const TSourceLoc& loc, const TType& type, const char* op) { +#ifndef GLSLANG_WEB if (containsFieldWithBasicType(type, EbtReference)) error(loc, "can't use with reference types", op, ""); +#endif } void TParseContext::storage16BitAssignmentCheck(const TSourceLoc& loc, const TType& type, const char* op) { +#ifndef GLSLANG_WEB if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtFloat16)) requireFloat16Arithmetic(loc, op, "can't use with structs containing float16"); @@ -4526,6 +4525,7 @@ void TParseContext::storage16BitAssignmentCheck(const TSourceLoc& loc, const TTy if (type.isArray() && type.getBasicType() == EbtUint8) requireInt8Arithmetic(loc, op, "can't use with arrays containing uint8"); +#endif } void TParseContext::specializationCheck(const TSourceLoc& loc, const TType& type, const char* op) @@ -5117,8 +5117,10 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "needs a literal integer", "set", ""); return; } else if (id == "binding") { +#ifndef GLSLANG_WEB profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, "binding"); profileRequires(loc, EEsProfile, 310, nullptr, "binding"); +#endif if ((unsigned int)value >= TQualifier::layoutBindingEnd) error(loc, "binding is too large", id.c_str(), ""); else @@ -5517,7 +5519,7 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb if (qualifier.hasPacking()) error(loc, "cannot specify packing on a variable declaration", "layout", ""); // "The offset qualifier can only be used on block members of blocks..." - if (qualifier.hasOffset() && type.getBasicType() != EbtAtomicUint) + if (qualifier.hasOffset() && !type.isAtomic()) error(loc, "cannot specify on a variable declaration", "offset", ""); // "The align qualifier can only be used on blocks or block members..." if (qualifier.hasAlign()) @@ -5675,32 +5677,30 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) } } } +#ifndef GLSLANG_WEB if (spvVersion.vulkan == 0 && lastBinding >= resources.maxCombinedTextureImageUnits) error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : ""); +#endif } -#ifndef GLSLANG_WEB - if (type.getBasicType() == EbtAtomicUint) { + if (type.isAtomic()) { if (qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) { error(loc, "atomic_uint binding is too large; see gl_MaxAtomicCounterBindings", "binding", ""); return; } } -#endif } else if (!intermediate.getAutoMapBindings()) { // some types require bindings -#ifndef GLSLANG_WEB // atomic_uint - if (type.getBasicType() == EbtAtomicUint) + if (type.isAtomic()) error(loc, "layout(binding=X) is required", "atomic_uint", ""); -#endif // SPIR-V if (spvVersion.spv > 0) { if (qualifier.isUniformOrBuffer()) { if (type.getBasicType() == EbtBlock && !qualifier.isPushConstant() && !qualifier.isShaderRecordNV() && - !qualifier.layoutAttachment && + !qualifier.hasAttachment() && !qualifier.hasBufferReference()) error(loc, "uniform/buffer blocks require layout(binding=X)", "binding", ""); else if (spvVersion.vulkan > 0 && type.getBasicType() == EbtSampler) @@ -5739,12 +5739,12 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) // "Except for image variables qualified with the format qualifiers r32f, r32i, and r32ui, image variables must // specify either memory qualifier readonly or the memory qualifier writeonly." if (! (qualifier.getFormat() == ElfR32f || qualifier.getFormat() == ElfR32i || qualifier.getFormat() == ElfR32ui)) { - if (! qualifier.readonly && ! qualifier.writeonly) + if (! qualifier.isReadOnly() && ! qualifier.isWriteOnly()) error(loc, "format requires readonly or writeonly memory qualifier", TQualifier::getLayoutFormatString(qualifier.getFormat()), ""); } } } - } else if (type.isImage() && ! qualifier.writeonly) { + } else if (type.isImage() && ! qualifier.isWriteOnly()) { const char *explanation = "image variables not declared 'writeonly' and without a format layout qualifier"; requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation); @@ -5966,9 +5966,9 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua // Correct and/or advance an object's offset layout qualifier. void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol) { -#ifndef GLSLANG_WEB const TQualifier& qualifier = symbol.getType().getQualifier(); - if (symbol.getType().getBasicType() == EbtAtomicUint) { +#ifndef GLSLANG_WEB + if (symbol.getType().isAtomic()) { if (qualifier.hasBinding() && (int)qualifier.layoutBinding < resources.maxAtomicCounterBindings) { // Set the offset @@ -6545,7 +6545,9 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp TType skeletalType; skeletalType.shallowCopy(variable->getType()); skeletalType.getQualifier().makeTemporary(); +#ifndef GLSLANG_WEB initializer = convertInitializerList(loc, skeletalType, initializer); +#endif if (! initializer) { // error recovery; don't leave const without constant values if (qualifier == EvqConst) @@ -7420,7 +7422,6 @@ 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"); @@ -7434,8 +7435,7 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q EShLangFragmentMask|EShLangMeshNVMask), "input block"); if (language == EShLangFragment) { profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block"); - } - else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) { + } else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) { error(loc, "input blocks cannot be used in a mesh shader", "out", ""); } break; @@ -7446,14 +7446,13 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q // ES 310 can have a block before shader_io is turned on, so skip this test for built-ins if (language == EShLangVertex && ! parsingBuiltins) { profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "vertex output block"); - } - else if (language == EShLangMeshNV && qualifier.isTaskMemory()) { + } else if (language == EShLangMeshNV && qualifier.isTaskMemory()) { error(loc, "can only use on input blocks in mesh shader", "taskNV", ""); - } - else if (language == EShLangTaskNV && ! qualifier.isTaskMemory()) { + } else if (language == EShLangTaskNV && ! qualifier.isTaskMemory()) { 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/ParseHelper.h b/glslang/MachineIndependent/ParseHelper.h index 9e74a696..1f63e84d 100644 --- a/glslang/MachineIndependent/ParseHelper.h +++ b/glslang/MachineIndependent/ParseHelper.h @@ -476,10 +476,11 @@ protected: TQualifier globalUniformDefaults; TQualifier globalInputDefaults; TQualifier globalOutputDefaults; - int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point TString currentCaller; // name of last function body entered (not valid when at global scope) - TIdSetType inductiveLoopIds; +#ifndef GLSLANG_WEB + int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point bool anyIndexLimits; + TIdSetType inductiveLoopIds; TVector needsIndexLimitationChecking; // @@ -515,6 +516,7 @@ protected: // array-sizing declarations // TVector ioArraySymbolResizeList; +#endif }; } // end namespace glslang diff --git a/glslang/MachineIndependent/Scan.cpp b/glslang/MachineIndependent/Scan.cpp index ad0c12c9..b4d8dc0d 100644 --- a/glslang/MachineIndependent/Scan.cpp +++ b/glslang/MachineIndependent/Scan.cpp @@ -324,7 +324,9 @@ struct str_hash // A single global usable by all threads, by all versions, by all languages. // After a single process-level initialization, this is read only and thread safe std::unordered_map* KeywordMap = nullptr; +#ifndef GLSLANG_WEB std::unordered_set* ReservedSet = nullptr; +#endif }; @@ -758,8 +760,10 @@ void TScanContext::deleteKeywordMap() { delete KeywordMap; KeywordMap = nullptr; +#ifndef GLSLANG_WEB delete ReservedSet; ReservedSet = nullptr; +#endif } // Called by yylex to get the next token. @@ -1051,6 +1055,11 @@ int TScanContext::tokenizeIdentifier() case SUBROUTINE: return es30ReservedFromGLSL(400); + case SHARED: + if ((parseContext.isEsProfile() && parseContext.version < 300) || + (!parseContext.isEsProfile() && parseContext.version < 140)) + return identifierOrType(); + return keyword; #endif case LAYOUT: @@ -1064,11 +1073,6 @@ int TScanContext::tokenizeIdentifier() return identifierOrType(); return keyword; } - case SHARED: - if ((parseContext.isEsProfile() && parseContext.version < 300) || - (!parseContext.isEsProfile() && parseContext.version < 140)) - return identifierOrType(); - return keyword; case HIGH_PRECISION: case MEDIUM_PRECISION: @@ -1649,7 +1653,7 @@ int TScanContext::identifierOrReserved(bool reserved) return 0; } - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future reserved keyword", tokenText, ""); return identifierOrType(); @@ -1664,7 +1668,7 @@ int TScanContext::es30ReservedFromGLSL(int version) if ((parseContext.isEsProfile() && parseContext.version < 300) || (!parseContext.isEsProfile() && parseContext.version < version)) { - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "future reserved word in ES 300 and keyword in GLSL", tokenText, ""); return identifierOrType(); @@ -1680,7 +1684,7 @@ int TScanContext::nonreservedKeyword(int esVersion, int nonEsVersion) { if ((parseContext.isEsProfile() && parseContext.version < esVersion) || (!parseContext.isEsProfile() && parseContext.version < nonEsVersion)) { - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future keyword", tokenText, ""); return identifierOrType(); @@ -1694,7 +1698,7 @@ int TScanContext::precisionKeyword() if (parseContext.isEsProfile() || parseContext.version >= 130) return keyword; - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using ES precision qualifier keyword", tokenText, ""); return identifierOrType(); @@ -1707,7 +1711,7 @@ int TScanContext::matNxM() if (parseContext.version > 110) return keyword; - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future non-square matrix type keyword", tokenText, ""); return identifierOrType(); @@ -1726,7 +1730,7 @@ int TScanContext::dMat() if (!parseContext.isEsProfile() && parseContext.version >= 400) return keyword; - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future type keyword", tokenText, ""); return identifierOrType(); @@ -1747,7 +1751,7 @@ int TScanContext::firstGenerationImage(bool inEs310) return keyword; } - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future type keyword", tokenText, ""); return identifierOrType(); @@ -1765,7 +1769,7 @@ int TScanContext::secondGenerationImage() (parseContext.version >= 420 || parseContext.extensionTurnedOn(E_GL_ARB_shader_image_load_store)))) return keyword; - if (parseContext.forwardCompatible) + if (parseContext.isForwardCompatible()) parseContext.warn(loc, "using future type keyword", tokenText, ""); return identifierOrType(); diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index bced5d72..a51c0c4c 100755 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -477,11 +477,13 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp // Function to Print all builtins void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable) { +#ifndef GLSLANG_WEB infoSink.debug << "BuiltinSymbolTable {\n"; symbolTable.dump(infoSink, true); infoSink.debug << "}\n"; +#endif } // Return true if the shader was correctly specified for version/profile/stage. @@ -634,7 +636,6 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo default: break; } -#endif if (profile == EEsProfile && version >= 300 && versionNotFirst) { correct = false; @@ -644,7 +645,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo // Check for SPIR-V compatibility if (spvVersion.spv != 0) { switch (profile) { - case EEsProfile: + case EEsProfile: if (spvVersion.vulkan > 0 && version < 310) { correct = false; infoSink.info.message(EPrefixError, "#version: ES shaders for Vulkan SPIR-V require version 310 or higher"); @@ -673,6 +674,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo break; } } +#endif return correct; } @@ -854,6 +856,7 @@ bool ProcessDeferred( : userInput.scanVersion(version, profile, versionNotFirstToken); bool versionNotFound = version == 0; if (forceDefaultVersionAndProfile && source == EShSourceGlsl) { +#ifndef GLSLANG_WEB if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound && (version != defaultVersion || profile != defaultProfile)) { compiler->infoSink.info << "Warning, (version, profile) forced to be (" @@ -861,7 +864,7 @@ bool ProcessDeferred( << "), while in source code it is (" << version << ", " << ProfileName(profile) << ")\n"; } - +#endif if (versionNotFound) { versionNotFirstToken = false; versionNotFirst = false; @@ -874,6 +877,7 @@ bool ProcessDeferred( bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage, versionNotFirst, defaultVersion, source, version, profile, spvVersion); bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst)); +#ifndef GLSLANG_WEB bool warnVersionNotFirst = false; if (! versionWillBeError && versionNotFirstToken) { if (messages & EShMsgRelaxedErrors) @@ -881,6 +885,7 @@ bool ProcessDeferred( else versionWillBeError = true; } +#endif intermediate.setSource(source); intermediate.setVersion(version); @@ -942,11 +947,13 @@ bool ProcessDeferred( parseContext->setLimits(*resources); if (! goodVersion) parseContext->addError(); +#ifndef GLSLANG_WEB if (warnVersionNotFirst) { TSourceLoc loc; loc.init(); parseContext->warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", ""); } +#endif parseContext->initializeExtensionBehavior(); @@ -977,6 +984,8 @@ bool ProcessDeferred( return success; } +#ifndef GLSLANG_WEB + // Responsible for keeping track of the most recent source string and line in // the preprocessor and outputting newlines appropriately if the source string // or line changes. @@ -1173,6 +1182,8 @@ struct DoPreprocessing { std::string* outputString; }; +#endif + // DoFullParse is a valid ProcessingConext template argument for fully // parsing the shader. It populates the "intermediate" with the AST. struct DoFullParse{ @@ -1203,6 +1214,7 @@ struct DoFullParse{ } }; +#ifndef GLSLANG_WEB // Take a single compilation unit, and run the preprocessor on it. // Return: True if there were no issues found in preprocessing, // False if during preprocessing any unknown version, pragmas or @@ -1235,6 +1247,7 @@ bool PreprocessDeferred( forwardCompatible, messages, intermediate, parser, false, includer); } +#endif // // do a partial compile on the given strings for a single compilation unit @@ -1829,6 +1842,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion &environment); } +#ifndef GLSLANG_WEB // Fill in a string with the result of preprocessing ShaderStrings // Returns true if all extensions, pragmas and version strings were valid. // @@ -1853,6 +1867,7 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources, defaultProfile, forceDefaultVersionAndProfile, forwardCompatible, message, includer, *intermediate, output_string); } +#endif const char* TShader::getInfoLog() { @@ -1928,6 +1943,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) if (stages[stage].size() == 0) return true; +#ifndef GLSLANG_WEB int numEsShaders = 0, numNonEsShaders = 0; for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) { if ((*it)->intermediate->getProfile() == EEsProfile) { @@ -1976,7 +1992,9 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) for (it = stages[stage].begin(); it != stages[stage].end(); ++it) intermediate[stage]->merge(*infoSink, *(*it)->intermediate); } - +#else + intermediate[stage] = stages[stage].front()->intermediate; +#endif intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0); if (messages & EShMsgAST) diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp index 2f72a364..2ea14af2 100755 --- a/glslang/MachineIndependent/SymbolTable.cpp +++ b/glslang/MachineIndependent/SymbolTable.cpp @@ -174,6 +174,8 @@ void TType::buildMangledName(TString& mangledName) const } } +#ifndef GLSLANG_WEB + // // Dump functions. // @@ -252,6 +254,8 @@ void TSymbolTable::dump(TInfoSink& infoSink, bool complete) const } } +#endif + // // Functions have buried pointers to delete. // diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h index f3873cff..40ca3da5 100755 --- a/glslang/MachineIndependent/SymbolTable.h +++ b/glslang/MachineIndependent/SymbolTable.h @@ -116,8 +116,11 @@ public: } virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); } virtual const char** getExtensions() const { return extensions->data(); } + +#ifndef GLSLANG_WEB virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0; void dumpExtensions(TInfoSink& infoSink) const; +#endif virtual bool isReadOnly() const { return ! writable; } virtual void makeReadOnly() { writable = false; } @@ -193,7 +196,9 @@ public: } virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); } +#ifndef GLSLANG_WEB virtual void dump(TInfoSink& infoSink, bool complete = false) const; +#endif protected: explicit TVariable(const TVariable&); @@ -314,7 +319,9 @@ public: virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; } virtual const TParameter& operator[](int i) const { return parameters[i]; } +#ifndef GLSLANG_WEB virtual void dump(TInfoSink& infoSink, bool complete = false) const override; +#endif protected: explicit TFunction(const TFunction&); @@ -374,7 +381,9 @@ public: virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); } virtual int getAnonId() const { return anonId; } +#ifndef GLSLANG_WEB virtual void dump(TInfoSink& infoSink, bool complete = false) const override; +#endif protected: explicit TAnonMember(const TAnonMember&); @@ -542,7 +551,9 @@ public: void relateToOperator(const char* name, TOperator op); void setFunctionExtensions(const char* name, int num, const char* const extensions[]); +#ifndef GLSLANG_WEB void dump(TInfoSink& infoSink, bool complete = false) const; +#endif TSymbolTableLevel* clone() const; void readOnly(); @@ -843,7 +854,9 @@ public: } int getMaxSymbolId() { return uniqueId; } +#ifndef GLSLANG_WEB void dump(TInfoSink& infoSink, bool complete = false) const; +#endif void copyTable(const TSymbolTable& copyOf); void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); } diff --git a/glslang/MachineIndependent/Versions.cpp b/glslang/MachineIndependent/Versions.cpp index f6592185..e96a9529 100644 --- a/glslang/MachineIndependent/Versions.cpp +++ b/glslang/MachineIndependent/Versions.cpp @@ -502,21 +502,6 @@ void TParseVersions::getPreamble(std::string& preamble) #endif } -// -// When to use requireProfile(): -// -// Use if only some profiles support a feature. However, if within a profile the feature -// is version or extension specific, follow this call with calls to profileRequires(). -// -// Operation: If the current profile is not one of the profileMask, -// give an error message. -// -void TParseVersions::requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc) -{ - if (! (profile & profileMask)) - error(loc, "not supported with this profile:", featureDesc, ProfileName(profile)); -} - // // Map from stage enum to externally readable text name. // @@ -543,6 +528,42 @@ const char* StageName(EShLanguage stage) } } +// +// When to use requireStage() +// +// If only some stages support a feature. +// +// Operation: If the current stage is not present, give an error message. +// +void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguageMask languageMask, const char* featureDesc) +{ + if (((1 << language) & languageMask) == 0) + error(loc, "not supported in this stage:", featureDesc, StageName(language)); +} + +// If only one stage supports a feature, this can be called. But, all supporting stages +// must be specified with one call. +void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguage stage, const char* featureDesc) +{ + requireStage(loc, static_cast(1 << stage), featureDesc); +} + +#ifndef GLSLANG_WEB +// +// When to use requireProfile(): +// +// Use if only some profiles support a feature. However, if within a profile the feature +// is version or extension specific, follow this call with calls to profileRequires(). +// +// Operation: If the current profile is not one of the profileMask, +// give an error message. +// +void TParseVersions::requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc) +{ + if (! (profile & profileMask)) + error(loc, "not supported with this profile:", featureDesc, ProfileName(profile)); +} + // // When to use profileRequires(): // @@ -560,7 +581,8 @@ const char* StageName(EShLanguage stage) // // entry point that takes multiple extensions -void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc) +void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, + const char* const extensions[], const char* featureDesc) { if (profile & profileMask) { bool okay = minVersion > 0 && version >= minVersion; @@ -584,33 +606,12 @@ void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int } // entry point for the above that takes a single extension -void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, const char* featureDesc) +void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, + const char* featureDesc) { profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc); } -// -// When to use requireStage() -// -// If only some stages support a feature. -// -// Operation: If the current stage is not present, give an error message. -// -void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguageMask languageMask, const char* featureDesc) -{ - if (((1 << language) & languageMask) == 0) - error(loc, "not supported in this stage:", featureDesc, StageName(language)); -} - -// If only one stage supports a feature, this can be called. But, all supporting stages -// must be specified with one call. -void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguage stage, const char* featureDesc) -{ - requireStage(loc, static_cast(1 << stage), featureDesc); -} - -#ifndef GLSLANG_WEB - void TParseVersions::unimplemented(const TSourceLoc& loc, const char* featureDesc) { error(loc, "feature not yet implemented", featureDesc, ""); @@ -1106,15 +1107,19 @@ void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op) // Call for any operation that requires Vulkan. void TParseVersions::requireVulkan(const TSourceLoc& loc, const char* op) { +#ifndef GLSLANG_WEB if (spvVersion.vulkan == 0) error(loc, "only allowed when using GLSL for Vulkan", op, ""); +#endif } // Call for any operation that requires SPIR-V. void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op) { +#ifndef GLSLANG_WEB if (spvVersion.spv == 0) error(loc, "only allowed when generating SPIR-V", op, ""); +#endif } } // end namespace glslang diff --git a/glslang/MachineIndependent/iomapper.cpp b/glslang/MachineIndependent/iomapper.cpp index 8a6ea3c6..26b830e4 100644 --- a/glslang/MachineIndependent/iomapper.cpp +++ b/glslang/MachineIndependent/iomapper.cpp @@ -477,7 +477,7 @@ int TDefaultIoResolverBase::resolveUniformLocation(EShLanguage /*stage*/, TVarEn } // no locations added if already present, a built-in variable, a block, or an opaque if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock || - type.getBasicType() == EbtAtomicUint || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) { + type.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) { return ent.newLocation = -1; } // no locations on blocks of built-in variables @@ -674,7 +674,7 @@ int TDefaultGlslIoResolver::resolveUniformLocation(EShLanguage /*stage*/, TVarEn } else { // no locations added if already present, a built-in variable, a block, or an opaque if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getBasicType() == EbtBlock || - type.getBasicType() == EbtAtomicUint || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) { + type.isAtomic() || (type.containsOpaque() && intermediate.getSpv().openGl == 0)) { return ent.newLocation = -1; } // no locations on blocks of built-in variables diff --git a/glslang/MachineIndependent/iomapper.h b/glslang/MachineIndependent/iomapper.h index a95238bb..01afc5a2 100644 --- a/glslang/MachineIndependent/iomapper.h +++ b/glslang/MachineIndependent/iomapper.h @@ -178,7 +178,7 @@ protected: // Return true if this is a UAV (unordered access view) type: static bool isUavType(const glslang::TType& type) { - if (type.getQualifier().readonly) + if (type.getQualifier().isReadOnly()) return false; return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) || (type.getQualifier().storage == EvqBuffer); diff --git a/glslang/MachineIndependent/limits.cpp b/glslang/MachineIndependent/limits.cpp index 64d191b4..51d93003 100644 --- a/glslang/MachineIndependent/limits.cpp +++ b/glslang/MachineIndependent/limits.cpp @@ -187,12 +187,14 @@ bool TIndexTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) // void TParseContext::constantIndexExpressionCheck(TIntermNode* index) { +#ifndef GLSLANG_WEB TIndexTraverser it(inductiveLoopIds); index->traverse(&it); if (it.bad) error(it.badLoc, "Non-constant-index-expression", "limitations", ""); +#endif } } // end namespace glslang diff --git a/glslang/MachineIndependent/linkValidate.cpp b/glslang/MachineIndependent/linkValidate.cpp index 45f45091..5b920f2d 100644 --- a/glslang/MachineIndependent/linkValidate.cpp +++ b/glslang/MachineIndependent/linkValidate.cpp @@ -89,8 +89,6 @@ void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) #endif } -#ifndef GLSLANG_WEB - void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit) { if (unit.getNumEntryPoints() > 0) { @@ -106,6 +104,8 @@ void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit) callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end()); } +#ifndef GLSLANG_WEB + #define MERGE_MAX(member) member = std::max(member, unit.member) #define MERGE_TRUE(member) if (unit.member) member = unit.member; @@ -307,6 +307,8 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit) ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end()); } +#endif + // Traverser that seeds an ID map with all built-ins, and tracks the // maximum ID used. // (It would be nice to put this in a function, but that causes warnings @@ -485,7 +487,6 @@ void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType) for (int i = 0; i < (int)type.getStruct()->size(); ++i) mergeImplicitArraySizes(*(*type.getStruct())[i].type, *(*unitType.getStruct())[i].type); } -#endif // not GLSLANG_WEB // // Compare two global objects from two compilation units and see if they match @@ -1258,6 +1259,7 @@ int TIntermediate::computeTypeUniformLocationSize(const TType& type) } #ifndef GLSLANG_WEB + // Accumulate xfb buffer ranges and check for collisions as the accumulation is done. // // Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value. @@ -1374,7 +1376,8 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains return 4 * numComponents; } } -#endif // not GLSLANG_WEB + +#endif const int baseAlignmentVec4Std140 = 16; diff --git a/glslang/MachineIndependent/parseVersions.h b/glslang/MachineIndependent/parseVersions.h index ea34f415..bed64743 100755 --- a/glslang/MachineIndependent/parseVersions.h +++ b/glslang/MachineIndependent/parseVersions.h @@ -57,17 +57,37 @@ public: TParseVersions(TIntermediate& interm, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) - : infoSink(infoSink), version(version), profile(profile), language(language), - spvVersion(spvVersion), forwardCompatible(forwardCompatible), - intermediate(interm), messages(messages), numErrors(0), currentScanner(0) { } + : +#ifndef GLSLANG_WEB + forwardCompatible(forwardCompatible), + profile(profile), +#endif + infoSink(infoSink), version(version), + language(language), + spvVersion(spvVersion), + intermediate(interm), messages(messages), numErrors(0), currentScanner(0) { } virtual ~TParseVersions() { } - virtual void requireProfile(const TSourceLoc&, int queryProfiles, const char* featureDesc); - virtual void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, int numExtensions, const char* const extensions[], const char* featureDesc); - virtual void profileRequires(const TSourceLoc&, int queryProfiles, int minVersion, const char* const extension, const char* featureDesc); - virtual void requireStage(const TSourceLoc&, EShLanguageMask, const char* featureDesc); - virtual void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc); + void requireStage(const TSourceLoc&, EShLanguageMask, const char* featureDesc); + void requireStage(const TSourceLoc&, EShLanguage, const char* featureDesc); #ifdef GLSLANG_WEB + const EProfile profile = EEsProfile; bool isEsProfile() const { return true; } + void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc) + { + if (! (EEsProfile & profileMask)) + error(loc, "not supported with this profile:", featureDesc, ProfileName(profile)); + } + void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, + const char* const extensions[], const char* featureDesc) + { + if ((EEsProfile & profileMask) && (minVersion == 0 || version < minVersion)) + error(loc, "not supported for this version or the enabled extensions", featureDesc, ""); + } + void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, + const char* featureDesc) + { + profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc); + } void initializeExtensionBehavior() { } void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc) { } void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc) { } @@ -92,8 +112,18 @@ public: void int64Check(const TSourceLoc&, const char* op, bool builtIn = false) { } void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false) { } void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false) { } + bool relaxedErrors() const { return false; } + bool suppressWarnings() const { return true; } + bool isForwardCompatible() const { return false; } #else + bool forwardCompatible; // true if errors are to be given for use of deprecated features + EProfile profile; // the declared profile in the shader (core by default) bool isEsProfile() const { return profile == EEsProfile; } + void requireProfile(const TSourceLoc& loc, int profileMask, const char* featureDesc); + void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, int numExtensions, + const char* const extensions[], const char* featureDesc); + void profileRequires(const TSourceLoc& loc, int profileMask, int minVersion, const char* extension, + const char* featureDesc); virtual void initializeExtensionBehavior(); virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc); virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc); @@ -131,6 +161,9 @@ public: virtual void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false); virtual void explicitFloat64Check(const TSourceLoc&, const char* op, bool builtIn = false); virtual void fcoopmatCheck(const TSourceLoc&, const char* op, bool builtIn = false); + bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; } + bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; } + bool isForwardCompatible() const { return forwardCompatible; } #endif // GLSLANG_WEB virtual void spvRemoved(const TSourceLoc&, const char* op); virtual void vulkanRemoved(const TSourceLoc&, const char* op); @@ -170,8 +203,6 @@ public: void setCurrentString(int string) { currentScanner->setString(string); } void getPreamble(std::string&); - bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; } - bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; } #ifdef ENABLE_HLSL bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; } bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; } @@ -184,10 +215,8 @@ public: // compilation mode int version; // version, updated by #version in the shader - EProfile profile; // the declared profile in the shader (core by default) EShLanguage language; // really the stage SpvVersion spvVersion; - bool forwardCompatible; // true if errors are to be given for use of deprecated features TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree protected: diff --git a/glslang/MachineIndependent/preprocessor/Pp.cpp b/glslang/MachineIndependent/preprocessor/Pp.cpp index fc23c047..d7ff485c 100755 --- a/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -722,6 +722,7 @@ int TPpContext::CPPline(TPpToken* ppToken) parseContext.setCurrentLine(lineRes); if (token != '\n') { +#ifndef GLSLANG_WEB if (token == PpAtomConstString) { parseContext.ppRequireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line"); // We need to save a copy of the string instead of pointing @@ -731,7 +732,9 @@ int TPpContext::CPPline(TPpToken* ppToken) parseContext.setCurrentSourceName(sourceName); hasFile = true; token = scanToken(ppToken); - } else { + } else +#endif + { token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken); if (! fileErr) { parseContext.setCurrentString(fileRes); @@ -952,16 +955,16 @@ int TPpContext::readCPPline(TPpToken* ppToken) case PpAtomIfndef: token = CPPifdef(0, ppToken); break; + case PpAtomLine: + token = CPPline(ppToken); + break; +#ifndef GLSLANG_WEB case PpAtomInclude: if(!parseContext.isReadingHLSL()) { parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include"); } token = CPPinclude(ppToken); break; - case PpAtomLine: - token = CPPline(ppToken); - break; -#ifndef GLSLANG_WEB case PpAtomPragma: token = CPPpragma(ppToken); break; diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp index fe36a76e..e35498ff 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -398,7 +398,7 @@ public: topLevelArrayStride = variables.back().arrayStride; } - if ((reflection.options & EShReflectionSeparateBuffers) && terminalType->getBasicType() == EbtAtomicUint) + if ((reflection.options & EShReflectionSeparateBuffers) && terminalType->isAtomic()) reflection.atomicCounterUniformIndices.push_back(uniformIndex); variables.back().topLevelArrayStride = topLevelArrayStride;