mirror of
https://github.com/love2d/love.git
synced 2026-08-21 21:15:09 +02:00
Update glslang. Add files for its GLSL source code to SPIRV module.
--HG-- branch : minor
This commit is contained in:
@@ -1423,9 +1423,38 @@ set(LOVE_SRC_3P_GLSLANG_OGLCOMPILERSDLL
|
|||||||
src/libraries/glslang/OGLCompilersDLL/InitializeDll.h
|
src/libraries/glslang/OGLCompilersDLL/InitializeDll.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set(LOVE_SRC_3P_GLSLANG_SPIRV
|
||||||
|
src/libraries/glslang/SPIRV/bitutils.h
|
||||||
|
src/libraries/glslang/SPIRV/disassemble.cpp
|
||||||
|
src/libraries/glslang/SPIRV/disassemble.h
|
||||||
|
src/libraries/glslang/SPIRV/doc.cpp
|
||||||
|
src/libraries/glslang/SPIRV/doc.h
|
||||||
|
src/libraries/glslang/SPIRV/GLSL.ext.AMD.h
|
||||||
|
src/libraries/glslang/SPIRV/GLSL.ext.EXT.h
|
||||||
|
src/libraries/glslang/SPIRV/GLSL.ext.KHR.h
|
||||||
|
src/libraries/glslang/SPIRV/GLSL.ext.NV.h
|
||||||
|
src/libraries/glslang/SPIRV/GLSL.std.450.h
|
||||||
|
src/libraries/glslang/SPIRV/GlslangToSpv.cpp
|
||||||
|
src/libraries/glslang/SPIRV/GlslangToSpv.h
|
||||||
|
src/libraries/glslang/SPIRV/hex_float.h
|
||||||
|
src/libraries/glslang/SPIRV/InReadableOrder.cpp
|
||||||
|
src/libraries/glslang/SPIRV/Logger.cpp
|
||||||
|
src/libraries/glslang/SPIRV/Logger.h
|
||||||
|
src/libraries/glslang/SPIRV/spirv.hpp
|
||||||
|
src/libraries/glslang/SPIRV/SpvBuilder.cpp
|
||||||
|
src/libraries/glslang/SPIRV/SpvBuilder.h
|
||||||
|
src/libraries/glslang/SPIRV/spvIR.h
|
||||||
|
src/libraries/glslang/SPIRV/SpvPostProcess.cpp
|
||||||
|
src/libraries/glslang/SPIRV/SPVRemapper.cpp
|
||||||
|
src/libraries/glslang/SPIRV/SPVRemapper.h
|
||||||
|
src/libraries/glslang/SPIRV/SpvTools.cpp
|
||||||
|
src/libraries/glslang/SPIRV/SpvTools.h
|
||||||
|
)
|
||||||
|
|
||||||
set(LOVE_SRC_3P_GLSLANG
|
set(LOVE_SRC_3P_GLSLANG
|
||||||
${LOVE_SRC_3P_GLSLANG_GLSLANG}
|
${LOVE_SRC_3P_GLSLANG_GLSLANG}
|
||||||
${LOVE_SRC_3P_GLSLANG_OGLCOMPILERSDLL}
|
${LOVE_SRC_3P_GLSLANG_OGLCOMPILERSDLL}
|
||||||
|
${LOVE_SRC_3P_GLSLANG_SPIRV}
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(love_3p_glslang ${LOVE_SRC_3P_GLSLANG})
|
add_library(love_3p_glslang ${LOVE_SRC_3P_GLSLANG})
|
||||||
|
|||||||
@@ -1207,6 +1207,40 @@
|
|||||||
FAF140DB1E20934C00F898D2 /* InitializeDll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */; };
|
FAF140DB1E20934C00F898D2 /* InitializeDll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */; };
|
||||||
FAF140DC1E20934C00F898D2 /* InitializeDll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */; };
|
FAF140DC1E20934C00F898D2 /* InitializeDll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */; };
|
||||||
FAF140DD1E20934C00F898D2 /* InitializeDll.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF1403C1E20934C00F898D2 /* InitializeDll.h */; };
|
FAF140DD1E20934C00F898D2 /* InitializeDll.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF1403C1E20934C00F898D2 /* InitializeDll.h */; };
|
||||||
|
FAF6C9DA23C2DE2900D7B5BC /* SPVRemapper.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9C123C2DE2900D7B5BC /* SPVRemapper.h */; };
|
||||||
|
FAF6C9DB23C2DE2900D7B5BC /* SpvBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9C223C2DE2900D7B5BC /* SpvBuilder.h */; };
|
||||||
|
FAF6C9DC23C2DE2900D7B5BC /* SpvPostProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9C323C2DE2900D7B5BC /* SpvPostProcess.cpp */; };
|
||||||
|
FAF6C9DD23C2DE2900D7B5BC /* SpvPostProcess.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9C323C2DE2900D7B5BC /* SpvPostProcess.cpp */; };
|
||||||
|
FAF6C9DE23C2DE2900D7B5BC /* SpvTools.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9C423C2DE2900D7B5BC /* SpvTools.h */; };
|
||||||
|
FAF6C9DF23C2DE2900D7B5BC /* SpvTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9C523C2DE2900D7B5BC /* SpvTools.cpp */; };
|
||||||
|
FAF6C9E023C2DE2900D7B5BC /* SpvTools.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9C523C2DE2900D7B5BC /* SpvTools.cpp */; };
|
||||||
|
FAF6C9E123C2DE2900D7B5BC /* InReadableOrder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9C623C2DE2900D7B5BC /* InReadableOrder.cpp */; };
|
||||||
|
FAF6C9E223C2DE2900D7B5BC /* InReadableOrder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9C623C2DE2900D7B5BC /* InReadableOrder.cpp */; };
|
||||||
|
FAF6C9E323C2DE2900D7B5BC /* GLSL.ext.AMD.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9C723C2DE2900D7B5BC /* GLSL.ext.AMD.h */; };
|
||||||
|
FAF6C9E423C2DE2900D7B5BC /* doc.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9C823C2DE2900D7B5BC /* doc.h */; };
|
||||||
|
FAF6C9E523C2DE2900D7B5BC /* spirv.hpp in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9C923C2DE2900D7B5BC /* spirv.hpp */; };
|
||||||
|
FAF6C9E623C2DE2900D7B5BC /* SpvBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9CA23C2DE2900D7B5BC /* SpvBuilder.cpp */; };
|
||||||
|
FAF6C9E723C2DE2900D7B5BC /* SpvBuilder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9CA23C2DE2900D7B5BC /* SpvBuilder.cpp */; };
|
||||||
|
FAF6C9E823C2DE2900D7B5BC /* GLSL.ext.EXT.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9CB23C2DE2900D7B5BC /* GLSL.ext.EXT.h */; };
|
||||||
|
FAF6C9E923C2DE2900D7B5BC /* GLSL.ext.KHR.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9CC23C2DE2900D7B5BC /* GLSL.ext.KHR.h */; };
|
||||||
|
FAF6C9EA23C2DE2900D7B5BC /* GLSL.ext.NV.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9CD23C2DE2900D7B5BC /* GLSL.ext.NV.h */; };
|
||||||
|
FAF6C9EB23C2DE2900D7B5BC /* GlslangToSpv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9CE23C2DE2900D7B5BC /* GlslangToSpv.cpp */; };
|
||||||
|
FAF6C9EC23C2DE2900D7B5BC /* GlslangToSpv.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9CE23C2DE2900D7B5BC /* GlslangToSpv.cpp */; };
|
||||||
|
FAF6C9ED23C2DE2900D7B5BC /* spvIR.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9CF23C2DE2900D7B5BC /* spvIR.h */; };
|
||||||
|
FAF6C9EE23C2DE2900D7B5BC /* bitutils.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9D023C2DE2900D7B5BC /* bitutils.h */; };
|
||||||
|
FAF6C9EF23C2DE2900D7B5BC /* disassemble.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9D123C2DE2900D7B5BC /* disassemble.h */; };
|
||||||
|
FAF6C9F023C2DE2900D7B5BC /* GlslangToSpv.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9D223C2DE2900D7B5BC /* GlslangToSpv.h */; };
|
||||||
|
FAF6C9F123C2DE2900D7B5BC /* GLSL.std.450.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9D323C2DE2900D7B5BC /* GLSL.std.450.h */; };
|
||||||
|
FAF6C9F223C2DE2900D7B5BC /* SPVRemapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9D423C2DE2900D7B5BC /* SPVRemapper.cpp */; };
|
||||||
|
FAF6C9F323C2DE2900D7B5BC /* SPVRemapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9D423C2DE2900D7B5BC /* SPVRemapper.cpp */; };
|
||||||
|
FAF6C9F423C2DE2900D7B5BC /* Logger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9D523C2DE2900D7B5BC /* Logger.cpp */; };
|
||||||
|
FAF6C9F523C2DE2900D7B5BC /* Logger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9D523C2DE2900D7B5BC /* Logger.cpp */; };
|
||||||
|
FAF6C9F623C2DE2900D7B5BC /* hex_float.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9D623C2DE2900D7B5BC /* hex_float.h */; };
|
||||||
|
FAF6C9F723C2DE2900D7B5BC /* Logger.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF6C9D723C2DE2900D7B5BC /* Logger.h */; };
|
||||||
|
FAF6C9F823C2DE2900D7B5BC /* doc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9D823C2DE2900D7B5BC /* doc.cpp */; };
|
||||||
|
FAF6C9F923C2DE2900D7B5BC /* doc.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9D823C2DE2900D7B5BC /* doc.cpp */; };
|
||||||
|
FAF6C9FA23C2DE2900D7B5BC /* disassemble.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9D923C2DE2900D7B5BC /* disassemble.cpp */; };
|
||||||
|
FAF6C9FB23C2DE2900D7B5BC /* disassemble.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF6C9D923C2DE2900D7B5BC /* disassemble.cpp */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
@@ -2060,6 +2094,31 @@
|
|||||||
FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeDll.cpp; sourceTree = "<group>"; };
|
FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeDll.cpp; sourceTree = "<group>"; };
|
||||||
FAF1403C1E20934C00F898D2 /* InitializeDll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeDll.h; sourceTree = "<group>"; };
|
FAF1403C1E20934C00F898D2 /* InitializeDll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeDll.h; sourceTree = "<group>"; };
|
||||||
FAF1889C1E9DA834008C1479 /* Optional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Optional.h; sourceTree = "<group>"; };
|
FAF1889C1E9DA834008C1479 /* Optional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Optional.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9C123C2DE2900D7B5BC /* SPVRemapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPVRemapper.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9C223C2DE2900D7B5BC /* SpvBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpvBuilder.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9C323C2DE2900D7B5BC /* SpvPostProcess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpvPostProcess.cpp; sourceTree = "<group>"; };
|
||||||
|
FAF6C9C423C2DE2900D7B5BC /* SpvTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpvTools.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9C523C2DE2900D7B5BC /* SpvTools.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpvTools.cpp; sourceTree = "<group>"; };
|
||||||
|
FAF6C9C623C2DE2900D7B5BC /* InReadableOrder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InReadableOrder.cpp; sourceTree = "<group>"; };
|
||||||
|
FAF6C9C723C2DE2900D7B5BC /* GLSL.ext.AMD.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLSL.ext.AMD.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9C823C2DE2900D7B5BC /* doc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = doc.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9C923C2DE2900D7B5BC /* spirv.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = spirv.hpp; sourceTree = "<group>"; };
|
||||||
|
FAF6C9CA23C2DE2900D7B5BC /* SpvBuilder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpvBuilder.cpp; sourceTree = "<group>"; };
|
||||||
|
FAF6C9CB23C2DE2900D7B5BC /* GLSL.ext.EXT.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLSL.ext.EXT.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9CC23C2DE2900D7B5BC /* GLSL.ext.KHR.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLSL.ext.KHR.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9CD23C2DE2900D7B5BC /* GLSL.ext.NV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLSL.ext.NV.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9CE23C2DE2900D7B5BC /* GlslangToSpv.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = GlslangToSpv.cpp; sourceTree = "<group>"; };
|
||||||
|
FAF6C9CF23C2DE2900D7B5BC /* spvIR.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spvIR.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9D023C2DE2900D7B5BC /* bitutils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bitutils.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9D123C2DE2900D7B5BC /* disassemble.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = disassemble.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9D223C2DE2900D7B5BC /* GlslangToSpv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GlslangToSpv.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9D323C2DE2900D7B5BC /* GLSL.std.450.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLSL.std.450.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9D423C2DE2900D7B5BC /* SPVRemapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SPVRemapper.cpp; sourceTree = "<group>"; };
|
||||||
|
FAF6C9D523C2DE2900D7B5BC /* Logger.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Logger.cpp; sourceTree = "<group>"; };
|
||||||
|
FAF6C9D623C2DE2900D7B5BC /* hex_float.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hex_float.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9D723C2DE2900D7B5BC /* Logger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Logger.h; sourceTree = "<group>"; };
|
||||||
|
FAF6C9D823C2DE2900D7B5BC /* doc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = doc.cpp; sourceTree = "<group>"; };
|
||||||
|
FAF6C9D923C2DE2900D7B5BC /* disassemble.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = disassemble.cpp; sourceTree = "<group>"; };
|
||||||
FAF949FD21DEE8B7001CD27E /* wrap_Event.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = wrap_Event.lua; sourceTree = "<group>"; };
|
FAF949FD21DEE8B7001CD27E /* wrap_Event.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = wrap_Event.lua; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
@@ -3554,6 +3613,7 @@
|
|||||||
children = (
|
children = (
|
||||||
FAF13FC01E20934C00F898D2 /* glslang */,
|
FAF13FC01E20934C00F898D2 /* glslang */,
|
||||||
FAF1403A1E20934C00F898D2 /* OGLCompilersDLL */,
|
FAF1403A1E20934C00F898D2 /* OGLCompilersDLL */,
|
||||||
|
FAF6C9C023C2DE2900D7B5BC /* SPIRV */,
|
||||||
);
|
);
|
||||||
path = glslang;
|
path = glslang;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -3694,6 +3754,38 @@
|
|||||||
path = OGLCompilersDLL;
|
path = OGLCompilersDLL;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
FAF6C9C023C2DE2900D7B5BC /* SPIRV */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
FAF6C9D023C2DE2900D7B5BC /* bitutils.h */,
|
||||||
|
FAF6C9D923C2DE2900D7B5BC /* disassemble.cpp */,
|
||||||
|
FAF6C9D123C2DE2900D7B5BC /* disassemble.h */,
|
||||||
|
FAF6C9D823C2DE2900D7B5BC /* doc.cpp */,
|
||||||
|
FAF6C9C823C2DE2900D7B5BC /* doc.h */,
|
||||||
|
FAF6C9C723C2DE2900D7B5BC /* GLSL.ext.AMD.h */,
|
||||||
|
FAF6C9CB23C2DE2900D7B5BC /* GLSL.ext.EXT.h */,
|
||||||
|
FAF6C9CC23C2DE2900D7B5BC /* GLSL.ext.KHR.h */,
|
||||||
|
FAF6C9CD23C2DE2900D7B5BC /* GLSL.ext.NV.h */,
|
||||||
|
FAF6C9D323C2DE2900D7B5BC /* GLSL.std.450.h */,
|
||||||
|
FAF6C9CE23C2DE2900D7B5BC /* GlslangToSpv.cpp */,
|
||||||
|
FAF6C9D223C2DE2900D7B5BC /* GlslangToSpv.h */,
|
||||||
|
FAF6C9D623C2DE2900D7B5BC /* hex_float.h */,
|
||||||
|
FAF6C9C623C2DE2900D7B5BC /* InReadableOrder.cpp */,
|
||||||
|
FAF6C9D523C2DE2900D7B5BC /* Logger.cpp */,
|
||||||
|
FAF6C9D723C2DE2900D7B5BC /* Logger.h */,
|
||||||
|
FAF6C9C923C2DE2900D7B5BC /* spirv.hpp */,
|
||||||
|
FAF6C9CA23C2DE2900D7B5BC /* SpvBuilder.cpp */,
|
||||||
|
FAF6C9C223C2DE2900D7B5BC /* SpvBuilder.h */,
|
||||||
|
FAF6C9CF23C2DE2900D7B5BC /* spvIR.h */,
|
||||||
|
FAF6C9C323C2DE2900D7B5BC /* SpvPostProcess.cpp */,
|
||||||
|
FAF6C9D423C2DE2900D7B5BC /* SPVRemapper.cpp */,
|
||||||
|
FAF6C9C123C2DE2900D7B5BC /* SPVRemapper.h */,
|
||||||
|
FAF6C9C523C2DE2900D7B5BC /* SpvTools.cpp */,
|
||||||
|
FAF6C9C423C2DE2900D7B5BC /* SpvTools.h */,
|
||||||
|
);
|
||||||
|
path = SPIRV;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXHeadersBuildPhase section */
|
/* Begin PBXHeadersBuildPhase section */
|
||||||
@@ -3701,7 +3793,9 @@
|
|||||||
isa = PBXHeadersBuildPhase;
|
isa = PBXHeadersBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
FAF6C9F623C2DE2900D7B5BC /* hex_float.h in Headers */,
|
||||||
FADF54221E3DA52C00012CC0 /* wrap_ParticleSystem.h in Headers */,
|
FADF54221E3DA52C00012CC0 /* wrap_ParticleSystem.h in Headers */,
|
||||||
|
FAF6C9EE23C2DE2900D7B5BC /* bitutils.h in Headers */,
|
||||||
217DFC0A1D9F6D490055D849 /* unix.h in Headers */,
|
217DFC0A1D9F6D490055D849 /* unix.h in Headers */,
|
||||||
FA0B7D7E1A95902C000E1D17 /* Texture.h in Headers */,
|
FA0B7D7E1A95902C000E1D17 /* Texture.h in Headers */,
|
||||||
FA0B7E561A95902C000E1D17 /* wrap_GearJoint.h in Headers */,
|
FA0B7E561A95902C000E1D17 /* wrap_GearJoint.h in Headers */,
|
||||||
@@ -3727,10 +3821,12 @@
|
|||||||
FA0B7E9C1A95902C000E1D17 /* VorbisDecoder.h in Headers */,
|
FA0B7E9C1A95902C000E1D17 /* VorbisDecoder.h in Headers */,
|
||||||
FAC271E523B5B5B400C200D3 /* renderstate.h in Headers */,
|
FAC271E523B5B5B400C200D3 /* renderstate.h in Headers */,
|
||||||
FAC756FB1E4F99D200B91289 /* Effect.h in Headers */,
|
FAC756FB1E4F99D200B91289 /* Effect.h in Headers */,
|
||||||
|
FAF6C9EF23C2DE2900D7B5BC /* disassemble.h in Headers */,
|
||||||
FAC7CD901FE35E95006A60C7 /* physfs_miniz.h in Headers */,
|
FAC7CD901FE35E95006A60C7 /* physfs_miniz.h in Headers */,
|
||||||
FA0B791D1A958E3B000E1D17 /* b64.h in Headers */,
|
FA0B791D1A958E3B000E1D17 /* b64.h in Headers */,
|
||||||
FA0B7DC61A95902C000E1D17 /* wrap_JoystickModule.h in Headers */,
|
FA0B7DC61A95902C000E1D17 /* wrap_JoystickModule.h in Headers */,
|
||||||
FA0B7D201A95902C000E1D17 /* ImageRasterizer.h in Headers */,
|
FA0B7D201A95902C000E1D17 /* ImageRasterizer.h in Headers */,
|
||||||
|
FAF6C9EA23C2DE2900D7B5BC /* GLSL.ext.NV.h in Headers */,
|
||||||
FA0B7D241A95902C000E1D17 /* Vera.ttf.h in Headers */,
|
FA0B7D241A95902C000E1D17 /* Vera.ttf.h in Headers */,
|
||||||
FADF54311E3DABF600012CC0 /* SpriteBatch.h in Headers */,
|
FADF54311E3DABF600012CC0 /* SpriteBatch.h in Headers */,
|
||||||
FA0B7E5F1A95902C000E1D17 /* wrap_MouseJoint.h in Headers */,
|
FA0B7E5F1A95902C000E1D17 /* wrap_MouseJoint.h in Headers */,
|
||||||
@@ -3792,10 +3888,12 @@
|
|||||||
FA0B7EDD1A95902D000E1D17 /* Touch.h in Headers */,
|
FA0B7EDD1A95902D000E1D17 /* Touch.h in Headers */,
|
||||||
FA0B7EDE1A95902D000E1D17 /* Touch.h in Headers */,
|
FA0B7EDE1A95902D000E1D17 /* Touch.h in Headers */,
|
||||||
FAC7CD861FE35E95006A60C7 /* physfs.h in Headers */,
|
FAC7CD861FE35E95006A60C7 /* physfs.h in Headers */,
|
||||||
|
FAF6C9E523C2DE2900D7B5BC /* spirv.hpp in Headers */,
|
||||||
FA0B7A541A958EA3000E1D17 /* b2Math.h in Headers */,
|
FA0B7A541A958EA3000E1D17 /* b2Math.h in Headers */,
|
||||||
217DFBEE1D9F6D490055D849 /* luasocket.h in Headers */,
|
217DFBEE1D9F6D490055D849 /* luasocket.h in Headers */,
|
||||||
FACA02F31F5E396B0084B28F /* HashFunction.h in Headers */,
|
FACA02F31F5E396B0084B28F /* HashFunction.h in Headers */,
|
||||||
FA0B7ED01A95902C000E1D17 /* wrap_LuaThread.h in Headers */,
|
FA0B7ED01A95902C000E1D17 /* wrap_LuaThread.h in Headers */,
|
||||||
|
FAF6C9E923C2DE2900D7B5BC /* GLSL.ext.KHR.h in Headers */,
|
||||||
FA0B7CE41A95902C000E1D17 /* wrap_Audio.h in Headers */,
|
FA0B7CE41A95902C000E1D17 /* wrap_Audio.h in Headers */,
|
||||||
FA0B7A7F1A958EA3000E1D17 /* b2ContactSolver.h in Headers */,
|
FA0B7A7F1A958EA3000E1D17 /* b2ContactSolver.h in Headers */,
|
||||||
FADF540F1E3D7CDD00012CC0 /* wrap_Video.h in Headers */,
|
FADF540F1E3D7CDD00012CC0 /* wrap_Video.h in Headers */,
|
||||||
@@ -3825,9 +3923,11 @@
|
|||||||
FA0B7A5A1A958EA3000E1D17 /* b2StackAllocator.h in Headers */,
|
FA0B7A5A1A958EA3000E1D17 /* b2StackAllocator.h in Headers */,
|
||||||
FA0B7D881A95902C000E1D17 /* ImageData.h in Headers */,
|
FA0B7D881A95902C000E1D17 /* ImageData.h in Headers */,
|
||||||
FA0B7A661A958EA3000E1D17 /* b2Fixture.h in Headers */,
|
FA0B7A661A958EA3000E1D17 /* b2Fixture.h in Headers */,
|
||||||
|
FAF6C9DA23C2DE2900D7B5BC /* SPVRemapper.h in Headers */,
|
||||||
FA0B7EE11A95902D000E1D17 /* wrap_Touch.h in Headers */,
|
FA0B7EE11A95902D000E1D17 /* wrap_Touch.h in Headers */,
|
||||||
FA9D8DDB1DEF8411002CD881 /* Stream.h in Headers */,
|
FA9D8DDB1DEF8411002CD881 /* Stream.h in Headers */,
|
||||||
FA0B7AA91A958EA3000E1D17 /* b2RopeJoint.h in Headers */,
|
FA0B7AA91A958EA3000E1D17 /* b2RopeJoint.h in Headers */,
|
||||||
|
FAF6C9E823C2DE2900D7B5BC /* GLSL.ext.EXT.h in Headers */,
|
||||||
FACA02F71F5E396B0084B28F /* wrap_DataModule.h in Headers */,
|
FACA02F71F5E396B0084B28F /* wrap_DataModule.h in Headers */,
|
||||||
FA56AA3A1FAFF02000A43D5F /* memory.h in Headers */,
|
FA56AA3A1FAFF02000A43D5F /* memory.h in Headers */,
|
||||||
FA0B7E441A95902C000E1D17 /* wrap_CircleShape.h in Headers */,
|
FA0B7E441A95902C000E1D17 /* wrap_CircleShape.h in Headers */,
|
||||||
@@ -3909,6 +4009,7 @@
|
|||||||
FA0B792B1A958E3B000E1D17 /* Matrix.h in Headers */,
|
FA0B792B1A958E3B000E1D17 /* Matrix.h in Headers */,
|
||||||
FA0B7DA41A95902C000E1D17 /* PKMHandler.h in Headers */,
|
FA0B7DA41A95902C000E1D17 /* PKMHandler.h in Headers */,
|
||||||
FA4C22D122C2E11000BFBB7C /* dr_flac.h in Headers */,
|
FA4C22D122C2E11000BFBB7C /* dr_flac.h in Headers */,
|
||||||
|
FAF6C9E423C2DE2900D7B5BC /* doc.h in Headers */,
|
||||||
FA0B7AC81A958EA3000E1D17 /* utility.h in Headers */,
|
FA0B7AC81A958EA3000E1D17 /* utility.h in Headers */,
|
||||||
217DFC0E1D9F6D490055D849 /* unixudp.h in Headers */,
|
217DFC0E1D9F6D490055D849 /* unixudp.h in Headers */,
|
||||||
FA0B791F1A958E3B000E1D17 /* Data.h in Headers */,
|
FA0B791F1A958E3B000E1D17 /* Data.h in Headers */,
|
||||||
@@ -3935,6 +4036,8 @@
|
|||||||
FA0B7EB71A95902C000E1D17 /* wrap_System.h in Headers */,
|
FA0B7EB71A95902C000E1D17 /* wrap_System.h in Headers */,
|
||||||
FA27B3A91B498151008A9DCE /* Video.h in Headers */,
|
FA27B3A91B498151008A9DCE /* Video.h in Headers */,
|
||||||
FAAA3FD81F64B3AD00F89E99 /* lprefix.h in Headers */,
|
FAAA3FD81F64B3AD00F89E99 /* lprefix.h in Headers */,
|
||||||
|
FAF6C9F023C2DE2900D7B5BC /* GlslangToSpv.h in Headers */,
|
||||||
|
FAF6C9F723C2DE2900D7B5BC /* Logger.h in Headers */,
|
||||||
217DFBFA1D9F6D490055D849 /* select.h in Headers */,
|
217DFBFA1D9F6D490055D849 /* select.h in Headers */,
|
||||||
FA0B7DF61A95902C000E1D17 /* wrap_Mouse.h in Headers */,
|
FA0B7DF61A95902C000E1D17 /* wrap_Mouse.h in Headers */,
|
||||||
FAF140661E20934C00F898D2 /* gl_types.h in Headers */,
|
FAF140661E20934C00F898D2 /* gl_types.h in Headers */,
|
||||||
@@ -3960,6 +4063,7 @@
|
|||||||
FAF1407F1E20934C00F898D2 /* localintermediate.h in Headers */,
|
FAF1407F1E20934C00F898D2 /* localintermediate.h in Headers */,
|
||||||
FAF1406B1E20934C00F898D2 /* glslang_tab.cpp.h in Headers */,
|
FAF1406B1E20934C00F898D2 /* glslang_tab.cpp.h in Headers */,
|
||||||
217DFBF71D9F6D490055D849 /* options.h in Headers */,
|
217DFBF71D9F6D490055D849 /* options.h in Headers */,
|
||||||
|
FAF6C9ED23C2DE2900D7B5BC /* spvIR.h in Headers */,
|
||||||
FA0B7E3B1A95902C000E1D17 /* World.h in Headers */,
|
FA0B7E3B1A95902C000E1D17 /* World.h in Headers */,
|
||||||
FA0B7DC31A95902C000E1D17 /* wrap_Joystick.h in Headers */,
|
FA0B7DC31A95902C000E1D17 /* wrap_Joystick.h in Headers */,
|
||||||
FAF140631E20934C00F898D2 /* Types.h in Headers */,
|
FAF140631E20934C00F898D2 /* Types.h in Headers */,
|
||||||
@@ -3969,6 +4073,7 @@
|
|||||||
FA0B7AC91A958EA3000E1D17 /* win32.h in Headers */,
|
FA0B7AC91A958EA3000E1D17 /* win32.h in Headers */,
|
||||||
FA0B7DFC1A95902C000E1D17 /* Body.h in Headers */,
|
FA0B7DFC1A95902C000E1D17 /* Body.h in Headers */,
|
||||||
FA1BA0B31E16FD0800AA2803 /* Shader.h in Headers */,
|
FA1BA0B31E16FD0800AA2803 /* Shader.h in Headers */,
|
||||||
|
FAF6C9F123C2DE2900D7B5BC /* GLSL.std.450.h in Headers */,
|
||||||
217DFC101D9F6D490055D849 /* url.lua.h in Headers */,
|
217DFC101D9F6D490055D849 /* url.lua.h in Headers */,
|
||||||
FAF140DD1E20934C00F898D2 /* InitializeDll.h in Headers */,
|
FAF140DD1E20934C00F898D2 /* InitializeDll.h in Headers */,
|
||||||
FA0B7A941A958EA3000E1D17 /* b2GearJoint.h in Headers */,
|
FA0B7A941A958EA3000E1D17 /* b2GearJoint.h in Headers */,
|
||||||
@@ -4002,6 +4107,7 @@
|
|||||||
FA0B7AC41A958EA3000E1D17 /* protocol.h in Headers */,
|
FA0B7AC41A958EA3000E1D17 /* protocol.h in Headers */,
|
||||||
FAF140601E20934C00F898D2 /* revision.h in Headers */,
|
FAF140601E20934C00F898D2 /* revision.h in Headers */,
|
||||||
FAF140A21E20934C00F898D2 /* RemoveTree.h in Headers */,
|
FAF140A21E20934C00F898D2 /* RemoveTree.h in Headers */,
|
||||||
|
FAF6C9DE23C2DE2900D7B5BC /* SpvTools.h in Headers */,
|
||||||
FA0B7A8E1A958EA3000E1D17 /* b2DistanceJoint.h in Headers */,
|
FA0B7A8E1A958EA3000E1D17 /* b2DistanceJoint.h in Headers */,
|
||||||
FA0B7A8B1A958EA3000E1D17 /* b2PolygonContact.h in Headers */,
|
FA0B7A8B1A958EA3000E1D17 /* b2PolygonContact.h in Headers */,
|
||||||
FA0B7D321A95902C000E1D17 /* Graphics.h in Headers */,
|
FA0B7D321A95902C000E1D17 /* Graphics.h in Headers */,
|
||||||
@@ -4028,6 +4134,7 @@
|
|||||||
FA0B7D4D1A95902C000E1D17 /* Shader.h in Headers */,
|
FA0B7D4D1A95902C000E1D17 /* Shader.h in Headers */,
|
||||||
FA0B793D1A958E3B000E1D17 /* runtime.h in Headers */,
|
FA0B793D1A958E3B000E1D17 /* runtime.h in Headers */,
|
||||||
FA0B7A701A958EA3000E1D17 /* b2WorldCallbacks.h in Headers */,
|
FA0B7A701A958EA3000E1D17 /* b2WorldCallbacks.h in Headers */,
|
||||||
|
FAF6C9E323C2DE2900D7B5BC /* GLSL.ext.AMD.h in Headers */,
|
||||||
FA0B7A9D1A958EA3000E1D17 /* b2MouseJoint.h in Headers */,
|
FA0B7A9D1A958EA3000E1D17 /* b2MouseJoint.h in Headers */,
|
||||||
FA57FB9A1AE1993600F2AD6D /* noise1234.h in Headers */,
|
FA57FB9A1AE1993600F2AD6D /* noise1234.h in Headers */,
|
||||||
FACA02EF1F5E396B0084B28F /* Compressor.h in Headers */,
|
FACA02EF1F5E396B0084B28F /* Compressor.h in Headers */,
|
||||||
@@ -4054,6 +4161,7 @@
|
|||||||
FA0B7A9A1A958EA3000E1D17 /* b2MotorJoint.h in Headers */,
|
FA0B7A9A1A958EA3000E1D17 /* b2MotorJoint.h in Headers */,
|
||||||
217DFC081D9F6D490055D849 /* udp.h in Headers */,
|
217DFC081D9F6D490055D849 /* udp.h in Headers */,
|
||||||
FA0B7DCF1A95902C000E1D17 /* wrap_Keyboard.h in Headers */,
|
FA0B7DCF1A95902C000E1D17 /* wrap_Keyboard.h in Headers */,
|
||||||
|
FAF6C9DB23C2DE2900D7B5BC /* SpvBuilder.h in Headers */,
|
||||||
FA0B7EA21A95902C000E1D17 /* Sound.h in Headers */,
|
FA0B7EA21A95902C000E1D17 /* Sound.h in Headers */,
|
||||||
FA0B7B331A958EA3000E1D17 /* wuff_config.h in Headers */,
|
FA0B7B331A958EA3000E1D17 /* wuff_config.h in Headers */,
|
||||||
FA0B7D3B1A95902C000E1D17 /* Graphics.h in Headers */,
|
FA0B7D3B1A95902C000E1D17 /* Graphics.h in Headers */,
|
||||||
@@ -4225,10 +4333,12 @@
|
|||||||
FA0B7ED91A95902D000E1D17 /* wrap_Timer.cpp in Sources */,
|
FA0B7ED91A95902D000E1D17 /* wrap_Timer.cpp in Sources */,
|
||||||
FAF1407D1E20934C00F898D2 /* linkValidate.cpp in Sources */,
|
FAF1407D1E20934C00F898D2 /* linkValidate.cpp in Sources */,
|
||||||
FAE64A872071363100BC7981 /* physfs_archiver_slb.c in Sources */,
|
FAE64A872071363100BC7981 /* physfs_archiver_slb.c in Sources */,
|
||||||
|
FAF6C9E723C2DE2900D7B5BC /* SpvBuilder.cpp in Sources */,
|
||||||
FA0B7DD11A95902C000E1D17 /* love.cpp in Sources */,
|
FA0B7DD11A95902C000E1D17 /* love.cpp in Sources */,
|
||||||
FA15DFAF1F9B8D390042AB22 /* lstrlib.c in Sources */,
|
FA15DFAF1F9B8D390042AB22 /* lstrlib.c in Sources */,
|
||||||
FA0B7AB61A958EA3000E1D17 /* ddsparse.cpp in Sources */,
|
FA0B7AB61A958EA3000E1D17 /* ddsparse.cpp in Sources */,
|
||||||
FA0B7D221A95902C000E1D17 /* Rasterizer.cpp in Sources */,
|
FA0B7D221A95902C000E1D17 /* Rasterizer.cpp in Sources */,
|
||||||
|
FAF6C9E223C2DE2900D7B5BC /* InReadableOrder.cpp in Sources */,
|
||||||
FA0B7A4F1A958EA3000E1D17 /* b2Draw.cpp in Sources */,
|
FA0B7A4F1A958EA3000E1D17 /* b2Draw.cpp in Sources */,
|
||||||
FAF140BC1E20934C00F898D2 /* ossource.cpp in Sources */,
|
FAF140BC1E20934C00F898D2 /* ossource.cpp in Sources */,
|
||||||
FA0B7D7D1A95902C000E1D17 /* Texture.cpp in Sources */,
|
FA0B7D7D1A95902C000E1D17 /* Texture.cpp in Sources */,
|
||||||
@@ -4325,6 +4435,7 @@
|
|||||||
FA0B7A3C1A958EA3000E1D17 /* b2TimeOfImpact.cpp in Sources */,
|
FA0B7A3C1A958EA3000E1D17 /* b2TimeOfImpact.cpp in Sources */,
|
||||||
FA4F2C081DE936DD00CA37D7 /* io.c in Sources */,
|
FA4F2C081DE936DD00CA37D7 /* io.c in Sources */,
|
||||||
FA0B7CDD1A95902C000E1D17 /* Source.cpp in Sources */,
|
FA0B7CDD1A95902C000E1D17 /* Source.cpp in Sources */,
|
||||||
|
FAF6C9EC23C2DE2900D7B5BC /* GlslangToSpv.cpp in Sources */,
|
||||||
FA0B7DC51A95902C000E1D17 /* wrap_JoystickModule.cpp in Sources */,
|
FA0B7DC51A95902C000E1D17 /* wrap_JoystickModule.cpp in Sources */,
|
||||||
FA0B7E701A95902C000E1D17 /* wrap_RopeJoint.cpp in Sources */,
|
FA0B7E701A95902C000E1D17 /* wrap_RopeJoint.cpp in Sources */,
|
||||||
FA24348821D401CB00B8918A /* attribute.cpp in Sources */,
|
FA24348821D401CB00B8918A /* attribute.cpp in Sources */,
|
||||||
@@ -4425,6 +4536,7 @@
|
|||||||
FA0B7E491A95902C000E1D17 /* wrap_DistanceJoint.cpp in Sources */,
|
FA0B7E491A95902C000E1D17 /* wrap_DistanceJoint.cpp in Sources */,
|
||||||
FA0B7A391A958EA3000E1D17 /* b2DynamicTree.cpp in Sources */,
|
FA0B7A391A958EA3000E1D17 /* b2DynamicTree.cpp in Sources */,
|
||||||
FA4F2C101DE936FE00CA37D7 /* udp.c in Sources */,
|
FA4F2C101DE936FE00CA37D7 /* udp.c in Sources */,
|
||||||
|
FAF6C9E023C2DE2900D7B5BC /* SpvTools.cpp in Sources */,
|
||||||
FAE64A8F2071364200BC7981 /* physfs_platform_unix.c in Sources */,
|
FAE64A8F2071364200BC7981 /* physfs_platform_unix.c in Sources */,
|
||||||
FA0B7A681A958EA3000E1D17 /* b2Island.cpp in Sources */,
|
FA0B7A681A958EA3000E1D17 /* b2Island.cpp in Sources */,
|
||||||
FA0B7E2B1A95902C000E1D17 /* RevoluteJoint.cpp in Sources */,
|
FA0B7E2B1A95902C000E1D17 /* RevoluteJoint.cpp in Sources */,
|
||||||
@@ -4439,6 +4551,7 @@
|
|||||||
FADF54301E3DABF600012CC0 /* SpriteBatch.cpp in Sources */,
|
FADF54301E3DABF600012CC0 /* SpriteBatch.cpp in Sources */,
|
||||||
FA0B7CF81A95902C000E1D17 /* FileData.cpp in Sources */,
|
FA0B7CF81A95902C000E1D17 /* FileData.cpp in Sources */,
|
||||||
FA0B7DA61A95902C000E1D17 /* PNGHandler.cpp in Sources */,
|
FA0B7DA61A95902C000E1D17 /* PNGHandler.cpp in Sources */,
|
||||||
|
FAF6C9F523C2DE2900D7B5BC /* Logger.cpp in Sources */,
|
||||||
FAE64A932071365100BC7981 /* physfs_platform_haiku.cpp in Sources */,
|
FAE64A932071365100BC7981 /* physfs_platform_haiku.cpp in Sources */,
|
||||||
FA0B7E981A95902C000E1D17 /* Sound.cpp in Sources */,
|
FA0B7E981A95902C000E1D17 /* Sound.cpp in Sources */,
|
||||||
FA0B7E371A95902C000E1D17 /* WheelJoint.cpp in Sources */,
|
FA0B7E371A95902C000E1D17 /* WheelJoint.cpp in Sources */,
|
||||||
@@ -4521,13 +4634,17 @@
|
|||||||
FA620A3B1AA305F6005DB4C2 /* types.cpp in Sources */,
|
FA620A3B1AA305F6005DB4C2 /* types.cpp in Sources */,
|
||||||
FA0B7DD41A95902C000E1D17 /* BezierCurve.cpp in Sources */,
|
FA0B7DD41A95902C000E1D17 /* BezierCurve.cpp in Sources */,
|
||||||
FA0B7E7C1A95902C000E1D17 /* wrap_World.cpp in Sources */,
|
FA0B7E7C1A95902C000E1D17 /* wrap_World.cpp in Sources */,
|
||||||
|
FAF6C9F923C2DE2900D7B5BC /* doc.cpp in Sources */,
|
||||||
FA4F2C0E1DE936FE00CA37D7 /* tcp.c in Sources */,
|
FA4F2C0E1DE936FE00CA37D7 /* tcp.c in Sources */,
|
||||||
FA0B7D431A95902C000E1D17 /* OpenGL.cpp in Sources */,
|
FA0B7D431A95902C000E1D17 /* OpenGL.cpp in Sources */,
|
||||||
|
FAF6C9DD23C2DE2900D7B5BC /* SpvPostProcess.cpp in Sources */,
|
||||||
FA0B7DBF1A95902C000E1D17 /* JoystickModule.cpp in Sources */,
|
FA0B7DBF1A95902C000E1D17 /* JoystickModule.cpp in Sources */,
|
||||||
FAB2D5AB1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */,
|
FAB2D5AB1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */,
|
||||||
FA0B7A9F1A958EA3000E1D17 /* b2PrismaticJoint.cpp in Sources */,
|
FA0B7A9F1A958EA3000E1D17 /* b2PrismaticJoint.cpp in Sources */,
|
||||||
FA1BA0AD1E16F9EE00AA2803 /* wrap_Canvas.cpp in Sources */,
|
FA1BA0AD1E16F9EE00AA2803 /* wrap_Canvas.cpp in Sources */,
|
||||||
|
FAF6C9FB23C2DE2900D7B5BC /* disassemble.cpp in Sources */,
|
||||||
FAE64A822071363100BC7981 /* physfs_archiver_grp.c in Sources */,
|
FAE64A822071363100BC7981 /* physfs_archiver_grp.c in Sources */,
|
||||||
|
FAF6C9F323C2DE2900D7B5BC /* SPVRemapper.cpp in Sources */,
|
||||||
FA0B79331A958E3B000E1D17 /* Object.cpp in Sources */,
|
FA0B79331A958E3B000E1D17 /* Object.cpp in Sources */,
|
||||||
FAE64A8D2071363500BC7981 /* physfs_platform_apple.m in Sources */,
|
FAE64A8D2071363500BC7981 /* physfs_platform_apple.m in Sources */,
|
||||||
FA0B7E5B1A95902C000E1D17 /* wrap_MotorJoint.cpp in Sources */,
|
FA0B7E5B1A95902C000E1D17 /* wrap_MotorJoint.cpp in Sources */,
|
||||||
@@ -4608,6 +4725,7 @@
|
|||||||
FA0B7A9E1A958EA3000E1D17 /* b2PrismaticJoint.cpp in Sources */,
|
FA0B7A9E1A958EA3000E1D17 /* b2PrismaticJoint.cpp in Sources */,
|
||||||
FA0B7EAF1A95902C000E1D17 /* System.cpp in Sources */,
|
FA0B7EAF1A95902C000E1D17 /* System.cpp in Sources */,
|
||||||
FA0B7EE21A95902D000E1D17 /* Window.cpp in Sources */,
|
FA0B7EE21A95902D000E1D17 /* Window.cpp in Sources */,
|
||||||
|
FAF6C9E123C2DE2900D7B5BC /* InReadableOrder.cpp in Sources */,
|
||||||
FA0B791B1A958E3B000E1D17 /* b64.cpp in Sources */,
|
FA0B791B1A958E3B000E1D17 /* b64.cpp in Sources */,
|
||||||
FA0B7EC11A95902C000E1D17 /* threads.cpp in Sources */,
|
FA0B7EC11A95902C000E1D17 /* threads.cpp in Sources */,
|
||||||
FA0B79321A958E3B000E1D17 /* Object.cpp in Sources */,
|
FA0B79321A958E3B000E1D17 /* Object.cpp in Sources */,
|
||||||
@@ -4615,10 +4733,12 @@
|
|||||||
FAF140641E20934C00F898D2 /* Constant.cpp in Sources */,
|
FAF140641E20934C00F898D2 /* Constant.cpp in Sources */,
|
||||||
FA0B7ED81A95902D000E1D17 /* wrap_Timer.cpp in Sources */,
|
FA0B7ED81A95902D000E1D17 /* wrap_Timer.cpp in Sources */,
|
||||||
FAF1407C1E20934C00F898D2 /* linkValidate.cpp in Sources */,
|
FAF1407C1E20934C00F898D2 /* linkValidate.cpp in Sources */,
|
||||||
|
FAF6C9DC23C2DE2900D7B5BC /* SpvPostProcess.cpp in Sources */,
|
||||||
FA0B7DD01A95902C000E1D17 /* love.cpp in Sources */,
|
FA0B7DD01A95902C000E1D17 /* love.cpp in Sources */,
|
||||||
FA0B7A521A958EA3000E1D17 /* b2Math.cpp in Sources */,
|
FA0B7A521A958EA3000E1D17 /* b2Math.cpp in Sources */,
|
||||||
FA0B7D211A95902C000E1D17 /* Rasterizer.cpp in Sources */,
|
FA0B7D211A95902C000E1D17 /* Rasterizer.cpp in Sources */,
|
||||||
FAC7CD7C1FE35E95006A60C7 /* physfs_archiver_slb.c in Sources */,
|
FAC7CD7C1FE35E95006A60C7 /* physfs_archiver_slb.c in Sources */,
|
||||||
|
FAF6C9FA23C2DE2900D7B5BC /* disassemble.cpp in Sources */,
|
||||||
FAC7CD931FE35E95006A60C7 /* physfs_archiver_zip.c in Sources */,
|
FAC7CD931FE35E95006A60C7 /* physfs_archiver_zip.c in Sources */,
|
||||||
FA0B7D7C1A95902C000E1D17 /* Texture.cpp in Sources */,
|
FA0B7D7C1A95902C000E1D17 /* Texture.cpp in Sources */,
|
||||||
FAF140BB1E20934C00F898D2 /* ossource.cpp in Sources */,
|
FAF140BB1E20934C00F898D2 /* ossource.cpp in Sources */,
|
||||||
@@ -4657,6 +4777,7 @@
|
|||||||
FA0B7D091A95902C000E1D17 /* wrap_FileData.cpp in Sources */,
|
FA0B7D091A95902C000E1D17 /* wrap_FileData.cpp in Sources */,
|
||||||
FA0B7B341A958EA3000E1D17 /* wuff_convert.c in Sources */,
|
FA0B7B341A958EA3000E1D17 /* wuff_convert.c in Sources */,
|
||||||
FAF140821E20934C00F898D2 /* ParseContextBase.cpp in Sources */,
|
FAF140821E20934C00F898D2 /* ParseContextBase.cpp in Sources */,
|
||||||
|
FAF6C9E623C2DE2900D7B5BC /* SpvBuilder.cpp in Sources */,
|
||||||
FA0B7D1E1A95902C000E1D17 /* ImageRasterizer.cpp in Sources */,
|
FA0B7D1E1A95902C000E1D17 /* ImageRasterizer.cpp in Sources */,
|
||||||
FAF140A31E20934C00F898D2 /* Scan.cpp in Sources */,
|
FAF140A31E20934C00F898D2 /* Scan.cpp in Sources */,
|
||||||
FA0B7EA31A95902C000E1D17 /* SoundData.cpp in Sources */,
|
FA0B7EA31A95902C000E1D17 /* SoundData.cpp in Sources */,
|
||||||
@@ -4673,9 +4794,11 @@
|
|||||||
FAF140A91E20934C00F898D2 /* SymbolTable.cpp in Sources */,
|
FAF140A91E20934C00F898D2 /* SymbolTable.cpp in Sources */,
|
||||||
FA0B7E181A95902C000E1D17 /* MotorJoint.cpp in Sources */,
|
FA0B7E181A95902C000E1D17 /* MotorJoint.cpp in Sources */,
|
||||||
FA0B7E4E1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */,
|
FA0B7E4E1A95902C000E1D17 /* wrap_Fixture.cpp in Sources */,
|
||||||
|
FAF6C9F423C2DE2900D7B5BC /* Logger.cpp in Sources */,
|
||||||
FA0B7EBE1A95902C000E1D17 /* Thread.cpp in Sources */,
|
FA0B7EBE1A95902C000E1D17 /* Thread.cpp in Sources */,
|
||||||
FAC7CD8F1FE35E95006A60C7 /* physfs_platform_posix.c in Sources */,
|
FAC7CD8F1FE35E95006A60C7 /* physfs_platform_posix.c in Sources */,
|
||||||
FAF1406E1E20934C00F898D2 /* Initialize.cpp in Sources */,
|
FAF1406E1E20934C00F898D2 /* Initialize.cpp in Sources */,
|
||||||
|
FAF6C9DF23C2DE2900D7B5BC /* SpvTools.cpp in Sources */,
|
||||||
FA0B7EB81A95902C000E1D17 /* Channel.cpp in Sources */,
|
FA0B7EB81A95902C000E1D17 /* Channel.cpp in Sources */,
|
||||||
217DFC091D9F6D490055D849 /* unix.c in Sources */,
|
217DFC091D9F6D490055D849 /* unix.c in Sources */,
|
||||||
FACA02EE1F5E396B0084B28F /* Compressor.cpp in Sources */,
|
FACA02EE1F5E396B0084B28F /* Compressor.cpp in Sources */,
|
||||||
@@ -4707,6 +4830,7 @@
|
|||||||
FA0B7AA41A958EA3000E1D17 /* b2RevoluteJoint.cpp in Sources */,
|
FA0B7AA41A958EA3000E1D17 /* b2RevoluteJoint.cpp in Sources */,
|
||||||
FA9D8DDD1DEF842A002CD881 /* Drawable.cpp in Sources */,
|
FA9D8DDD1DEF842A002CD881 /* Drawable.cpp in Sources */,
|
||||||
FA0B7DFA1A95902C000E1D17 /* Body.cpp in Sources */,
|
FA0B7DFA1A95902C000E1D17 /* Body.cpp in Sources */,
|
||||||
|
FAF6C9EB23C2DE2900D7B5BC /* GlslangToSpv.cpp in Sources */,
|
||||||
FADF54021E3D77B500012CC0 /* wrap_Text.cpp in Sources */,
|
FADF54021E3D77B500012CC0 /* wrap_Text.cpp in Sources */,
|
||||||
FA0B7ED11A95902C000E1D17 /* wrap_ThreadModule.cpp in Sources */,
|
FA0B7ED11A95902C000E1D17 /* wrap_ThreadModule.cpp in Sources */,
|
||||||
FAC7CD7F1FE35E95006A60C7 /* physfs_archiver_wad.c in Sources */,
|
FAC7CD7F1FE35E95006A60C7 /* physfs_archiver_wad.c in Sources */,
|
||||||
@@ -4792,6 +4916,7 @@
|
|||||||
FAF1408C1E20934C00F898D2 /* PpAtom.cpp in Sources */,
|
FAF1408C1E20934C00F898D2 /* PpAtom.cpp in Sources */,
|
||||||
FA0B7A801A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp in Sources */,
|
FA0B7A801A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp in Sources */,
|
||||||
FAF140711E20934C00F898D2 /* Intermediate.cpp in Sources */,
|
FAF140711E20934C00F898D2 /* Intermediate.cpp in Sources */,
|
||||||
|
FAF6C9F823C2DE2900D7B5BC /* doc.cpp in Sources */,
|
||||||
FAC7CD7D1FE35E95006A60C7 /* physfs_platform_winrt.cpp in Sources */,
|
FAC7CD7D1FE35E95006A60C7 /* physfs_platform_winrt.cpp in Sources */,
|
||||||
FA0B7E541A95902C000E1D17 /* wrap_GearJoint.cpp in Sources */,
|
FA0B7E541A95902C000E1D17 /* wrap_GearJoint.cpp in Sources */,
|
||||||
FA0A3A6023366CE9001C269E /* floattypes.cpp in Sources */,
|
FA0A3A6023366CE9001C269E /* floattypes.cpp in Sources */,
|
||||||
@@ -4964,6 +5089,7 @@
|
|||||||
FA1E887E1DF363CD00E808AA /* Filter.cpp in Sources */,
|
FA1E887E1DF363CD00E808AA /* Filter.cpp in Sources */,
|
||||||
FA0B7D281A95902C000E1D17 /* wrap_GlyphData.cpp in Sources */,
|
FA0B7D281A95902C000E1D17 /* wrap_GlyphData.cpp in Sources */,
|
||||||
FA0B7DE21A95902C000E1D17 /* wrap_RandomGenerator.cpp in Sources */,
|
FA0B7DE21A95902C000E1D17 /* wrap_RandomGenerator.cpp in Sources */,
|
||||||
|
FAF6C9F223C2DE2900D7B5BC /* SPVRemapper.cpp in Sources */,
|
||||||
FACA02F61F5E396B0084B28F /* wrap_DataModule.cpp in Sources */,
|
FACA02F61F5E396B0084B28F /* wrap_DataModule.cpp in Sources */,
|
||||||
FA0B79401A958E3B000E1D17 /* utf8.cpp in Sources */,
|
FA0B79401A958E3B000E1D17 /* utf8.cpp in Sources */,
|
||||||
FA0B79241A958E3B000E1D17 /* Exception.cpp in Sources */,
|
FA0B79241A958E3B000E1D17 /* Exception.cpp in Sources */,
|
||||||
@@ -5032,6 +5158,7 @@
|
|||||||
"\"$(SRCROOT)/../../src/libraries\"",
|
"\"$(SRCROOT)/../../src/libraries\"",
|
||||||
"\"$(SRCROOT)/../../src/modules\"",
|
"\"$(SRCROOT)/../../src/modules\"",
|
||||||
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
|
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
|
||||||
|
"\"$(SRCROOT)/../../src/libraries/glslang\"",
|
||||||
);
|
);
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@rpath";
|
LD_RUNPATH_SEARCH_PATHS = "@rpath";
|
||||||
@@ -5098,6 +5225,7 @@
|
|||||||
"\"$(SRCROOT)/../../src/libraries\"",
|
"\"$(SRCROOT)/../../src/libraries\"",
|
||||||
"\"$(SRCROOT)/../../src/modules\"",
|
"\"$(SRCROOT)/../../src/modules\"",
|
||||||
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
|
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
|
||||||
|
"\"$(SRCROOT)/../../src/libraries/glslang\"",
|
||||||
);
|
);
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@rpath";
|
LD_RUNPATH_SEARCH_PATHS = "@rpath";
|
||||||
@@ -5284,6 +5412,7 @@
|
|||||||
"\"$(SRCROOT)/../../src/libraries\"",
|
"\"$(SRCROOT)/../../src/libraries\"",
|
||||||
"\"$(SRCROOT)/../../src/modules\"",
|
"\"$(SRCROOT)/../../src/modules\"",
|
||||||
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
|
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
|
||||||
|
"\"$(SRCROOT)/../../src/libraries/glslang\"",
|
||||||
);
|
);
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "@rpath";
|
LD_RUNPATH_SEARCH_PATHS = "@rpath";
|
||||||
|
|||||||
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2016 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
** of this software and/or associated documentation files (the "Materials"),
|
||||||
|
** to deal in the Materials without restriction, including without limitation
|
||||||
|
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
** and/or sell copies of the Materials, and to permit persons to whom the
|
||||||
|
** Materials are furnished to do so, subject to the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included in
|
||||||
|
** all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
|
||||||
|
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
|
||||||
|
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
|
||||||
|
** IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GLSLextAMD_H
|
||||||
|
#define GLSLextAMD_H
|
||||||
|
|
||||||
|
static const int GLSLextAMDVersion = 100;
|
||||||
|
static const int GLSLextAMDRevision = 7;
|
||||||
|
|
||||||
|
// SPV_AMD_shader_ballot
|
||||||
|
static const char* const E_SPV_AMD_shader_ballot = "SPV_AMD_shader_ballot";
|
||||||
|
|
||||||
|
enum ShaderBallotAMD {
|
||||||
|
ShaderBallotBadAMD = 0, // Don't use
|
||||||
|
|
||||||
|
SwizzleInvocationsAMD = 1,
|
||||||
|
SwizzleInvocationsMaskedAMD = 2,
|
||||||
|
WriteInvocationAMD = 3,
|
||||||
|
MbcntAMD = 4,
|
||||||
|
|
||||||
|
ShaderBallotCountAMD
|
||||||
|
};
|
||||||
|
|
||||||
|
// SPV_AMD_shader_trinary_minmax
|
||||||
|
static const char* const E_SPV_AMD_shader_trinary_minmax = "SPV_AMD_shader_trinary_minmax";
|
||||||
|
|
||||||
|
enum ShaderTrinaryMinMaxAMD {
|
||||||
|
ShaderTrinaryMinMaxBadAMD = 0, // Don't use
|
||||||
|
|
||||||
|
FMin3AMD = 1,
|
||||||
|
UMin3AMD = 2,
|
||||||
|
SMin3AMD = 3,
|
||||||
|
FMax3AMD = 4,
|
||||||
|
UMax3AMD = 5,
|
||||||
|
SMax3AMD = 6,
|
||||||
|
FMid3AMD = 7,
|
||||||
|
UMid3AMD = 8,
|
||||||
|
SMid3AMD = 9,
|
||||||
|
|
||||||
|
ShaderTrinaryMinMaxCountAMD
|
||||||
|
};
|
||||||
|
|
||||||
|
// SPV_AMD_shader_explicit_vertex_parameter
|
||||||
|
static const char* const E_SPV_AMD_shader_explicit_vertex_parameter = "SPV_AMD_shader_explicit_vertex_parameter";
|
||||||
|
|
||||||
|
enum ShaderExplicitVertexParameterAMD {
|
||||||
|
ShaderExplicitVertexParameterBadAMD = 0, // Don't use
|
||||||
|
|
||||||
|
InterpolateAtVertexAMD = 1,
|
||||||
|
|
||||||
|
ShaderExplicitVertexParameterCountAMD
|
||||||
|
};
|
||||||
|
|
||||||
|
// SPV_AMD_gcn_shader
|
||||||
|
static const char* const E_SPV_AMD_gcn_shader = "SPV_AMD_gcn_shader";
|
||||||
|
|
||||||
|
enum GcnShaderAMD {
|
||||||
|
GcnShaderBadAMD = 0, // Don't use
|
||||||
|
|
||||||
|
CubeFaceIndexAMD = 1,
|
||||||
|
CubeFaceCoordAMD = 2,
|
||||||
|
TimeAMD = 3,
|
||||||
|
|
||||||
|
GcnShaderCountAMD
|
||||||
|
};
|
||||||
|
|
||||||
|
// SPV_AMD_gpu_shader_half_float
|
||||||
|
static const char* const E_SPV_AMD_gpu_shader_half_float = "SPV_AMD_gpu_shader_half_float";
|
||||||
|
|
||||||
|
// SPV_AMD_texture_gather_bias_lod
|
||||||
|
static const char* const E_SPV_AMD_texture_gather_bias_lod = "SPV_AMD_texture_gather_bias_lod";
|
||||||
|
|
||||||
|
// SPV_AMD_gpu_shader_int16
|
||||||
|
static const char* const E_SPV_AMD_gpu_shader_int16 = "SPV_AMD_gpu_shader_int16";
|
||||||
|
|
||||||
|
// SPV_AMD_shader_image_load_store_lod
|
||||||
|
static const char* const E_SPV_AMD_shader_image_load_store_lod = "SPV_AMD_shader_image_load_store_lod";
|
||||||
|
|
||||||
|
// SPV_AMD_shader_fragment_mask
|
||||||
|
static const char* const E_SPV_AMD_shader_fragment_mask = "SPV_AMD_shader_fragment_mask";
|
||||||
|
|
||||||
|
// SPV_AMD_gpu_shader_half_float_fetch
|
||||||
|
static const char* const E_SPV_AMD_gpu_shader_half_float_fetch = "SPV_AMD_gpu_shader_half_float_fetch";
|
||||||
|
|
||||||
|
#endif // #ifndef GLSLextAMD_H
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2016 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
** of this software and/or associated documentation files (the "Materials"),
|
||||||
|
** to deal in the Materials without restriction, including without limitation
|
||||||
|
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
** and/or sell copies of the Materials, and to permit persons to whom the
|
||||||
|
** Materials are furnished to do so, subject to the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included in
|
||||||
|
** all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
|
||||||
|
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
|
||||||
|
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
|
||||||
|
** IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GLSLextEXT_H
|
||||||
|
#define GLSLextEXT_H
|
||||||
|
|
||||||
|
static const int GLSLextEXTVersion = 100;
|
||||||
|
static const int GLSLextEXTRevision = 2;
|
||||||
|
|
||||||
|
static const char* const E_SPV_EXT_shader_stencil_export = "SPV_EXT_shader_stencil_export";
|
||||||
|
static const char* const E_SPV_EXT_shader_viewport_index_layer = "SPV_EXT_shader_viewport_index_layer";
|
||||||
|
static const char* const E_SPV_EXT_fragment_fully_covered = "SPV_EXT_fragment_fully_covered";
|
||||||
|
static const char* const E_SPV_EXT_fragment_invocation_density = "SPV_EXT_fragment_invocation_density";
|
||||||
|
static const char* const E_SPV_EXT_demote_to_helper_invocation = "SPV_EXT_demote_to_helper_invocation";
|
||||||
|
|
||||||
|
#endif // #ifndef GLSLextEXT_H
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2016 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
** of this software and/or associated documentation files (the "Materials"),
|
||||||
|
** to deal in the Materials without restriction, including without limitation
|
||||||
|
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
** and/or sell copies of the Materials, and to permit persons to whom the
|
||||||
|
** Materials are furnished to do so, subject to the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included in
|
||||||
|
** all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
|
||||||
|
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
|
||||||
|
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
|
||||||
|
** IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GLSLextKHR_H
|
||||||
|
#define GLSLextKHR_H
|
||||||
|
|
||||||
|
static const int GLSLextKHRVersion = 100;
|
||||||
|
static const int GLSLextKHRRevision = 2;
|
||||||
|
|
||||||
|
static const char* const E_SPV_KHR_shader_ballot = "SPV_KHR_shader_ballot";
|
||||||
|
static const char* const E_SPV_KHR_subgroup_vote = "SPV_KHR_subgroup_vote";
|
||||||
|
static const char* const E_SPV_KHR_device_group = "SPV_KHR_device_group";
|
||||||
|
static const char* const E_SPV_KHR_multiview = "SPV_KHR_multiview";
|
||||||
|
static const char* const E_SPV_KHR_shader_draw_parameters = "SPV_KHR_shader_draw_parameters";
|
||||||
|
static const char* const E_SPV_KHR_16bit_storage = "SPV_KHR_16bit_storage";
|
||||||
|
static const char* const E_SPV_KHR_8bit_storage = "SPV_KHR_8bit_storage";
|
||||||
|
static const char* const E_SPV_KHR_storage_buffer_storage_class = "SPV_KHR_storage_buffer_storage_class";
|
||||||
|
static const char* const E_SPV_KHR_post_depth_coverage = "SPV_KHR_post_depth_coverage";
|
||||||
|
static const char* const E_SPV_KHR_vulkan_memory_model = "SPV_KHR_vulkan_memory_model";
|
||||||
|
static const char* const E_SPV_EXT_physical_storage_buffer = "SPV_EXT_physical_storage_buffer";
|
||||||
|
static const char* const E_SPV_KHR_physical_storage_buffer = "SPV_KHR_physical_storage_buffer";
|
||||||
|
static const char* const E_SPV_EXT_fragment_shader_interlock = "SPV_EXT_fragment_shader_interlock";
|
||||||
|
static const char* const E_SPV_KHR_shader_clock = "SPV_KHR_shader_clock";
|
||||||
|
|
||||||
|
#endif // #ifndef GLSLextKHR_H
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2017 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
** of this software and/or associated documentation files (the "Materials"),
|
||||||
|
** to deal in the Materials without restriction, including without limitation
|
||||||
|
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
** and/or sell copies of the Materials, and to permit persons to whom the
|
||||||
|
** Materials are furnished to do so, subject to the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included in
|
||||||
|
** all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
|
||||||
|
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
|
||||||
|
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
|
||||||
|
** IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GLSLextNV_H
|
||||||
|
#define GLSLextNV_H
|
||||||
|
|
||||||
|
enum BuiltIn;
|
||||||
|
enum Decoration;
|
||||||
|
enum Op;
|
||||||
|
enum Capability;
|
||||||
|
|
||||||
|
static const int GLSLextNVVersion = 100;
|
||||||
|
static const int GLSLextNVRevision = 11;
|
||||||
|
|
||||||
|
//SPV_NV_sample_mask_override_coverage
|
||||||
|
const char* const E_SPV_NV_sample_mask_override_coverage = "SPV_NV_sample_mask_override_coverage";
|
||||||
|
|
||||||
|
//SPV_NV_geometry_shader_passthrough
|
||||||
|
const char* const E_SPV_NV_geometry_shader_passthrough = "SPV_NV_geometry_shader_passthrough";
|
||||||
|
|
||||||
|
//SPV_NV_viewport_array2
|
||||||
|
const char* const E_SPV_NV_viewport_array2 = "SPV_NV_viewport_array2";
|
||||||
|
const char* const E_ARB_shader_viewport_layer_array = "SPV_ARB_shader_viewport_layer_array";
|
||||||
|
|
||||||
|
//SPV_NV_stereo_view_rendering
|
||||||
|
const char* const E_SPV_NV_stereo_view_rendering = "SPV_NV_stereo_view_rendering";
|
||||||
|
|
||||||
|
//SPV_NVX_multiview_per_view_attributes
|
||||||
|
const char* const E_SPV_NVX_multiview_per_view_attributes = "SPV_NVX_multiview_per_view_attributes";
|
||||||
|
|
||||||
|
//SPV_NV_shader_subgroup_partitioned
|
||||||
|
const char* const E_SPV_NV_shader_subgroup_partitioned = "SPV_NV_shader_subgroup_partitioned";
|
||||||
|
|
||||||
|
//SPV_NV_fragment_shader_barycentric
|
||||||
|
const char* const E_SPV_NV_fragment_shader_barycentric = "SPV_NV_fragment_shader_barycentric";
|
||||||
|
|
||||||
|
//SPV_NV_compute_shader_derivatives
|
||||||
|
const char* const E_SPV_NV_compute_shader_derivatives = "SPV_NV_compute_shader_derivatives";
|
||||||
|
|
||||||
|
//SPV_NV_shader_image_footprint
|
||||||
|
const char* const E_SPV_NV_shader_image_footprint = "SPV_NV_shader_image_footprint";
|
||||||
|
|
||||||
|
//SPV_NV_mesh_shader
|
||||||
|
const char* const E_SPV_NV_mesh_shader = "SPV_NV_mesh_shader";
|
||||||
|
|
||||||
|
//SPV_NV_raytracing
|
||||||
|
const char* const E_SPV_NV_ray_tracing = "SPV_NV_ray_tracing";
|
||||||
|
|
||||||
|
//SPV_NV_shading_rate
|
||||||
|
const char* const E_SPV_NV_shading_rate = "SPV_NV_shading_rate";
|
||||||
|
|
||||||
|
//SPV_NV_cooperative_matrix
|
||||||
|
const char* const E_SPV_NV_cooperative_matrix = "SPV_NV_cooperative_matrix";
|
||||||
|
|
||||||
|
//SPV_NV_shader_sm_builtins
|
||||||
|
const char* const E_SPV_NV_shader_sm_builtins = "SPV_NV_shader_sm_builtins";
|
||||||
|
|
||||||
|
#endif // #ifndef GLSLextNV_H
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2016 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
** of this software and/or associated documentation files (the "Materials"),
|
||||||
|
** to deal in the Materials without restriction, including without limitation
|
||||||
|
** the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
** and/or sell copies of the Materials, and to permit persons to whom the
|
||||||
|
** Materials are furnished to do so, subject to the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included in
|
||||||
|
** all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS
|
||||||
|
** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND
|
||||||
|
** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||||
|
** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
** THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
** FROM,OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE USE OR OTHER DEALINGS
|
||||||
|
** IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GLSLstd450_H
|
||||||
|
#define GLSLstd450_H
|
||||||
|
|
||||||
|
static const int GLSLstd450Version = 100;
|
||||||
|
static const int GLSLstd450Revision = 1;
|
||||||
|
|
||||||
|
enum GLSLstd450 {
|
||||||
|
GLSLstd450Bad = 0, // Don't use
|
||||||
|
|
||||||
|
GLSLstd450Round = 1,
|
||||||
|
GLSLstd450RoundEven = 2,
|
||||||
|
GLSLstd450Trunc = 3,
|
||||||
|
GLSLstd450FAbs = 4,
|
||||||
|
GLSLstd450SAbs = 5,
|
||||||
|
GLSLstd450FSign = 6,
|
||||||
|
GLSLstd450SSign = 7,
|
||||||
|
GLSLstd450Floor = 8,
|
||||||
|
GLSLstd450Ceil = 9,
|
||||||
|
GLSLstd450Fract = 10,
|
||||||
|
|
||||||
|
GLSLstd450Radians = 11,
|
||||||
|
GLSLstd450Degrees = 12,
|
||||||
|
GLSLstd450Sin = 13,
|
||||||
|
GLSLstd450Cos = 14,
|
||||||
|
GLSLstd450Tan = 15,
|
||||||
|
GLSLstd450Asin = 16,
|
||||||
|
GLSLstd450Acos = 17,
|
||||||
|
GLSLstd450Atan = 18,
|
||||||
|
GLSLstd450Sinh = 19,
|
||||||
|
GLSLstd450Cosh = 20,
|
||||||
|
GLSLstd450Tanh = 21,
|
||||||
|
GLSLstd450Asinh = 22,
|
||||||
|
GLSLstd450Acosh = 23,
|
||||||
|
GLSLstd450Atanh = 24,
|
||||||
|
GLSLstd450Atan2 = 25,
|
||||||
|
|
||||||
|
GLSLstd450Pow = 26,
|
||||||
|
GLSLstd450Exp = 27,
|
||||||
|
GLSLstd450Log = 28,
|
||||||
|
GLSLstd450Exp2 = 29,
|
||||||
|
GLSLstd450Log2 = 30,
|
||||||
|
GLSLstd450Sqrt = 31,
|
||||||
|
GLSLstd450InverseSqrt = 32,
|
||||||
|
|
||||||
|
GLSLstd450Determinant = 33,
|
||||||
|
GLSLstd450MatrixInverse = 34,
|
||||||
|
|
||||||
|
GLSLstd450Modf = 35, // second operand needs an OpVariable to write to
|
||||||
|
GLSLstd450ModfStruct = 36, // no OpVariable operand
|
||||||
|
GLSLstd450FMin = 37,
|
||||||
|
GLSLstd450UMin = 38,
|
||||||
|
GLSLstd450SMin = 39,
|
||||||
|
GLSLstd450FMax = 40,
|
||||||
|
GLSLstd450UMax = 41,
|
||||||
|
GLSLstd450SMax = 42,
|
||||||
|
GLSLstd450FClamp = 43,
|
||||||
|
GLSLstd450UClamp = 44,
|
||||||
|
GLSLstd450SClamp = 45,
|
||||||
|
GLSLstd450FMix = 46,
|
||||||
|
GLSLstd450IMix = 47, // Reserved
|
||||||
|
GLSLstd450Step = 48,
|
||||||
|
GLSLstd450SmoothStep = 49,
|
||||||
|
|
||||||
|
GLSLstd450Fma = 50,
|
||||||
|
GLSLstd450Frexp = 51, // second operand needs an OpVariable to write to
|
||||||
|
GLSLstd450FrexpStruct = 52, // no OpVariable operand
|
||||||
|
GLSLstd450Ldexp = 53,
|
||||||
|
|
||||||
|
GLSLstd450PackSnorm4x8 = 54,
|
||||||
|
GLSLstd450PackUnorm4x8 = 55,
|
||||||
|
GLSLstd450PackSnorm2x16 = 56,
|
||||||
|
GLSLstd450PackUnorm2x16 = 57,
|
||||||
|
GLSLstd450PackHalf2x16 = 58,
|
||||||
|
GLSLstd450PackDouble2x32 = 59,
|
||||||
|
GLSLstd450UnpackSnorm2x16 = 60,
|
||||||
|
GLSLstd450UnpackUnorm2x16 = 61,
|
||||||
|
GLSLstd450UnpackHalf2x16 = 62,
|
||||||
|
GLSLstd450UnpackSnorm4x8 = 63,
|
||||||
|
GLSLstd450UnpackUnorm4x8 = 64,
|
||||||
|
GLSLstd450UnpackDouble2x32 = 65,
|
||||||
|
|
||||||
|
GLSLstd450Length = 66,
|
||||||
|
GLSLstd450Distance = 67,
|
||||||
|
GLSLstd450Cross = 68,
|
||||||
|
GLSLstd450Normalize = 69,
|
||||||
|
GLSLstd450FaceForward = 70,
|
||||||
|
GLSLstd450Reflect = 71,
|
||||||
|
GLSLstd450Refract = 72,
|
||||||
|
|
||||||
|
GLSLstd450FindILsb = 73,
|
||||||
|
GLSLstd450FindSMsb = 74,
|
||||||
|
GLSLstd450FindUMsb = 75,
|
||||||
|
|
||||||
|
GLSLstd450InterpolateAtCentroid = 76,
|
||||||
|
GLSLstd450InterpolateAtSample = 77,
|
||||||
|
GLSLstd450InterpolateAtOffset = 78,
|
||||||
|
|
||||||
|
GLSLstd450NMin = 79,
|
||||||
|
GLSLstd450NMax = 80,
|
||||||
|
GLSLstd450NClamp = 81,
|
||||||
|
|
||||||
|
GLSLstd450Count
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // #ifndef GLSLstd450_H
|
||||||
Executable
+8347
File diff suppressed because it is too large
Load Diff
Executable
+61
@@ -0,0 +1,61 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2014 LunarG, Inc.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && _MSC_VER >= 1900
|
||||||
|
#pragma warning(disable : 4464) // relative include path contains '..'
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "SpvTools.h"
|
||||||
|
#include "glslang/Include/intermediate.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
void GetSpirvVersion(std::string&);
|
||||||
|
int GetSpirvGeneratorVersion();
|
||||||
|
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
|
SpvOptions* options = nullptr);
|
||||||
|
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
|
spv::SpvBuildLogger* logger, SpvOptions* options = nullptr);
|
||||||
|
void OutputSpvBin(const std::vector<unsigned int>& spirv, const char* baseName);
|
||||||
|
void OutputSpvHex(const std::vector<unsigned int>& spirv, const char* baseName, const char* varName);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2016 Google, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// The SPIR-V spec requires code blocks to appear in an order satisfying the
|
||||||
|
// dominator-tree direction (ie, dominator before the dominated). This is,
|
||||||
|
// actually, easy to achieve: any pre-order CFG traversal algorithm will do it.
|
||||||
|
// Because such algorithms visit a block only after traversing some path to it
|
||||||
|
// from the root, they necessarily visit the block's idom first.
|
||||||
|
//
|
||||||
|
// But not every graph-traversal algorithm outputs blocks in an order that
|
||||||
|
// appears logical to human readers. The problem is that unrelated branches may
|
||||||
|
// be interspersed with each other, and merge blocks may come before some of the
|
||||||
|
// branches being merged.
|
||||||
|
//
|
||||||
|
// A good, human-readable order of blocks may be achieved by performing
|
||||||
|
// depth-first search but delaying merge nodes until after all their branches
|
||||||
|
// have been visited. This is implemented below by the inReadableOrder()
|
||||||
|
// function.
|
||||||
|
|
||||||
|
#include "spvIR.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
using spv::Block;
|
||||||
|
using spv::Id;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// Traverses CFG in a readable order, invoking a pre-set callback on each block.
|
||||||
|
// Use by calling visit() on the root block.
|
||||||
|
class ReadableOrderTraverser {
|
||||||
|
public:
|
||||||
|
ReadableOrderTraverser(std::function<void(Block*, spv::ReachReason, Block*)> callback)
|
||||||
|
: callback_(callback) {}
|
||||||
|
// Visits the block if it hasn't been visited already and isn't currently
|
||||||
|
// being delayed. Invokes callback(block, why, header), then descends into its
|
||||||
|
// successors. Delays merge-block and continue-block processing until all
|
||||||
|
// the branches have been completed. If |block| is an unreachable merge block or
|
||||||
|
// an unreachable continue target, then |header| is the corresponding header block.
|
||||||
|
void visit(Block* block, spv::ReachReason why, Block* header)
|
||||||
|
{
|
||||||
|
assert(block);
|
||||||
|
if (why == spv::ReachViaControlFlow) {
|
||||||
|
reachableViaControlFlow_.insert(block);
|
||||||
|
}
|
||||||
|
if (visited_.count(block) || delayed_.count(block))
|
||||||
|
return;
|
||||||
|
callback_(block, why, header);
|
||||||
|
visited_.insert(block);
|
||||||
|
Block* mergeBlock = nullptr;
|
||||||
|
Block* continueBlock = nullptr;
|
||||||
|
auto mergeInst = block->getMergeInstruction();
|
||||||
|
if (mergeInst) {
|
||||||
|
Id mergeId = mergeInst->getIdOperand(0);
|
||||||
|
mergeBlock = block->getParent().getParent().getInstruction(mergeId)->getBlock();
|
||||||
|
delayed_.insert(mergeBlock);
|
||||||
|
if (mergeInst->getOpCode() == spv::OpLoopMerge) {
|
||||||
|
Id continueId = mergeInst->getIdOperand(1);
|
||||||
|
continueBlock =
|
||||||
|
block->getParent().getParent().getInstruction(continueId)->getBlock();
|
||||||
|
delayed_.insert(continueBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (why == spv::ReachViaControlFlow) {
|
||||||
|
const auto& successors = block->getSuccessors();
|
||||||
|
for (auto it = successors.cbegin(); it != successors.cend(); ++it)
|
||||||
|
visit(*it, why, nullptr);
|
||||||
|
}
|
||||||
|
if (continueBlock) {
|
||||||
|
const spv::ReachReason continueWhy =
|
||||||
|
(reachableViaControlFlow_.count(continueBlock) > 0)
|
||||||
|
? spv::ReachViaControlFlow
|
||||||
|
: spv::ReachDeadContinue;
|
||||||
|
delayed_.erase(continueBlock);
|
||||||
|
visit(continueBlock, continueWhy, block);
|
||||||
|
}
|
||||||
|
if (mergeBlock) {
|
||||||
|
const spv::ReachReason mergeWhy =
|
||||||
|
(reachableViaControlFlow_.count(mergeBlock) > 0)
|
||||||
|
? spv::ReachViaControlFlow
|
||||||
|
: spv::ReachDeadMerge;
|
||||||
|
delayed_.erase(mergeBlock);
|
||||||
|
visit(mergeBlock, mergeWhy, block);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::function<void(Block*, spv::ReachReason, Block*)> callback_;
|
||||||
|
// Whether a block has already been visited or is being delayed.
|
||||||
|
std::unordered_set<Block *> visited_, delayed_;
|
||||||
|
|
||||||
|
// The set of blocks that actually are reached via control flow.
|
||||||
|
std::unordered_set<Block *> reachableViaControlFlow_;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void spv::inReadableOrder(Block* root, std::function<void(Block*, spv::ReachReason, Block*)> callback)
|
||||||
|
{
|
||||||
|
ReadableOrderTraverser(callback).visit(root, spv::ReachViaControlFlow, nullptr);
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2016 Google, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// 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 <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
void SpvBuildLogger::tbdFunctionality(const std::string& f)
|
||||||
|
{
|
||||||
|
if (std::find(std::begin(tbdFeatures), std::end(tbdFeatures), f) == std::end(tbdFeatures))
|
||||||
|
tbdFeatures.push_back(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpvBuildLogger::missingFunctionality(const std::string& f)
|
||||||
|
{
|
||||||
|
if (std::find(std::begin(missingFeatures), std::end(missingFeatures), f) == std::end(missingFeatures))
|
||||||
|
missingFeatures.push_back(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SpvBuildLogger::getAllMessages() const {
|
||||||
|
std::ostringstream messages;
|
||||||
|
for (auto it = tbdFeatures.cbegin(); it != tbdFeatures.cend(); ++it)
|
||||||
|
messages << "TBD functionality: " << *it << "\n";
|
||||||
|
for (auto it = missingFeatures.cbegin(); it != missingFeatures.cend(); ++it)
|
||||||
|
messages << "Missing functionality: " << *it << "\n";
|
||||||
|
for (auto it = warnings.cbegin(); it != warnings.cend(); ++it)
|
||||||
|
messages << "warning: " << *it << "\n";
|
||||||
|
for (auto it = errors.cbegin(); it != errors.cend(); ++it)
|
||||||
|
messages << "error: " << *it << "\n";
|
||||||
|
return messages.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end spv namespace
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2016 Google, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of Google Inc. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
#ifndef GLSLANG_SPIRV_LOGGER_H
|
||||||
|
#define GLSLANG_SPIRV_LOGGER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
// A class for holding all SPIR-V build status messages, including
|
||||||
|
// missing/TBD functionalities, warnings, and errors.
|
||||||
|
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.
|
||||||
|
void missingFunctionality(const std::string& f);
|
||||||
|
|
||||||
|
// Logs a warning.
|
||||||
|
void warning(const std::string& w) { warnings.push_back(w); }
|
||||||
|
// Logs an error.
|
||||||
|
void error(const std::string& e) { errors.push_back(e); }
|
||||||
|
|
||||||
|
// Returns all messages accumulated in the order of:
|
||||||
|
// TBD functionalities, missing functionalities, warnings, errors.
|
||||||
|
std::string getAllMessages() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
private:
|
||||||
|
SpvBuildLogger(const SpvBuildLogger&);
|
||||||
|
|
||||||
|
std::vector<std::string> tbdFeatures;
|
||||||
|
std::vector<std::string> missingFeatures;
|
||||||
|
std::vector<std::string> warnings;
|
||||||
|
std::vector<std::string> errors;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end spv namespace
|
||||||
|
|
||||||
|
#endif // GLSLANG_SPIRV_LOGGER_H
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,304 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2015 LunarG, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef SPIRVREMAPPER_H
|
||||||
|
#define SPIRVREMAPPER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
// MSVC defines __cplusplus as an older value, even when it supports almost all of 11.
|
||||||
|
// We handle that here by making our own symbol.
|
||||||
|
#if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1700)
|
||||||
|
# define use_cpp11 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class spirvbin_base_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Options {
|
||||||
|
NONE = 0,
|
||||||
|
STRIP = (1<<0),
|
||||||
|
MAP_TYPES = (1<<1),
|
||||||
|
MAP_NAMES = (1<<2),
|
||||||
|
MAP_FUNCS = (1<<3),
|
||||||
|
DCE_FUNCS = (1<<4),
|
||||||
|
DCE_VARS = (1<<5),
|
||||||
|
DCE_TYPES = (1<<6),
|
||||||
|
OPT_LOADSTORE = (1<<7),
|
||||||
|
OPT_FWD_LS = (1<<8), // EXPERIMENTAL: PRODUCES INVALID SCHEMA-0 SPIRV
|
||||||
|
MAP_ALL = (MAP_TYPES | MAP_NAMES | MAP_FUNCS),
|
||||||
|
DCE_ALL = (DCE_FUNCS | DCE_VARS | DCE_TYPES),
|
||||||
|
OPT_ALL = (OPT_LOADSTORE),
|
||||||
|
|
||||||
|
ALL_BUT_STRIP = (MAP_ALL | DCE_ALL | OPT_ALL),
|
||||||
|
DO_EVERYTHING = (STRIP | ALL_BUT_STRIP)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace SPV
|
||||||
|
|
||||||
|
#if !defined (use_cpp11)
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
class spirvbin_t : public spirvbin_base_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
spirvbin_t(int /*verbose = 0*/) { }
|
||||||
|
|
||||||
|
void remap(std::vector<std::uint32_t>& /*spv*/, unsigned int /*opts = 0*/)
|
||||||
|
{
|
||||||
|
printf("Tool not compiled for C++11, which is required for SPIR-V remapping.\n");
|
||||||
|
exit(5);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace SPV
|
||||||
|
|
||||||
|
#else // defined (use_cpp11)
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "spirv.hpp"
|
||||||
|
#include "spvIR.h"
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
// class to hold SPIR-V binary data for remapping, DCE, and debug stripping
|
||||||
|
class spirvbin_t : public spirvbin_base_t
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
spirvbin_t(int verbose = 0) : entryPoint(spv::NoResult), largestNewId(0), verbose(verbose), errorLatch(false)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
virtual ~spirvbin_t() { }
|
||||||
|
|
||||||
|
// remap on an existing binary in memory
|
||||||
|
void remap(std::vector<std::uint32_t>& spv, std::uint32_t opts = DO_EVERYTHING);
|
||||||
|
|
||||||
|
// Type for error/log handler functions
|
||||||
|
typedef std::function<void(const std::string&)> errorfn_t;
|
||||||
|
typedef std::function<void(const std::string&)> logfn_t;
|
||||||
|
|
||||||
|
// Register error/log handling functions (can be lambda fn / functor / etc)
|
||||||
|
static void registerErrorHandler(errorfn_t handler) { errorHandler = handler; }
|
||||||
|
static void registerLogHandler(logfn_t handler) { logHandler = handler; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// This can be overridden to provide other message behavior if needed
|
||||||
|
virtual void msg(int minVerbosity, int indent, const std::string& txt) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Local to global, or global to local ID map
|
||||||
|
typedef std::unordered_map<spv::Id, spv::Id> idmap_t;
|
||||||
|
typedef std::unordered_set<spv::Id> idset_t;
|
||||||
|
typedef std::unordered_map<spv::Id, int> blockmap_t;
|
||||||
|
|
||||||
|
void remap(std::uint32_t opts = DO_EVERYTHING);
|
||||||
|
|
||||||
|
// Map of names to IDs
|
||||||
|
typedef std::unordered_map<std::string, spv::Id> namemap_t;
|
||||||
|
|
||||||
|
typedef std::uint32_t spirword_t;
|
||||||
|
|
||||||
|
typedef std::pair<unsigned, unsigned> range_t;
|
||||||
|
typedef std::function<void(spv::Id&)> idfn_t;
|
||||||
|
typedef std::function<bool(spv::Op, unsigned start)> instfn_t;
|
||||||
|
|
||||||
|
// Special Values for ID map:
|
||||||
|
static const spv::Id unmapped; // unchanged from default value
|
||||||
|
static const spv::Id unused; // unused ID
|
||||||
|
static const int header_size; // SPIR header = 5 words
|
||||||
|
|
||||||
|
class id_iterator_t;
|
||||||
|
|
||||||
|
// For mapping type entries between different shaders
|
||||||
|
typedef std::vector<spirword_t> typeentry_t;
|
||||||
|
typedef std::map<spv::Id, typeentry_t> globaltypes_t;
|
||||||
|
|
||||||
|
// A set that preserves position order, and a reverse map
|
||||||
|
typedef std::set<int> posmap_t;
|
||||||
|
typedef std::unordered_map<spv::Id, int> posmap_rev_t;
|
||||||
|
|
||||||
|
// Maps and ID to the size of its base type, if known.
|
||||||
|
typedef std::unordered_map<spv::Id, unsigned> typesize_map_t;
|
||||||
|
|
||||||
|
// handle error
|
||||||
|
void error(const std::string& txt) const { errorLatch = true; errorHandler(txt); }
|
||||||
|
|
||||||
|
bool isConstOp(spv::Op opCode) const;
|
||||||
|
bool isTypeOp(spv::Op opCode) const;
|
||||||
|
bool isStripOp(spv::Op opCode) const;
|
||||||
|
bool isFlowCtrl(spv::Op opCode) const;
|
||||||
|
range_t literalRange(spv::Op opCode) const;
|
||||||
|
range_t typeRange(spv::Op opCode) const;
|
||||||
|
range_t constRange(spv::Op opCode) const;
|
||||||
|
unsigned typeSizeInWords(spv::Id id) const;
|
||||||
|
unsigned idTypeSizeInWords(spv::Id id) const;
|
||||||
|
|
||||||
|
spv::Id& asId(unsigned word) { return spv[word]; }
|
||||||
|
const spv::Id& asId(unsigned word) const { return spv[word]; }
|
||||||
|
spv::Op asOpCode(unsigned word) const { return opOpCode(spv[word]); }
|
||||||
|
std::uint32_t asOpCodeHash(unsigned word);
|
||||||
|
spv::Decoration asDecoration(unsigned word) const { return spv::Decoration(spv[word]); }
|
||||||
|
unsigned asWordCount(unsigned word) const { return opWordCount(spv[word]); }
|
||||||
|
spv::Id asTypeConstId(unsigned word) const { return asId(word + (isTypeOp(asOpCode(word)) ? 1 : 2)); }
|
||||||
|
unsigned idPos(spv::Id id) const;
|
||||||
|
|
||||||
|
static unsigned opWordCount(spirword_t data) { return data >> spv::WordCountShift; }
|
||||||
|
static spv::Op opOpCode(spirword_t data) { return spv::Op(data & spv::OpCodeMask); }
|
||||||
|
|
||||||
|
// Header access & set methods
|
||||||
|
spirword_t magic() const { return spv[0]; } // return magic number
|
||||||
|
spirword_t bound() const { return spv[3]; } // return Id bound from header
|
||||||
|
spirword_t bound(spirword_t b) { return spv[3] = b; }
|
||||||
|
spirword_t genmagic() const { return spv[2]; } // generator magic
|
||||||
|
spirword_t genmagic(spirword_t m) { return spv[2] = m; }
|
||||||
|
spirword_t schemaNum() const { return spv[4]; } // schema number from header
|
||||||
|
|
||||||
|
// Mapping fns: get
|
||||||
|
spv::Id localId(spv::Id id) const { return idMapL[id]; }
|
||||||
|
|
||||||
|
// Mapping fns: set
|
||||||
|
inline spv::Id localId(spv::Id id, spv::Id newId);
|
||||||
|
void countIds(spv::Id id);
|
||||||
|
|
||||||
|
// Return next unused new local ID.
|
||||||
|
// NOTE: boost::dynamic_bitset would be more efficient due to find_next(),
|
||||||
|
// which std::vector<bool> doens't have.
|
||||||
|
inline spv::Id nextUnusedId(spv::Id id);
|
||||||
|
|
||||||
|
void buildLocalMaps();
|
||||||
|
std::string literalString(unsigned word) const; // Return literal as a std::string
|
||||||
|
int literalStringWords(const std::string& str) const { return (int(str.size())+4)/4; }
|
||||||
|
|
||||||
|
bool isNewIdMapped(spv::Id newId) const { return isMapped(newId); }
|
||||||
|
bool isOldIdUnmapped(spv::Id oldId) const { return localId(oldId) == unmapped; }
|
||||||
|
bool isOldIdUnused(spv::Id oldId) const { return localId(oldId) == unused; }
|
||||||
|
bool isOldIdMapped(spv::Id oldId) const { return !isOldIdUnused(oldId) && !isOldIdUnmapped(oldId); }
|
||||||
|
bool isFunction(spv::Id oldId) const { return fnPos.find(oldId) != fnPos.end(); }
|
||||||
|
|
||||||
|
// bool matchType(const globaltypes_t& globalTypes, spv::Id lt, spv::Id gt) const;
|
||||||
|
// spv::Id findType(const globaltypes_t& globalTypes, spv::Id lt) const;
|
||||||
|
std::uint32_t hashType(unsigned typeStart) const;
|
||||||
|
|
||||||
|
spirvbin_t& process(instfn_t, idfn_t, unsigned begin = 0, unsigned end = 0);
|
||||||
|
int processInstruction(unsigned word, instfn_t, idfn_t);
|
||||||
|
|
||||||
|
void validate() const;
|
||||||
|
void mapTypeConst();
|
||||||
|
void mapFnBodies();
|
||||||
|
void optLoadStore();
|
||||||
|
void dceFuncs();
|
||||||
|
void dceVars();
|
||||||
|
void dceTypes();
|
||||||
|
void mapNames();
|
||||||
|
void foldIds(); // fold IDs to smallest space
|
||||||
|
void forwardLoadStores(); // load store forwarding (EXPERIMENTAL)
|
||||||
|
void offsetIds(); // create relative offset IDs
|
||||||
|
|
||||||
|
void applyMap(); // remap per local name map
|
||||||
|
void mapRemainder(); // map any IDs we haven't touched yet
|
||||||
|
void stripDebug(); // strip all debug info
|
||||||
|
void stripDeadRefs(); // strips debug info for now-dead references after DCE
|
||||||
|
void strip(); // remove debug symbols
|
||||||
|
|
||||||
|
std::vector<spirword_t> spv; // SPIR words
|
||||||
|
|
||||||
|
namemap_t nameMap; // ID names from OpName
|
||||||
|
|
||||||
|
// Since we want to also do binary ops, we can't use std::vector<bool>. we could use
|
||||||
|
// boost::dynamic_bitset, but we're trying to avoid a boost dependency.
|
||||||
|
typedef std::uint64_t bits_t;
|
||||||
|
std::vector<bits_t> mapped; // which new IDs have been mapped
|
||||||
|
static const int mBits = sizeof(bits_t) * 4;
|
||||||
|
|
||||||
|
bool isMapped(spv::Id id) const { return id < maxMappedId() && ((mapped[id/mBits] & (1LL<<(id%mBits))) != 0); }
|
||||||
|
void setMapped(spv::Id id) { resizeMapped(id); mapped[id/mBits] |= (1LL<<(id%mBits)); }
|
||||||
|
void resizeMapped(spv::Id id) { if (id >= maxMappedId()) mapped.resize(id/mBits+1, 0); }
|
||||||
|
size_t maxMappedId() const { return mapped.size() * mBits; }
|
||||||
|
|
||||||
|
// Add a strip range for a given instruction starting at 'start'
|
||||||
|
// Note: avoiding brace initializers to please older versions os MSVC.
|
||||||
|
void stripInst(unsigned start) { stripRange.push_back(range_t(start, start + asWordCount(start))); }
|
||||||
|
|
||||||
|
// Function start and end. use unordered_map because we'll have
|
||||||
|
// many fewer functions than IDs.
|
||||||
|
std::unordered_map<spv::Id, range_t> fnPos;
|
||||||
|
|
||||||
|
// Which functions are called, anywhere in the module, with a call count
|
||||||
|
std::unordered_map<spv::Id, int> fnCalls;
|
||||||
|
|
||||||
|
posmap_t typeConstPos; // word positions that define types & consts (ordered)
|
||||||
|
posmap_rev_t idPosR; // reverse map from IDs to positions
|
||||||
|
typesize_map_t idTypeSizeMap; // maps each ID to its type size, if known.
|
||||||
|
|
||||||
|
std::vector<spv::Id> idMapL; // ID {M}ap from {L}ocal to {G}lobal IDs
|
||||||
|
|
||||||
|
spv::Id entryPoint; // module entry point
|
||||||
|
spv::Id largestNewId; // biggest new ID we have mapped anything to
|
||||||
|
|
||||||
|
// Sections of the binary to strip, given as [begin,end)
|
||||||
|
std::vector<range_t> stripRange;
|
||||||
|
|
||||||
|
// processing options:
|
||||||
|
std::uint32_t options;
|
||||||
|
int verbose; // verbosity level
|
||||||
|
|
||||||
|
// Error latch: this is set if the error handler is ever executed. It would be better to
|
||||||
|
// use a try/catch block and throw, but that's not desired for certain environments, so
|
||||||
|
// this is the alternative.
|
||||||
|
mutable bool errorLatch;
|
||||||
|
|
||||||
|
static errorfn_t errorHandler;
|
||||||
|
static logfn_t logHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace SPV
|
||||||
|
|
||||||
|
#endif // defined (use_cpp11)
|
||||||
|
#endif // SPIRVREMAPPER_H
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,790 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
|
// Copyright (C) 2017 ARM Limited.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// "Builder" is an interface to fully build SPIR-V IR. Allocate one of
|
||||||
|
// these to build (a thread safe) internal SPIR-V representation (IR),
|
||||||
|
// and then dump it as a binary stream according to the SPIR-V specification.
|
||||||
|
//
|
||||||
|
// A Builder has a 1:1 relationship with a SPIR-V module.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef SpvBuilder_H
|
||||||
|
#define SpvBuilder_H
|
||||||
|
|
||||||
|
#include "Logger.h"
|
||||||
|
#include "spirv.hpp"
|
||||||
|
#include "spvIR.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <set>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stack>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
Spv_1_0 = (1 << 16),
|
||||||
|
Spv_1_1 = (1 << 16) | (1 << 8),
|
||||||
|
Spv_1_2 = (1 << 16) | (2 << 8),
|
||||||
|
Spv_1_3 = (1 << 16) | (3 << 8),
|
||||||
|
Spv_1_4 = (1 << 16) | (4 << 8),
|
||||||
|
Spv_1_5 = (1 << 16) | (5 << 8),
|
||||||
|
} SpvVersion;
|
||||||
|
|
||||||
|
class Builder {
|
||||||
|
public:
|
||||||
|
Builder(unsigned int spvVersion, unsigned int userNumber, SpvBuildLogger* logger);
|
||||||
|
virtual ~Builder();
|
||||||
|
|
||||||
|
static const int maxMatrixSize = 4;
|
||||||
|
|
||||||
|
unsigned int getSpvVersion() const { return spvVersion; }
|
||||||
|
|
||||||
|
void setSource(spv::SourceLanguage lang, int version)
|
||||||
|
{
|
||||||
|
source = lang;
|
||||||
|
sourceVersion = version;
|
||||||
|
}
|
||||||
|
spv::Id getStringId(const std::string& str)
|
||||||
|
{
|
||||||
|
auto sItr = stringIds.find(str);
|
||||||
|
if (sItr != stringIds.end())
|
||||||
|
return sItr->second;
|
||||||
|
spv::Id strId = getUniqueId();
|
||||||
|
Instruction* fileString = new Instruction(strId, NoType, OpString);
|
||||||
|
const char* file_c_str = str.c_str();
|
||||||
|
fileString->addStringOperand(file_c_str);
|
||||||
|
strings.push_back(std::unique_ptr<Instruction>(fileString));
|
||||||
|
stringIds[file_c_str] = strId;
|
||||||
|
return strId;
|
||||||
|
}
|
||||||
|
void setSourceFile(const std::string& file)
|
||||||
|
{
|
||||||
|
sourceFileStringId = getStringId(file);
|
||||||
|
}
|
||||||
|
void setSourceText(const std::string& text) { sourceText = text; }
|
||||||
|
void addSourceExtension(const char* ext) { sourceExtensions.push_back(ext); }
|
||||||
|
void addModuleProcessed(const std::string& p) { moduleProcesses.push_back(p.c_str()); }
|
||||||
|
void setEmitOpLines() { emitOpLines = true; }
|
||||||
|
void addExtension(const char* ext) { extensions.insert(ext); }
|
||||||
|
void removeExtension(const char* ext)
|
||||||
|
{
|
||||||
|
extensions.erase(ext);
|
||||||
|
}
|
||||||
|
void addIncorporatedExtension(const char* ext, SpvVersion incorporatedVersion)
|
||||||
|
{
|
||||||
|
if (getSpvVersion() < static_cast<unsigned>(incorporatedVersion))
|
||||||
|
addExtension(ext);
|
||||||
|
}
|
||||||
|
void promoteIncorporatedExtension(const char* baseExt, const char* promoExt, SpvVersion incorporatedVersion)
|
||||||
|
{
|
||||||
|
removeExtension(baseExt);
|
||||||
|
addIncorporatedExtension(promoExt, incorporatedVersion);
|
||||||
|
}
|
||||||
|
void addInclude(const std::string& name, const std::string& text)
|
||||||
|
{
|
||||||
|
spv::Id incId = getStringId(name);
|
||||||
|
includeFiles[incId] = &text;
|
||||||
|
}
|
||||||
|
Id import(const char*);
|
||||||
|
void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem)
|
||||||
|
{
|
||||||
|
addressModel = addr;
|
||||||
|
memoryModel = mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addCapability(spv::Capability cap) { capabilities.insert(cap); }
|
||||||
|
|
||||||
|
// To get a new <id> for anything needing a new one.
|
||||||
|
Id getUniqueId() { return ++uniqueId; }
|
||||||
|
|
||||||
|
// To get a set of new <id>s, e.g., for a set of function parameters
|
||||||
|
Id getUniqueIds(int numIds)
|
||||||
|
{
|
||||||
|
Id id = uniqueId + 1;
|
||||||
|
uniqueId += numIds;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate OpLine for non-filename-based #line directives (ie no filename
|
||||||
|
// seen yet): Log the current line, and if different than the last one,
|
||||||
|
// issue a new OpLine using the new line and current source file name.
|
||||||
|
void setLine(int line);
|
||||||
|
|
||||||
|
// If filename null, generate OpLine for non-filename-based line directives,
|
||||||
|
// else do filename-based: Log the current line and file, and if different
|
||||||
|
// than the last one, issue a new OpLine using the new line and file
|
||||||
|
// name.
|
||||||
|
void setLine(int line, const char* filename);
|
||||||
|
// Low-level OpLine. See setLine() for a layered helper.
|
||||||
|
void addLine(Id fileName, int line, int column);
|
||||||
|
|
||||||
|
// For creating new types (will return old type if the requested one was already made).
|
||||||
|
Id makeVoidType();
|
||||||
|
Id makeBoolType();
|
||||||
|
Id makePointer(StorageClass, Id pointee);
|
||||||
|
Id makeForwardPointer(StorageClass);
|
||||||
|
Id makePointerFromForwardPointer(StorageClass, Id forwardPointerType, Id pointee);
|
||||||
|
Id makeIntegerType(int width, bool hasSign); // generic
|
||||||
|
Id makeIntType(int width) { return makeIntegerType(width, true); }
|
||||||
|
Id makeUintType(int width) { return makeIntegerType(width, false); }
|
||||||
|
Id makeFloatType(int width);
|
||||||
|
Id makeStructType(const std::vector<Id>& members, const char*);
|
||||||
|
Id makeStructResultType(Id type0, Id type1);
|
||||||
|
Id makeVectorType(Id component, int size);
|
||||||
|
Id makeMatrixType(Id component, int cols, int rows);
|
||||||
|
Id makeArrayType(Id element, Id sizeId, int stride); // 0 stride means no stride decoration
|
||||||
|
Id makeRuntimeArray(Id element);
|
||||||
|
Id makeFunctionType(Id returnType, const std::vector<Id>& paramTypes);
|
||||||
|
Id makeImageType(Id sampledType, Dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format);
|
||||||
|
Id makeSamplerType();
|
||||||
|
Id makeSampledImageType(Id imageType);
|
||||||
|
Id makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols);
|
||||||
|
|
||||||
|
// accelerationStructureNV type
|
||||||
|
Id makeAccelerationStructureNVType();
|
||||||
|
|
||||||
|
// For querying about types.
|
||||||
|
Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
|
||||||
|
Id getDerefTypeId(Id resultId) const;
|
||||||
|
Op getOpCode(Id id) const { return module.getInstruction(id)->getOpCode(); }
|
||||||
|
Op getTypeClass(Id typeId) const { return getOpCode(typeId); }
|
||||||
|
Op getMostBasicTypeClass(Id typeId) const;
|
||||||
|
int getNumComponents(Id resultId) const { return getNumTypeComponents(getTypeId(resultId)); }
|
||||||
|
int getNumTypeConstituents(Id typeId) const;
|
||||||
|
int getNumTypeComponents(Id typeId) const { return getNumTypeConstituents(typeId); }
|
||||||
|
Id getScalarTypeId(Id typeId) const;
|
||||||
|
Id getContainedTypeId(Id typeId) const;
|
||||||
|
Id getContainedTypeId(Id typeId, int) const;
|
||||||
|
StorageClass getTypeStorageClass(Id typeId) const { return module.getStorageClass(typeId); }
|
||||||
|
ImageFormat getImageTypeFormat(Id typeId) const { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); }
|
||||||
|
|
||||||
|
bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); }
|
||||||
|
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
|
||||||
|
bool isVector(Id resultId) const { return isVectorType(getTypeId(resultId)); }
|
||||||
|
bool isMatrix(Id resultId) const { return isMatrixType(getTypeId(resultId)); }
|
||||||
|
bool isCooperativeMatrix(Id resultId)const { return isCooperativeMatrixType(getTypeId(resultId)); }
|
||||||
|
bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
|
||||||
|
bool isSampledImage(Id resultId) const { return isSampledImageType(getTypeId(resultId)); }
|
||||||
|
|
||||||
|
bool isBoolType(Id typeId) { return groupedTypes[OpTypeBool].size() > 0 && typeId == groupedTypes[OpTypeBool].back()->getResultId(); }
|
||||||
|
bool isIntType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) != 0; }
|
||||||
|
bool isUintType(Id typeId) const { return getTypeClass(typeId) == OpTypeInt && module.getInstruction(typeId)->getImmediateOperand(1) == 0; }
|
||||||
|
bool isFloatType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat; }
|
||||||
|
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; }
|
||||||
|
bool isScalarType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || getTypeClass(typeId) == OpTypeBool; }
|
||||||
|
bool isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; }
|
||||||
|
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
|
||||||
|
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
|
||||||
|
bool isArrayType(Id typeId) const { return getTypeClass(typeId) == OpTypeArray; }
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
bool isCooperativeMatrixType(Id typeId)const { return false; }
|
||||||
|
#else
|
||||||
|
bool isCooperativeMatrixType(Id typeId)const { return getTypeClass(typeId) == OpTypeCooperativeMatrixNV; }
|
||||||
|
#endif
|
||||||
|
bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); }
|
||||||
|
bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; }
|
||||||
|
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
|
||||||
|
bool isSampledImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampledImage; }
|
||||||
|
bool containsType(Id typeId, Op typeOp, unsigned int width) const;
|
||||||
|
bool containsPhysicalStorageBufferOrArray(Id typeId) const;
|
||||||
|
|
||||||
|
bool isConstantOpCode(Op opcode) const;
|
||||||
|
bool isSpecConstantOpCode(Op opcode) const;
|
||||||
|
bool isConstant(Id resultId) const { return isConstantOpCode(getOpCode(resultId)); }
|
||||||
|
bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; }
|
||||||
|
bool isSpecConstant(Id resultId) const { return isSpecConstantOpCode(getOpCode(resultId)); }
|
||||||
|
unsigned int getConstantScalar(Id resultId) const { return module.getInstruction(resultId)->getImmediateOperand(0); }
|
||||||
|
StorageClass getStorageClass(Id resultId) const { return getTypeStorageClass(getTypeId(resultId)); }
|
||||||
|
|
||||||
|
int getScalarTypeWidth(Id typeId) const
|
||||||
|
{
|
||||||
|
Id scalarTypeId = getScalarTypeId(typeId);
|
||||||
|
assert(getTypeClass(scalarTypeId) == OpTypeInt || getTypeClass(scalarTypeId) == OpTypeFloat);
|
||||||
|
return module.getInstruction(scalarTypeId)->getImmediateOperand(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getTypeNumColumns(Id typeId) const
|
||||||
|
{
|
||||||
|
assert(isMatrixType(typeId));
|
||||||
|
return getNumTypeConstituents(typeId);
|
||||||
|
}
|
||||||
|
int getNumColumns(Id resultId) const { return getTypeNumColumns(getTypeId(resultId)); }
|
||||||
|
int getTypeNumRows(Id typeId) const
|
||||||
|
{
|
||||||
|
assert(isMatrixType(typeId));
|
||||||
|
return getNumTypeComponents(getContainedTypeId(typeId));
|
||||||
|
}
|
||||||
|
int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); }
|
||||||
|
|
||||||
|
Dim getTypeDimensionality(Id typeId) const
|
||||||
|
{
|
||||||
|
assert(isImageType(typeId));
|
||||||
|
return (Dim)module.getInstruction(typeId)->getImmediateOperand(1);
|
||||||
|
}
|
||||||
|
Id getImageType(Id resultId) const
|
||||||
|
{
|
||||||
|
Id typeId = getTypeId(resultId);
|
||||||
|
assert(isImageType(typeId) || isSampledImageType(typeId));
|
||||||
|
return isSampledImageType(typeId) ? module.getInstruction(typeId)->getIdOperand(0) : typeId;
|
||||||
|
}
|
||||||
|
bool isArrayedImageType(Id typeId) const
|
||||||
|
{
|
||||||
|
assert(isImageType(typeId));
|
||||||
|
return module.getInstruction(typeId)->getImmediateOperand(3) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For making new constants (will return old constant if the requested one was already made).
|
||||||
|
Id makeBoolConstant(bool b, bool specConstant = false);
|
||||||
|
Id makeInt8Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(8), (unsigned)i, specConstant); }
|
||||||
|
Id makeUint8Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(8), u, specConstant); }
|
||||||
|
Id makeInt16Constant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(16), (unsigned)i, specConstant); }
|
||||||
|
Id makeUint16Constant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(16), u, specConstant); }
|
||||||
|
Id makeIntConstant(int i, bool specConstant = false) { return makeIntConstant(makeIntType(32), (unsigned)i, specConstant); }
|
||||||
|
Id makeUintConstant(unsigned u, bool specConstant = false) { return makeIntConstant(makeUintType(32), u, specConstant); }
|
||||||
|
Id makeInt64Constant(long long i, bool specConstant = false) { return makeInt64Constant(makeIntType(64), (unsigned long long)i, specConstant); }
|
||||||
|
Id makeUint64Constant(unsigned long long u, bool specConstant = false) { return makeInt64Constant(makeUintType(64), u, specConstant); }
|
||||||
|
Id makeFloatConstant(float f, bool specConstant = false);
|
||||||
|
Id makeDoubleConstant(double d, bool specConstant = false);
|
||||||
|
Id makeFloat16Constant(float f16, bool specConstant = false);
|
||||||
|
Id makeFpConstant(Id type, double d, bool specConstant = false);
|
||||||
|
|
||||||
|
// Turn the array of constants into a proper spv constant of the requested type.
|
||||||
|
Id makeCompositeConstant(Id type, const std::vector<Id>& comps, bool specConst = false);
|
||||||
|
|
||||||
|
// Methods for adding information outside the CFG.
|
||||||
|
Instruction* addEntryPoint(ExecutionModel, Function*, const char* name);
|
||||||
|
void addExecutionMode(Function*, ExecutionMode mode, int value1 = -1, int value2 = -1, int value3 = -1);
|
||||||
|
void addName(Id, const char* name);
|
||||||
|
void addMemberName(Id, int member, const char* name);
|
||||||
|
void addDecoration(Id, Decoration, int num = -1);
|
||||||
|
void addDecoration(Id, Decoration, const char*);
|
||||||
|
void addDecorationId(Id id, Decoration, Id idDecoration);
|
||||||
|
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
||||||
|
void addMemberDecoration(Id, unsigned int member, Decoration, const char*);
|
||||||
|
|
||||||
|
// At the end of what block do the next create*() instructions go?
|
||||||
|
void setBuildPoint(Block* bp) { buildPoint = bp; }
|
||||||
|
Block* getBuildPoint() const { return buildPoint; }
|
||||||
|
|
||||||
|
// Make the entry-point function. The returned pointer is only valid
|
||||||
|
// for the lifetime of this builder.
|
||||||
|
Function* makeEntryPoint(const char*);
|
||||||
|
|
||||||
|
// Make a shader-style function, and create its entry block if entry is non-zero.
|
||||||
|
// Return the function, pass back the entry.
|
||||||
|
// The returned pointer is only valid for the lifetime of this builder.
|
||||||
|
Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, const std::vector<Id>& paramTypes,
|
||||||
|
const std::vector<std::vector<Decoration>>& precisions, Block **entry = 0);
|
||||||
|
|
||||||
|
// Create a return. An 'implicit' return is one not appearing in the source
|
||||||
|
// code. In the case of an implicit return, no post-return block is inserted.
|
||||||
|
void makeReturn(bool implicit, Id retVal = 0);
|
||||||
|
|
||||||
|
// Generate all the code needed to finish up a function.
|
||||||
|
void leaveFunction();
|
||||||
|
|
||||||
|
// Create a discard.
|
||||||
|
void makeDiscard();
|
||||||
|
|
||||||
|
// Create a global or function local or IO variable.
|
||||||
|
Id createVariable(StorageClass, Id type, const char* name = 0, Id initializer = NoResult);
|
||||||
|
|
||||||
|
// Create an intermediate with an undefined value.
|
||||||
|
Id createUndefined(Id type);
|
||||||
|
|
||||||
|
// Store into an Id and return the l-value
|
||||||
|
void createStore(Id rValue, Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||||
|
|
||||||
|
// Load from an Id and return it
|
||||||
|
Id createLoad(Id lValue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||||
|
|
||||||
|
// Create an OpAccessChain instruction
|
||||||
|
Id createAccessChain(StorageClass, Id base, const std::vector<Id>& offsets);
|
||||||
|
|
||||||
|
// Create an OpArrayLength instruction
|
||||||
|
Id createArrayLength(Id base, unsigned int member);
|
||||||
|
|
||||||
|
// Create an OpCooperativeMatrixLengthNV instruction
|
||||||
|
Id createCooperativeMatrixLength(Id type);
|
||||||
|
|
||||||
|
// Create an OpCompositeExtract instruction
|
||||||
|
Id createCompositeExtract(Id composite, Id typeId, unsigned index);
|
||||||
|
Id createCompositeExtract(Id composite, Id typeId, const std::vector<unsigned>& indexes);
|
||||||
|
Id createCompositeInsert(Id object, Id composite, Id typeId, unsigned index);
|
||||||
|
Id createCompositeInsert(Id object, Id composite, Id typeId, const std::vector<unsigned>& indexes);
|
||||||
|
|
||||||
|
Id createVectorExtractDynamic(Id vector, Id typeId, Id componentIndex);
|
||||||
|
Id createVectorInsertDynamic(Id vector, Id typeId, Id component, Id componentIndex);
|
||||||
|
|
||||||
|
void createNoResultOp(Op);
|
||||||
|
void createNoResultOp(Op, Id operand);
|
||||||
|
void createNoResultOp(Op, const std::vector<Id>& operands);
|
||||||
|
void createNoResultOp(Op, const std::vector<IdImmediate>& operands);
|
||||||
|
void createControlBarrier(Scope execution, Scope memory, MemorySemanticsMask);
|
||||||
|
void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
|
||||||
|
Id createUnaryOp(Op, Id typeId, Id operand);
|
||||||
|
Id createBinOp(Op, Id typeId, Id operand1, Id operand2);
|
||||||
|
Id createTriOp(Op, Id typeId, Id operand1, Id operand2, Id operand3);
|
||||||
|
Id createOp(Op, Id typeId, const std::vector<Id>& operands);
|
||||||
|
Id createOp(Op, Id typeId, const std::vector<IdImmediate>& operands);
|
||||||
|
Id createFunctionCall(spv::Function*, const std::vector<spv::Id>&);
|
||||||
|
Id createSpecConstantOp(Op, Id typeId, const std::vector<spv::Id>& operands, const std::vector<unsigned>& literals);
|
||||||
|
|
||||||
|
// Take an rvalue (source) and a set of channels to extract from it to
|
||||||
|
// make a new rvalue, which is returned.
|
||||||
|
Id createRvalueSwizzle(Decoration precision, Id typeId, Id source, const std::vector<unsigned>& channels);
|
||||||
|
|
||||||
|
// Take a copy of an lvalue (target) and a source of components, and set the
|
||||||
|
// source components into the lvalue where the 'channels' say to put them.
|
||||||
|
// An updated version of the target is returned.
|
||||||
|
// (No true lvalue or stores are used.)
|
||||||
|
Id createLvalueSwizzle(Id typeId, Id target, Id source, const std::vector<unsigned>& channels);
|
||||||
|
|
||||||
|
// If both the id and precision are valid, the id
|
||||||
|
// gets tagged with the requested precision.
|
||||||
|
// The passed in id is always the returned id, to simplify use patterns.
|
||||||
|
Id setPrecision(Id id, Decoration precision)
|
||||||
|
{
|
||||||
|
if (precision != NoPrecision && id != NoResult)
|
||||||
|
addDecoration(id, precision);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can smear a scalar to a vector for the following forms:
|
||||||
|
// - promoteScalar(scalar, vector) // smear scalar to width of vector
|
||||||
|
// - promoteScalar(vector, scalar) // smear scalar to width of vector
|
||||||
|
// - promoteScalar(pointer, scalar) // smear scalar to width of what pointer points to
|
||||||
|
// - promoteScalar(scalar, scalar) // do nothing
|
||||||
|
// Other forms are not allowed.
|
||||||
|
//
|
||||||
|
// Generally, the type of 'scalar' does not need to be the same type as the components in 'vector'.
|
||||||
|
// The type of the created vector is a vector of components of the same type as the scalar.
|
||||||
|
//
|
||||||
|
// Note: One of the arguments will change, with the result coming back that way rather than
|
||||||
|
// through the return value.
|
||||||
|
void promoteScalar(Decoration precision, Id& left, Id& right);
|
||||||
|
|
||||||
|
// Make a value by smearing the scalar to fill the type.
|
||||||
|
// vectorType should be the correct type for making a vector of scalarVal.
|
||||||
|
// (No conversions are done.)
|
||||||
|
Id smearScalar(Decoration precision, Id scalarVal, Id vectorType);
|
||||||
|
|
||||||
|
// Create a call to a built-in function.
|
||||||
|
Id createBuiltinCall(Id resultType, Id builtins, int entryPoint, const std::vector<Id>& args);
|
||||||
|
|
||||||
|
// List of parameters used to create a texture operation
|
||||||
|
struct TextureParameters {
|
||||||
|
Id sampler;
|
||||||
|
Id coords;
|
||||||
|
Id bias;
|
||||||
|
Id lod;
|
||||||
|
Id Dref;
|
||||||
|
Id offset;
|
||||||
|
Id offsets;
|
||||||
|
Id gradX;
|
||||||
|
Id gradY;
|
||||||
|
Id sample;
|
||||||
|
Id component;
|
||||||
|
Id texelOut;
|
||||||
|
Id lodClamp;
|
||||||
|
Id granularity;
|
||||||
|
Id coarse;
|
||||||
|
bool nonprivate;
|
||||||
|
bool volatil;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Select the correct texture operation based on all inputs, and emit the correct instruction
|
||||||
|
Id createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather,
|
||||||
|
bool noImplicit, const TextureParameters&, ImageOperandsMask);
|
||||||
|
|
||||||
|
// Emit the OpTextureQuery* instruction that was passed in.
|
||||||
|
// Figure out the right return value and type, and return it.
|
||||||
|
Id createTextureQueryCall(Op, const TextureParameters&, bool isUnsignedResult);
|
||||||
|
|
||||||
|
Id createSamplePositionCall(Decoration precision, Id, Id);
|
||||||
|
|
||||||
|
Id createBitFieldExtractCall(Decoration precision, Id, Id, Id, bool isSigned);
|
||||||
|
Id createBitFieldInsertCall(Decoration precision, Id, Id, Id, Id);
|
||||||
|
|
||||||
|
// Reduction comparison for composites: For equal and not-equal resulting in a scalar.
|
||||||
|
Id createCompositeCompare(Decoration precision, Id, Id, bool /* true if for equal, false if for not-equal */);
|
||||||
|
|
||||||
|
// OpCompositeConstruct
|
||||||
|
Id createCompositeConstruct(Id typeId, const std::vector<Id>& constituents);
|
||||||
|
|
||||||
|
// vector or scalar constructor
|
||||||
|
Id createConstructor(Decoration precision, const std::vector<Id>& sources, Id resultTypeId);
|
||||||
|
|
||||||
|
// matrix constructor
|
||||||
|
Id createMatrixConstructor(Decoration precision, const std::vector<Id>& sources, Id constructee);
|
||||||
|
|
||||||
|
// Helper to use for building nested control flow with if-then-else.
|
||||||
|
class If {
|
||||||
|
public:
|
||||||
|
If(Id condition, unsigned int ctrl, Builder& builder);
|
||||||
|
~If() {}
|
||||||
|
|
||||||
|
void makeBeginElse();
|
||||||
|
void makeEndIf();
|
||||||
|
|
||||||
|
private:
|
||||||
|
If(const If&);
|
||||||
|
If& operator=(If&);
|
||||||
|
|
||||||
|
Builder& builder;
|
||||||
|
Id condition;
|
||||||
|
unsigned int control;
|
||||||
|
Function* function;
|
||||||
|
Block* headerBlock;
|
||||||
|
Block* thenBlock;
|
||||||
|
Block* elseBlock;
|
||||||
|
Block* mergeBlock;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Make a switch statement. A switch has 'numSegments' of pieces of code, not containing
|
||||||
|
// any case/default labels, all separated by one or more case/default labels. Each possible
|
||||||
|
// case value v is a jump to the caseValues[v] segment. The defaultSegment is also in this
|
||||||
|
// number space. How to compute the value is given by 'condition', as in switch(condition).
|
||||||
|
//
|
||||||
|
// The SPIR-V Builder will maintain the stack of post-switch merge blocks for nested switches.
|
||||||
|
//
|
||||||
|
// Use a defaultSegment < 0 if there is no default segment (to branch to post switch).
|
||||||
|
//
|
||||||
|
// Returns the right set of basic blocks to start each code segment with, so that the caller's
|
||||||
|
// recursion stack can hold the memory for it.
|
||||||
|
//
|
||||||
|
void makeSwitch(Id condition, unsigned int control, int numSegments, const std::vector<int>& caseValues,
|
||||||
|
const std::vector<int>& valueToSegment, int defaultSegment, std::vector<Block*>& segmentBB); // return argument
|
||||||
|
|
||||||
|
// Add a branch to the innermost switch's merge block.
|
||||||
|
void addSwitchBreak();
|
||||||
|
|
||||||
|
// Move to the next code segment, passing in the return argument in makeSwitch()
|
||||||
|
void nextSwitchSegment(std::vector<Block*>& segmentBB, int segment);
|
||||||
|
|
||||||
|
// Finish off the innermost switch.
|
||||||
|
void endSwitch(std::vector<Block*>& segmentBB);
|
||||||
|
|
||||||
|
struct LoopBlocks {
|
||||||
|
LoopBlocks(Block& head, Block& body, Block& merge, Block& continue_target) :
|
||||||
|
head(head), body(body), merge(merge), continue_target(continue_target) { }
|
||||||
|
Block &head, &body, &merge, &continue_target;
|
||||||
|
private:
|
||||||
|
LoopBlocks();
|
||||||
|
LoopBlocks& operator=(const LoopBlocks&);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Start a new loop and prepare the builder to generate code for it. Until
|
||||||
|
// closeLoop() is called for this loop, createLoopContinue() and
|
||||||
|
// createLoopExit() will target its corresponding blocks.
|
||||||
|
LoopBlocks& makeNewLoop();
|
||||||
|
|
||||||
|
// Create a new block in the function containing the build point. Memory is
|
||||||
|
// owned by the function object.
|
||||||
|
Block& makeNewBlock();
|
||||||
|
|
||||||
|
// Add a branch to the continue_target of the current (innermost) loop.
|
||||||
|
void createLoopContinue();
|
||||||
|
|
||||||
|
// Add an exit (e.g. "break") from the innermost loop that we're currently
|
||||||
|
// in.
|
||||||
|
void createLoopExit();
|
||||||
|
|
||||||
|
// Close the innermost loop that you're in
|
||||||
|
void closeLoop();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Access chain design for an R-Value vs. L-Value:
|
||||||
|
//
|
||||||
|
// There is a single access chain the builder is building at
|
||||||
|
// any particular time. Such a chain can be used to either to a load or
|
||||||
|
// a store, when desired.
|
||||||
|
//
|
||||||
|
// Expressions can be r-values, l-values, or both, or only r-values:
|
||||||
|
// a[b.c].d = .... // l-value
|
||||||
|
// ... = a[b.c].d; // r-value, that also looks like an l-value
|
||||||
|
// ++a[b.c].d; // r-value and l-value
|
||||||
|
// (x + y)[2]; // r-value only, can't possibly be l-value
|
||||||
|
//
|
||||||
|
// Computing an r-value means generating code. Hence,
|
||||||
|
// r-values should only be computed when they are needed, not speculatively.
|
||||||
|
//
|
||||||
|
// Computing an l-value means saving away information for later use in the compiler,
|
||||||
|
// no code is generated until the l-value is later dereferenced. It is okay
|
||||||
|
// to speculatively generate an l-value, just not okay to speculatively dereference it.
|
||||||
|
//
|
||||||
|
// The base of the access chain (the left-most variable or expression
|
||||||
|
// from which everything is based) can be set either as an l-value
|
||||||
|
// or as an r-value. Most efficient would be to set an l-value if one
|
||||||
|
// is available. If an expression was evaluated, the resulting r-value
|
||||||
|
// can be set as the chain base.
|
||||||
|
//
|
||||||
|
// The users of this single access chain can save and restore if they
|
||||||
|
// want to nest or manage multiple chains.
|
||||||
|
//
|
||||||
|
|
||||||
|
struct AccessChain {
|
||||||
|
Id base; // for l-values, pointer to the base object, for r-values, the base object
|
||||||
|
std::vector<Id> indexChain;
|
||||||
|
Id instr; // cache the instruction that generates this access chain
|
||||||
|
std::vector<unsigned> swizzle; // each std::vector element selects the next GLSL component number
|
||||||
|
Id component; // a dynamic component index, can coexist with a swizzle, done after the swizzle, NoResult if not present
|
||||||
|
Id preSwizzleBaseType; // dereferenced type, before swizzle or component is applied; NoType unless a swizzle or component is present
|
||||||
|
bool isRValue; // true if 'base' is an r-value, otherwise, base is an l-value
|
||||||
|
unsigned int alignment; // bitwise OR of alignment values passed in. Accumulates worst alignment. Only tracks base and (optional) component selection alignment.
|
||||||
|
|
||||||
|
// Accumulate whether anything in the chain of structures has coherent decorations.
|
||||||
|
struct CoherentFlags {
|
||||||
|
CoherentFlags() { clear(); }
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
void clear() { }
|
||||||
|
bool isVolatile() const { return false; }
|
||||||
|
CoherentFlags operator |=(const CoherentFlags &other) { return *this; }
|
||||||
|
#else
|
||||||
|
bool isVolatile() const { return volatil; }
|
||||||
|
|
||||||
|
unsigned coherent : 1;
|
||||||
|
unsigned devicecoherent : 1;
|
||||||
|
unsigned queuefamilycoherent : 1;
|
||||||
|
unsigned workgroupcoherent : 1;
|
||||||
|
unsigned subgroupcoherent : 1;
|
||||||
|
unsigned nonprivate : 1;
|
||||||
|
unsigned volatil : 1;
|
||||||
|
unsigned isImage : 1;
|
||||||
|
|
||||||
|
void clear() {
|
||||||
|
coherent = 0;
|
||||||
|
devicecoherent = 0;
|
||||||
|
queuefamilycoherent = 0;
|
||||||
|
workgroupcoherent = 0;
|
||||||
|
subgroupcoherent = 0;
|
||||||
|
nonprivate = 0;
|
||||||
|
volatil = 0;
|
||||||
|
isImage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoherentFlags operator |=(const CoherentFlags &other) {
|
||||||
|
coherent |= other.coherent;
|
||||||
|
devicecoherent |= other.devicecoherent;
|
||||||
|
queuefamilycoherent |= other.queuefamilycoherent;
|
||||||
|
workgroupcoherent |= other.workgroupcoherent;
|
||||||
|
subgroupcoherent |= other.subgroupcoherent;
|
||||||
|
nonprivate |= other.nonprivate;
|
||||||
|
volatil |= other.volatil;
|
||||||
|
isImage |= other.isImage;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
CoherentFlags coherentFlags;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// the SPIR-V builder maintains a single active chain that
|
||||||
|
// the following methods operate on
|
||||||
|
//
|
||||||
|
|
||||||
|
// for external save and restore
|
||||||
|
AccessChain getAccessChain() { return accessChain; }
|
||||||
|
void setAccessChain(AccessChain newChain) { accessChain = newChain; }
|
||||||
|
|
||||||
|
// clear accessChain
|
||||||
|
void clearAccessChain();
|
||||||
|
|
||||||
|
// set new base as an l-value base
|
||||||
|
void setAccessChainLValue(Id lValue)
|
||||||
|
{
|
||||||
|
assert(isPointer(lValue));
|
||||||
|
accessChain.base = lValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set new base value as an r-value
|
||||||
|
void setAccessChainRValue(Id rValue)
|
||||||
|
{
|
||||||
|
accessChain.isRValue = true;
|
||||||
|
accessChain.base = rValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// push offset onto the end of the chain
|
||||||
|
void accessChainPush(Id offset, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
|
||||||
|
{
|
||||||
|
accessChain.indexChain.push_back(offset);
|
||||||
|
accessChain.coherentFlags |= coherentFlags;
|
||||||
|
accessChain.alignment |= alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
||||||
|
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment);
|
||||||
|
|
||||||
|
// push a dynamic component selection onto the access chain, only applicable with a
|
||||||
|
// non-trivial swizzle or no swizzle
|
||||||
|
void accessChainPushComponent(Id component, Id preSwizzleBaseType, AccessChain::CoherentFlags coherentFlags, unsigned int alignment)
|
||||||
|
{
|
||||||
|
if (accessChain.swizzle.size() != 1) {
|
||||||
|
accessChain.component = component;
|
||||||
|
if (accessChain.preSwizzleBaseType == NoType)
|
||||||
|
accessChain.preSwizzleBaseType = preSwizzleBaseType;
|
||||||
|
}
|
||||||
|
accessChain.coherentFlags |= coherentFlags;
|
||||||
|
accessChain.alignment |= alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
// use accessChain and swizzle to store value
|
||||||
|
void accessChainStore(Id rvalue, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||||
|
|
||||||
|
// use accessChain and swizzle to load an r-value
|
||||||
|
Id accessChainLoad(Decoration precision, Decoration nonUniform, Id ResultType, spv::MemoryAccessMask memoryAccess = spv::MemoryAccessMaskNone, spv::Scope scope = spv::ScopeMax, unsigned int alignment = 0);
|
||||||
|
|
||||||
|
// get the direct pointer for an l-value
|
||||||
|
Id accessChainGetLValue();
|
||||||
|
|
||||||
|
// Get the inferred SPIR-V type of the result of the current access chain,
|
||||||
|
// based on the type of the base and the chain of dereferences.
|
||||||
|
Id accessChainGetInferredType();
|
||||||
|
|
||||||
|
// Add capabilities, extensions, remove unneeded decorations, etc.,
|
||||||
|
// based on the resulting SPIR-V.
|
||||||
|
void postProcess();
|
||||||
|
|
||||||
|
// Prune unreachable blocks in the CFG and remove unneeded decorations.
|
||||||
|
void postProcessCFG();
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
// Add capabilities, extensions based on instructions in the module.
|
||||||
|
void postProcessFeatures();
|
||||||
|
// Hook to visit each instruction in a block in a function
|
||||||
|
void postProcess(Instruction&);
|
||||||
|
// Hook to visit each non-32-bit sized float/int operation in a block.
|
||||||
|
void postProcessType(const Instruction&, spv::Id typeId);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void dump(std::vector<unsigned int>&) const;
|
||||||
|
|
||||||
|
void createBranch(Block* block);
|
||||||
|
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
|
||||||
|
void createLoopMerge(Block* mergeBlock, Block* continueBlock, unsigned int control, const std::vector<unsigned int>& operands);
|
||||||
|
|
||||||
|
// Sets to generate opcode for specialization constants.
|
||||||
|
void setToSpecConstCodeGenMode() { generatingOpCodeForSpecConst = true; }
|
||||||
|
// Sets to generate opcode for non-specialization constants (normal mode).
|
||||||
|
void setToNormalCodeGenMode() { generatingOpCodeForSpecConst = false; }
|
||||||
|
// Check if the builder is generating code for spec constants.
|
||||||
|
bool isInSpecConstCodeGenMode() { return generatingOpCodeForSpecConst; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Id makeIntConstant(Id typeId, unsigned value, bool specConstant);
|
||||||
|
Id makeInt64Constant(Id typeId, unsigned long long value, bool specConstant);
|
||||||
|
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value);
|
||||||
|
Id findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2);
|
||||||
|
Id findCompositeConstant(Op typeClass, Id typeId, const std::vector<Id>& comps);
|
||||||
|
Id findStructConstant(Id typeId, const std::vector<Id>& comps);
|
||||||
|
Id collapseAccessChain();
|
||||||
|
void remapDynamicSwizzle();
|
||||||
|
void transferAccessChainSwizzle(bool dynamic);
|
||||||
|
void simplifyAccessChainSwizzle();
|
||||||
|
void createAndSetNoPredecessorBlock(const char*);
|
||||||
|
void createSelectionMerge(Block* mergeBlock, unsigned int control);
|
||||||
|
void dumpSourceInstructions(std::vector<unsigned int>&) const;
|
||||||
|
void dumpSourceInstructions(const spv::Id fileId, const std::string& text, std::vector<unsigned int>&) const;
|
||||||
|
void dumpInstructions(std::vector<unsigned int>&, const std::vector<std::unique_ptr<Instruction> >&) const;
|
||||||
|
void dumpModuleProcesses(std::vector<unsigned int>&) const;
|
||||||
|
spv::MemoryAccessMask sanitizeMemoryAccessForStorageClass(spv::MemoryAccessMask memoryAccess, StorageClass sc) const;
|
||||||
|
|
||||||
|
unsigned int spvVersion; // the version of SPIR-V to emit in the header
|
||||||
|
SourceLanguage source;
|
||||||
|
int sourceVersion;
|
||||||
|
spv::Id sourceFileStringId;
|
||||||
|
std::string sourceText;
|
||||||
|
int currentLine;
|
||||||
|
const char* currentFile;
|
||||||
|
bool emitOpLines;
|
||||||
|
std::set<std::string> extensions;
|
||||||
|
std::vector<const char*> sourceExtensions;
|
||||||
|
std::vector<const char*> moduleProcesses;
|
||||||
|
AddressingModel addressModel;
|
||||||
|
MemoryModel memoryModel;
|
||||||
|
std::set<spv::Capability> capabilities;
|
||||||
|
int builderNumber;
|
||||||
|
Module module;
|
||||||
|
Block* buildPoint;
|
||||||
|
Id uniqueId;
|
||||||
|
Function* entryPointFunction;
|
||||||
|
bool generatingOpCodeForSpecConst;
|
||||||
|
AccessChain accessChain;
|
||||||
|
|
||||||
|
// special blocks of instructions for output
|
||||||
|
std::vector<std::unique_ptr<Instruction> > strings;
|
||||||
|
std::vector<std::unique_ptr<Instruction> > imports;
|
||||||
|
std::vector<std::unique_ptr<Instruction> > entryPoints;
|
||||||
|
std::vector<std::unique_ptr<Instruction> > executionModes;
|
||||||
|
std::vector<std::unique_ptr<Instruction> > names;
|
||||||
|
std::vector<std::unique_ptr<Instruction> > decorations;
|
||||||
|
std::vector<std::unique_ptr<Instruction> > constantsTypesGlobals;
|
||||||
|
std::vector<std::unique_ptr<Instruction> > externals;
|
||||||
|
std::vector<std::unique_ptr<Function> > functions;
|
||||||
|
|
||||||
|
// not output, internally used for quick & dirty canonical (unique) creation
|
||||||
|
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedConstants; // map type opcodes to constant inst.
|
||||||
|
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedStructConstants; // map struct-id to constant instructions
|
||||||
|
std::unordered_map<unsigned int, std::vector<Instruction*>> groupedTypes; // map type opcodes to type instructions
|
||||||
|
|
||||||
|
// stack of switches
|
||||||
|
std::stack<Block*> switchMerges;
|
||||||
|
|
||||||
|
// Our loop stack.
|
||||||
|
std::stack<LoopBlocks> loops;
|
||||||
|
|
||||||
|
// map from strings to their string ids
|
||||||
|
std::unordered_map<std::string, spv::Id> stringIds;
|
||||||
|
|
||||||
|
// map from include file name ids to their contents
|
||||||
|
std::map<spv::Id, const std::string*> includeFiles;
|
||||||
|
|
||||||
|
// The stream for outputting warnings and errors.
|
||||||
|
SpvBuildLogger* logger;
|
||||||
|
}; // end Builder class
|
||||||
|
|
||||||
|
}; // end spv namespace
|
||||||
|
|
||||||
|
#endif // SpvBuilder_H
|
||||||
@@ -0,0 +1,450 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2018 Google, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Post-processing for SPIR-V IR, in internal form, not standard binary form.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#include "SpvBuilder.h"
|
||||||
|
|
||||||
|
#include "spirv.hpp"
|
||||||
|
#include "GlslangToSpv.h"
|
||||||
|
#include "SpvBuilder.h"
|
||||||
|
namespace spv {
|
||||||
|
#include "GLSL.std.450.h"
|
||||||
|
#include "GLSL.ext.KHR.h"
|
||||||
|
#include "GLSL.ext.EXT.h"
|
||||||
|
#include "GLSL.ext.AMD.h"
|
||||||
|
#include "GLSL.ext.NV.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
// Hook to visit each operand type and result type of an instruction.
|
||||||
|
// Will be called multiple times for one instruction, once for each typed
|
||||||
|
// operand and the result.
|
||||||
|
void Builder::postProcessType(const Instruction& inst, Id typeId)
|
||||||
|
{
|
||||||
|
// Characterize the type being questioned
|
||||||
|
Id basicTypeOp = getMostBasicTypeClass(typeId);
|
||||||
|
int width = 0;
|
||||||
|
if (basicTypeOp == OpTypeFloat || basicTypeOp == OpTypeInt)
|
||||||
|
width = getScalarTypeWidth(typeId);
|
||||||
|
|
||||||
|
// Do opcode-specific checks
|
||||||
|
switch (inst.getOpCode()) {
|
||||||
|
case OpLoad:
|
||||||
|
case OpStore:
|
||||||
|
if (basicTypeOp == OpTypeStruct) {
|
||||||
|
if (containsType(typeId, OpTypeInt, 8))
|
||||||
|
addCapability(CapabilityInt8);
|
||||||
|
if (containsType(typeId, OpTypeInt, 16))
|
||||||
|
addCapability(CapabilityInt16);
|
||||||
|
if (containsType(typeId, OpTypeFloat, 16))
|
||||||
|
addCapability(CapabilityFloat16);
|
||||||
|
} else {
|
||||||
|
StorageClass storageClass = getStorageClass(inst.getIdOperand(0));
|
||||||
|
if (width == 8) {
|
||||||
|
switch (storageClass) {
|
||||||
|
case StorageClassPhysicalStorageBufferEXT:
|
||||||
|
case StorageClassUniform:
|
||||||
|
case StorageClassStorageBuffer:
|
||||||
|
case StorageClassPushConstant:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
addCapability(CapabilityInt8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (width == 16) {
|
||||||
|
switch (storageClass) {
|
||||||
|
case StorageClassPhysicalStorageBufferEXT:
|
||||||
|
case StorageClassUniform:
|
||||||
|
case StorageClassStorageBuffer:
|
||||||
|
case StorageClassPushConstant:
|
||||||
|
case StorageClassInput:
|
||||||
|
case StorageClassOutput:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (basicTypeOp == OpTypeInt)
|
||||||
|
addCapability(CapabilityInt16);
|
||||||
|
if (basicTypeOp == OpTypeFloat)
|
||||||
|
addCapability(CapabilityFloat16);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OpAccessChain:
|
||||||
|
case OpPtrAccessChain:
|
||||||
|
case OpCopyObject:
|
||||||
|
break;
|
||||||
|
case OpFConvert:
|
||||||
|
case OpSConvert:
|
||||||
|
case OpUConvert:
|
||||||
|
// Look for any 8/16-bit storage capabilities. If there are none, assume that
|
||||||
|
// the convert instruction requires the Float16/Int8/16 capability.
|
||||||
|
if (containsType(typeId, OpTypeFloat, 16) || containsType(typeId, OpTypeInt, 16)) {
|
||||||
|
bool foundStorage = false;
|
||||||
|
for (auto it = capabilities.begin(); it != capabilities.end(); ++it) {
|
||||||
|
spv::Capability cap = *it;
|
||||||
|
if (cap == spv::CapabilityStorageInputOutput16 ||
|
||||||
|
cap == spv::CapabilityStoragePushConstant16 ||
|
||||||
|
cap == spv::CapabilityStorageUniformBufferBlock16 ||
|
||||||
|
cap == spv::CapabilityStorageUniform16) {
|
||||||
|
foundStorage = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundStorage) {
|
||||||
|
if (containsType(typeId, OpTypeFloat, 16))
|
||||||
|
addCapability(CapabilityFloat16);
|
||||||
|
if (containsType(typeId, OpTypeInt, 16))
|
||||||
|
addCapability(CapabilityInt16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (containsType(typeId, OpTypeInt, 8)) {
|
||||||
|
bool foundStorage = false;
|
||||||
|
for (auto it = capabilities.begin(); it != capabilities.end(); ++it) {
|
||||||
|
spv::Capability cap = *it;
|
||||||
|
if (cap == spv::CapabilityStoragePushConstant8 ||
|
||||||
|
cap == spv::CapabilityUniformAndStorageBuffer8BitAccess ||
|
||||||
|
cap == spv::CapabilityStorageBuffer8BitAccess) {
|
||||||
|
foundStorage = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!foundStorage) {
|
||||||
|
addCapability(CapabilityInt8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OpExtInst:
|
||||||
|
switch (inst.getImmediateOperand(1)) {
|
||||||
|
case GLSLstd450Frexp:
|
||||||
|
case GLSLstd450FrexpStruct:
|
||||||
|
if (getSpvVersion() < glslang::EShTargetSpv_1_3 && containsType(typeId, OpTypeInt, 16))
|
||||||
|
addExtension(spv::E_SPV_AMD_gpu_shader_int16);
|
||||||
|
break;
|
||||||
|
case GLSLstd450InterpolateAtCentroid:
|
||||||
|
case GLSLstd450InterpolateAtSample:
|
||||||
|
case GLSLstd450InterpolateAtOffset:
|
||||||
|
if (getSpvVersion() < glslang::EShTargetSpv_1_3 && containsType(typeId, OpTypeFloat, 16))
|
||||||
|
addExtension(spv::E_SPV_AMD_gpu_shader_half_float);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (basicTypeOp == OpTypeFloat && width == 16)
|
||||||
|
addCapability(CapabilityFloat16);
|
||||||
|
if (basicTypeOp == OpTypeInt && width == 16)
|
||||||
|
addCapability(CapabilityInt16);
|
||||||
|
if (basicTypeOp == OpTypeInt && width == 8)
|
||||||
|
addCapability(CapabilityInt8);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called for each instruction that resides in a block.
|
||||||
|
void Builder::postProcess(Instruction& inst)
|
||||||
|
{
|
||||||
|
// Add capabilities based simply on the opcode.
|
||||||
|
switch (inst.getOpCode()) {
|
||||||
|
case OpExtInst:
|
||||||
|
switch (inst.getImmediateOperand(1)) {
|
||||||
|
case GLSLstd450InterpolateAtCentroid:
|
||||||
|
case GLSLstd450InterpolateAtSample:
|
||||||
|
case GLSLstd450InterpolateAtOffset:
|
||||||
|
addCapability(CapabilityInterpolationFunction);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OpDPdxFine:
|
||||||
|
case OpDPdyFine:
|
||||||
|
case OpFwidthFine:
|
||||||
|
case OpDPdxCoarse:
|
||||||
|
case OpDPdyCoarse:
|
||||||
|
case OpFwidthCoarse:
|
||||||
|
addCapability(CapabilityDerivativeControl);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpImageQueryLod:
|
||||||
|
case OpImageQuerySize:
|
||||||
|
case OpImageQuerySizeLod:
|
||||||
|
case OpImageQuerySamples:
|
||||||
|
case OpImageQueryLevels:
|
||||||
|
addCapability(CapabilityImageQuery);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpGroupNonUniformPartitionNV:
|
||||||
|
addExtension(E_SPV_NV_shader_subgroup_partitioned);
|
||||||
|
addCapability(CapabilityGroupNonUniformPartitionedNV);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpLoad:
|
||||||
|
case OpStore:
|
||||||
|
{
|
||||||
|
// For any load/store to a PhysicalStorageBufferEXT, walk the accesschain
|
||||||
|
// index list to compute the misalignment. The pre-existing alignment value
|
||||||
|
// (set via Builder::AccessChain::alignment) only accounts for the base of
|
||||||
|
// the reference type and any scalar component selection in the accesschain,
|
||||||
|
// and this function computes the rest from the SPIR-V Offset decorations.
|
||||||
|
Instruction *accessChain = module.getInstruction(inst.getIdOperand(0));
|
||||||
|
if (accessChain->getOpCode() == OpAccessChain) {
|
||||||
|
Instruction *base = module.getInstruction(accessChain->getIdOperand(0));
|
||||||
|
// Get the type of the base of the access chain. It must be a pointer type.
|
||||||
|
Id typeId = base->getTypeId();
|
||||||
|
Instruction *type = module.getInstruction(typeId);
|
||||||
|
assert(type->getOpCode() == OpTypePointer);
|
||||||
|
if (type->getImmediateOperand(0) != StorageClassPhysicalStorageBufferEXT) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Get the pointee type.
|
||||||
|
typeId = type->getIdOperand(1);
|
||||||
|
type = module.getInstruction(typeId);
|
||||||
|
// Walk the index list for the access chain. For each index, find any
|
||||||
|
// misalignment that can apply when accessing the member/element via
|
||||||
|
// Offset/ArrayStride/MatrixStride decorations, and bitwise OR them all
|
||||||
|
// together.
|
||||||
|
int alignment = 0;
|
||||||
|
for (int i = 1; i < accessChain->getNumOperands(); ++i) {
|
||||||
|
Instruction *idx = module.getInstruction(accessChain->getIdOperand(i));
|
||||||
|
if (type->getOpCode() == OpTypeStruct) {
|
||||||
|
assert(idx->getOpCode() == OpConstant);
|
||||||
|
unsigned int c = idx->getImmediateOperand(0);
|
||||||
|
|
||||||
|
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
|
||||||
|
if (decoration.get()->getOpCode() == OpMemberDecorate &&
|
||||||
|
decoration.get()->getIdOperand(0) == typeId &&
|
||||||
|
decoration.get()->getImmediateOperand(1) == c &&
|
||||||
|
(decoration.get()->getImmediateOperand(2) == DecorationOffset ||
|
||||||
|
decoration.get()->getImmediateOperand(2) == DecorationMatrixStride)) {
|
||||||
|
alignment |= decoration.get()->getImmediateOperand(3);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::for_each(decorations.begin(), decorations.end(), function);
|
||||||
|
// get the next member type
|
||||||
|
typeId = type->getIdOperand(c);
|
||||||
|
type = module.getInstruction(typeId);
|
||||||
|
} else if (type->getOpCode() == OpTypeArray ||
|
||||||
|
type->getOpCode() == OpTypeRuntimeArray) {
|
||||||
|
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
|
||||||
|
if (decoration.get()->getOpCode() == OpDecorate &&
|
||||||
|
decoration.get()->getIdOperand(0) == typeId &&
|
||||||
|
decoration.get()->getImmediateOperand(1) == DecorationArrayStride) {
|
||||||
|
alignment |= decoration.get()->getImmediateOperand(2);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::for_each(decorations.begin(), decorations.end(), function);
|
||||||
|
// Get the element type
|
||||||
|
typeId = type->getIdOperand(0);
|
||||||
|
type = module.getInstruction(typeId);
|
||||||
|
} else {
|
||||||
|
// Once we get to any non-aggregate type, we're done.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(inst.getNumOperands() >= 3);
|
||||||
|
unsigned int memoryAccess = inst.getImmediateOperand((inst.getOpCode() == OpStore) ? 2 : 1);
|
||||||
|
assert(memoryAccess & MemoryAccessAlignedMask);
|
||||||
|
static_cast<void>(memoryAccess);
|
||||||
|
// Compute the index of the alignment operand.
|
||||||
|
int alignmentIdx = 2;
|
||||||
|
if (inst.getOpCode() == OpStore)
|
||||||
|
alignmentIdx++;
|
||||||
|
// Merge new and old (mis)alignment
|
||||||
|
alignment |= inst.getImmediateOperand(alignmentIdx);
|
||||||
|
// Pick the LSB
|
||||||
|
alignment = alignment & ~(alignment & (alignment-1));
|
||||||
|
// update the Aligned operand
|
||||||
|
inst.setImmediateOperand(alignmentIdx, alignment);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks based on type
|
||||||
|
if (inst.getTypeId() != NoType)
|
||||||
|
postProcessType(inst, inst.getTypeId());
|
||||||
|
for (int op = 0; op < inst.getNumOperands(); ++op) {
|
||||||
|
if (inst.isIdOperand(op)) {
|
||||||
|
// In blocks, these are always result ids, but we are relying on
|
||||||
|
// getTypeId() to return NoType for things like OpLabel.
|
||||||
|
if (getTypeId(inst.getIdOperand(op)) != NoType)
|
||||||
|
postProcessType(inst, getTypeId(inst.getIdOperand(op)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// comment in header
|
||||||
|
void Builder::postProcessCFG()
|
||||||
|
{
|
||||||
|
// reachableBlocks is the set of blockss reached via control flow, or which are
|
||||||
|
// unreachable continue targert or unreachable merge.
|
||||||
|
std::unordered_set<const Block*> reachableBlocks;
|
||||||
|
std::unordered_map<Block*, Block*> headerForUnreachableContinue;
|
||||||
|
std::unordered_set<Block*> unreachableMerges;
|
||||||
|
std::unordered_set<Id> unreachableDefinitions;
|
||||||
|
// Collect IDs defined in unreachable blocks. For each function, label the
|
||||||
|
// reachable blocks first. Then for each unreachable block, collect the
|
||||||
|
// result IDs of the instructions in it.
|
||||||
|
for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) {
|
||||||
|
Function* f = *fi;
|
||||||
|
Block* entry = f->getEntryBlock();
|
||||||
|
inReadableOrder(entry,
|
||||||
|
[&reachableBlocks, &unreachableMerges, &headerForUnreachableContinue]
|
||||||
|
(Block* b, ReachReason why, Block* header) {
|
||||||
|
reachableBlocks.insert(b);
|
||||||
|
if (why == ReachDeadContinue) headerForUnreachableContinue[b] = header;
|
||||||
|
if (why == ReachDeadMerge) unreachableMerges.insert(b);
|
||||||
|
});
|
||||||
|
for (auto bi = f->getBlocks().cbegin(); bi != f->getBlocks().cend(); bi++) {
|
||||||
|
Block* b = *bi;
|
||||||
|
if (unreachableMerges.count(b) != 0 || headerForUnreachableContinue.count(b) != 0) {
|
||||||
|
auto ii = b->getInstructions().cbegin();
|
||||||
|
++ii; // Keep potential decorations on the label.
|
||||||
|
for (; ii != b->getInstructions().cend(); ++ii)
|
||||||
|
unreachableDefinitions.insert(ii->get()->getResultId());
|
||||||
|
} else if (reachableBlocks.count(b) == 0) {
|
||||||
|
// The normal case for unreachable code. All definitions are considered dead.
|
||||||
|
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ++ii)
|
||||||
|
unreachableDefinitions.insert(ii->get()->getResultId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modify unreachable merge blocks and unreachable continue targets.
|
||||||
|
// Delete their contents.
|
||||||
|
for (auto mergeIter = unreachableMerges.begin(); mergeIter != unreachableMerges.end(); ++mergeIter) {
|
||||||
|
(*mergeIter)->rewriteAsCanonicalUnreachableMerge();
|
||||||
|
}
|
||||||
|
for (auto continueIter = headerForUnreachableContinue.begin();
|
||||||
|
continueIter != headerForUnreachableContinue.end();
|
||||||
|
++continueIter) {
|
||||||
|
Block* continue_target = continueIter->first;
|
||||||
|
Block* header = continueIter->second;
|
||||||
|
continue_target->rewriteAsCanonicalUnreachableContinue(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove unneeded decorations, for unreachable instructions
|
||||||
|
decorations.erase(std::remove_if(decorations.begin(), decorations.end(),
|
||||||
|
[&unreachableDefinitions](std::unique_ptr<Instruction>& I) -> bool {
|
||||||
|
Id decoration_id = I.get()->getIdOperand(0);
|
||||||
|
return unreachableDefinitions.count(decoration_id) != 0;
|
||||||
|
}),
|
||||||
|
decorations.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
// comment in header
|
||||||
|
void Builder::postProcessFeatures() {
|
||||||
|
// Add per-instruction capabilities, extensions, etc.,
|
||||||
|
|
||||||
|
// Look for any 8/16 bit type in physical storage buffer class, and set the
|
||||||
|
// appropriate capability. This happens in createSpvVariable for other storage
|
||||||
|
// classes, but there isn't always a variable for physical storage buffer.
|
||||||
|
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
|
||||||
|
Instruction* type = groupedTypes[OpTypePointer][t];
|
||||||
|
if (type->getImmediateOperand(0) == (unsigned)StorageClassPhysicalStorageBufferEXT) {
|
||||||
|
if (containsType(type->getIdOperand(1), OpTypeInt, 8)) {
|
||||||
|
addIncorporatedExtension(spv::E_SPV_KHR_8bit_storage, spv::Spv_1_5);
|
||||||
|
addCapability(spv::CapabilityStorageBuffer8BitAccess);
|
||||||
|
}
|
||||||
|
if (containsType(type->getIdOperand(1), OpTypeInt, 16) ||
|
||||||
|
containsType(type->getIdOperand(1), OpTypeFloat, 16)) {
|
||||||
|
addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3);
|
||||||
|
addCapability(spv::CapabilityStorageBuffer16BitAccess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// process all block-contained instructions
|
||||||
|
for (auto fi = module.getFunctions().cbegin(); fi != module.getFunctions().cend(); fi++) {
|
||||||
|
Function* f = *fi;
|
||||||
|
for (auto bi = f->getBlocks().cbegin(); bi != f->getBlocks().cend(); bi++) {
|
||||||
|
Block* b = *bi;
|
||||||
|
for (auto ii = b->getInstructions().cbegin(); ii != b->getInstructions().cend(); ii++)
|
||||||
|
postProcess(*ii->get());
|
||||||
|
|
||||||
|
// For all local variables that contain pointers to PhysicalStorageBufferEXT, check whether
|
||||||
|
// there is an existing restrict/aliased decoration. If we don't find one, add Aliased as the
|
||||||
|
// default.
|
||||||
|
for (auto vi = b->getLocalVariables().cbegin(); vi != b->getLocalVariables().cend(); vi++) {
|
||||||
|
const Instruction& inst = *vi->get();
|
||||||
|
Id resultId = inst.getResultId();
|
||||||
|
if (containsPhysicalStorageBufferOrArray(getDerefTypeId(resultId))) {
|
||||||
|
bool foundDecoration = false;
|
||||||
|
const auto function = [&](const std::unique_ptr<Instruction>& decoration) {
|
||||||
|
if (decoration.get()->getIdOperand(0) == resultId &&
|
||||||
|
decoration.get()->getOpCode() == OpDecorate &&
|
||||||
|
(decoration.get()->getImmediateOperand(1) == spv::DecorationAliasedPointerEXT ||
|
||||||
|
decoration.get()->getImmediateOperand(1) == spv::DecorationRestrictPointerEXT)) {
|
||||||
|
foundDecoration = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
std::for_each(decorations.begin(), decorations.end(), function);
|
||||||
|
if (!foundDecoration) {
|
||||||
|
addDecoration(resultId, spv::DecorationAliasedPointerEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// comment in header
|
||||||
|
void Builder::postProcess() {
|
||||||
|
postProcessCFG();
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
postProcessFeatures();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end spv namespace
|
||||||
@@ -0,0 +1,214 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2014-2016 LunarG, Inc.
|
||||||
|
// Copyright (C) 2018 Google, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call into SPIRV-Tools to disassemble, validate, and optimize.
|
||||||
|
//
|
||||||
|
|
||||||
|
#if ENABLE_OPT
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "SpvTools.h"
|
||||||
|
#include "spirv-tools/optimizer.hpp"
|
||||||
|
#include "spirv-tools/libspirv.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
// Translate glslang's view of target versioning to what SPIRV-Tools uses.
|
||||||
|
spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger)
|
||||||
|
{
|
||||||
|
switch (spvVersion.vulkan) {
|
||||||
|
case glslang::EShTargetVulkan_1_0:
|
||||||
|
return spv_target_env::SPV_ENV_VULKAN_1_0;
|
||||||
|
case glslang::EShTargetVulkan_1_1:
|
||||||
|
switch (spvVersion.spv) {
|
||||||
|
case EShTargetSpv_1_0:
|
||||||
|
case EShTargetSpv_1_1:
|
||||||
|
case EShTargetSpv_1_2:
|
||||||
|
case EShTargetSpv_1_3:
|
||||||
|
return spv_target_env::SPV_ENV_VULKAN_1_1;
|
||||||
|
case EShTargetSpv_1_4:
|
||||||
|
return spv_target_env::SPV_ENV_VULKAN_1_1_SPIRV_1_4;
|
||||||
|
default:
|
||||||
|
logger->missingFunctionality("Target version for SPIRV-Tools validator");
|
||||||
|
return spv_target_env::SPV_ENV_VULKAN_1_1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (spvVersion.openGl > 0)
|
||||||
|
return spv_target_env::SPV_ENV_OPENGL_4_5;
|
||||||
|
|
||||||
|
logger->missingFunctionality("Target version for SPIRV-Tools validator");
|
||||||
|
return spv_target_env::SPV_ENV_UNIVERSAL_1_0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Use the SPIRV-Tools disassembler to print SPIR-V.
|
||||||
|
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv)
|
||||||
|
{
|
||||||
|
// disassemble
|
||||||
|
spv_context context = spvContextCreate(SPV_ENV_UNIVERSAL_1_3);
|
||||||
|
spv_text text;
|
||||||
|
spv_diagnostic diagnostic = nullptr;
|
||||||
|
spvBinaryToText(context, spirv.data(), spirv.size(),
|
||||||
|
SPV_BINARY_TO_TEXT_OPTION_FRIENDLY_NAMES | SPV_BINARY_TO_TEXT_OPTION_INDENT,
|
||||||
|
&text, &diagnostic);
|
||||||
|
|
||||||
|
// dump
|
||||||
|
if (diagnostic == nullptr)
|
||||||
|
out << text->str;
|
||||||
|
else
|
||||||
|
spvDiagnosticPrint(diagnostic);
|
||||||
|
|
||||||
|
// teardown
|
||||||
|
spvDiagnosticDestroy(diagnostic);
|
||||||
|
spvContextDestroy(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the SPIRV-Tools validator to generated SPIR-V.
|
||||||
|
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
|
spv::SpvBuildLogger* logger, bool prelegalization)
|
||||||
|
{
|
||||||
|
// validate
|
||||||
|
spv_context context = spvContextCreate(MapToSpirvToolsEnv(intermediate.getSpv(), logger));
|
||||||
|
spv_const_binary_t binary = { spirv.data(), spirv.size() };
|
||||||
|
spv_diagnostic diagnostic = nullptr;
|
||||||
|
spv_validator_options options = spvValidatorOptionsCreate();
|
||||||
|
spvValidatorOptionsSetRelaxBlockLayout(options, intermediate.usingHlslOffsets());
|
||||||
|
spvValidatorOptionsSetBeforeHlslLegalization(options, prelegalization);
|
||||||
|
spvValidateWithOptions(context, options, &binary, &diagnostic);
|
||||||
|
|
||||||
|
// report
|
||||||
|
if (diagnostic != nullptr) {
|
||||||
|
logger->error("SPIRV-Tools Validation Errors");
|
||||||
|
logger->error(diagnostic->error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// tear down
|
||||||
|
spvValidatorOptionsDestroy(options);
|
||||||
|
spvDiagnosticDestroy(diagnostic);
|
||||||
|
spvContextDestroy(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
|
||||||
|
// legalizing HLSL SPIR-V.
|
||||||
|
void SpirvToolsLegalize(const glslang::TIntermediate&, std::vector<unsigned int>& spirv,
|
||||||
|
spv::SpvBuildLogger*, const SpvOptions* options)
|
||||||
|
{
|
||||||
|
spv_target_env target_env = SPV_ENV_UNIVERSAL_1_2;
|
||||||
|
|
||||||
|
spvtools::Optimizer optimizer(target_env);
|
||||||
|
optimizer.SetMessageConsumer(
|
||||||
|
[](spv_message_level_t level, const char *source, const spv_position_t &position, const char *message) {
|
||||||
|
auto &out = std::cerr;
|
||||||
|
switch (level)
|
||||||
|
{
|
||||||
|
case SPV_MSG_FATAL:
|
||||||
|
case SPV_MSG_INTERNAL_ERROR:
|
||||||
|
case SPV_MSG_ERROR:
|
||||||
|
out << "error: ";
|
||||||
|
break;
|
||||||
|
case SPV_MSG_WARNING:
|
||||||
|
out << "warning: ";
|
||||||
|
break;
|
||||||
|
case SPV_MSG_INFO:
|
||||||
|
case SPV_MSG_DEBUG:
|
||||||
|
out << "info: ";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (source)
|
||||||
|
{
|
||||||
|
out << source << ":";
|
||||||
|
}
|
||||||
|
out << position.line << ":" << position.column << ":" << position.index << ":";
|
||||||
|
if (message)
|
||||||
|
{
|
||||||
|
out << " " << message;
|
||||||
|
}
|
||||||
|
out << std::endl;
|
||||||
|
});
|
||||||
|
|
||||||
|
// If debug (specifically source line info) is being generated, propagate
|
||||||
|
// line information into all SPIR-V instructions. This avoids loss of
|
||||||
|
// information when instructions are deleted or moved. Later, remove
|
||||||
|
// redundant information to minimize final SPRIR-V size.
|
||||||
|
if (options->generateDebugInfo) {
|
||||||
|
optimizer.RegisterPass(spvtools::CreatePropagateLineInfoPass());
|
||||||
|
}
|
||||||
|
optimizer.RegisterPass(spvtools::CreateWrapOpKillPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateMergeReturnPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateInlineExhaustivePass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateEliminateDeadFunctionsPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateScalarReplacementPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateLocalAccessChainConvertPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateLocalSingleBlockLoadStoreElimPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateLocalSingleStoreElimPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateSimplificationPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateDeadBranchElimPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateBlockMergePass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateLocalMultiStoreElimPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateIfConversionPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateSimplificationPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateVectorDCEPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateDeadInsertElimPass());
|
||||||
|
if (options->optimizeSize) {
|
||||||
|
optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass());
|
||||||
|
}
|
||||||
|
optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass());
|
||||||
|
optimizer.RegisterPass(spvtools::CreateCFGCleanupPass());
|
||||||
|
if (options->generateDebugInfo) {
|
||||||
|
optimizer.RegisterPass(spvtools::CreateRedundantLineInfoElimPass());
|
||||||
|
}
|
||||||
|
|
||||||
|
spvtools::OptimizerOptions spvOptOptions;
|
||||||
|
spvOptOptions.set_run_validator(false); // The validator may run as a seperate step later on
|
||||||
|
optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end namespace glslang
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2014-2016 LunarG, Inc.
|
||||||
|
// Copyright (C) 2018 Google, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Call into SPIRV-Tools to disassemble, validate, and optimize.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef GLSLANG_SPV_TOOLS_H
|
||||||
|
#define GLSLANG_SPV_TOOLS_H
|
||||||
|
|
||||||
|
#ifdef ENABLE_OPT
|
||||||
|
#include <vector>
|
||||||
|
#include <ostream>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "glslang/MachineIndependent/localintermediate.h"
|
||||||
|
#include "Logger.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
struct SpvOptions {
|
||||||
|
SpvOptions() : generateDebugInfo(false), disableOptimizer(true),
|
||||||
|
optimizeSize(false), disassemble(false), validate(false) { }
|
||||||
|
bool generateDebugInfo;
|
||||||
|
bool disableOptimizer;
|
||||||
|
bool optimizeSize;
|
||||||
|
bool disassemble;
|
||||||
|
bool validate;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef ENABLE_OPT
|
||||||
|
|
||||||
|
// Use the SPIRV-Tools disassembler to print SPIR-V.
|
||||||
|
void SpirvToolsDisassemble(std::ostream& out, const std::vector<unsigned int>& spirv);
|
||||||
|
|
||||||
|
// Apply the SPIRV-Tools validator to generated SPIR-V.
|
||||||
|
void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
|
spv::SpvBuildLogger*, bool prelegalization);
|
||||||
|
|
||||||
|
// Apply the SPIRV-Tools optimizer to generated SPIR-V, for the purpose of
|
||||||
|
// legalizing HLSL SPIR-V.
|
||||||
|
void SpirvToolsLegalize(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv,
|
||||||
|
spv::SpvBuildLogger*, const SpvOptions*);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // GLSLANG_SPV_TOOLS_H
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
// Copyright (c) 2015-2016 The Khronos Group Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef LIBSPIRV_UTIL_BITUTILS_H_
|
||||||
|
#define LIBSPIRV_UTIL_BITUTILS_H_
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace spvutils {
|
||||||
|
|
||||||
|
// Performs a bitwise copy of source to the destination type Dest.
|
||||||
|
template <typename Dest, typename Src>
|
||||||
|
Dest BitwiseCast(Src source) {
|
||||||
|
Dest dest;
|
||||||
|
static_assert(sizeof(source) == sizeof(dest),
|
||||||
|
"BitwiseCast: Source and destination must have the same size");
|
||||||
|
std::memcpy(static_cast<void*>(&dest), &source, sizeof(dest));
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBits<T, First, Num> returns an integer of type <T> with bits set
|
||||||
|
// for position <First> through <First + Num - 1>, counting from the least
|
||||||
|
// significant bit. In particular when Num == 0, no positions are set to 1.
|
||||||
|
// A static assert will be triggered if First + Num > sizeof(T) * 8, that is,
|
||||||
|
// a bit that will not fit in the underlying type is set.
|
||||||
|
template <typename T, size_t First = 0, size_t Num = 0>
|
||||||
|
struct SetBits {
|
||||||
|
static_assert(First < sizeof(T) * 8,
|
||||||
|
"Tried to set a bit that is shifted too far.");
|
||||||
|
const static T get = (T(1) << First) | SetBits<T, First + 1, Num - 1>::get;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T, size_t Last>
|
||||||
|
struct SetBits<T, Last, 0> {
|
||||||
|
const static T get = T(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is all compile-time so we can put our tests right here.
|
||||||
|
static_assert(SetBits<uint32_t, 0, 0>::get == uint32_t(0x00000000),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 0, 1>::get == uint32_t(0x00000001),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 31, 1>::get == uint32_t(0x80000000),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 1, 2>::get == uint32_t(0x00000006),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 30, 2>::get == uint32_t(0xc0000000),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 0, 31>::get == uint32_t(0x7FFFFFFF),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 0, 32>::get == uint32_t(0xFFFFFFFF),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint32_t, 16, 16>::get == uint32_t(0xFFFF0000),
|
||||||
|
"SetBits failed");
|
||||||
|
|
||||||
|
static_assert(SetBits<uint64_t, 0, 1>::get == uint64_t(0x0000000000000001LL),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint64_t, 63, 1>::get == uint64_t(0x8000000000000000LL),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint64_t, 62, 2>::get == uint64_t(0xc000000000000000LL),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint64_t, 31, 1>::get == uint64_t(0x0000000080000000LL),
|
||||||
|
"SetBits failed");
|
||||||
|
static_assert(SetBits<uint64_t, 16, 16>::get == uint64_t(0x00000000FFFF0000LL),
|
||||||
|
"SetBits failed");
|
||||||
|
|
||||||
|
} // namespace spvutils
|
||||||
|
|
||||||
|
#endif // LIBSPIRV_UTIL_BITUTILS_H_
|
||||||
@@ -0,0 +1,736 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disassembler for SPIR-V.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cassert>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <stack>
|
||||||
|
#include <sstream>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
#include "disassemble.h"
|
||||||
|
#include "doc.h"
|
||||||
|
#include "SpvTools.h"
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
extern "C" {
|
||||||
|
// Include C-based headers that don't have a namespace
|
||||||
|
#include "GLSL.std.450.h"
|
||||||
|
#include "GLSL.ext.AMD.h"
|
||||||
|
#include "GLSL.ext.NV.h"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const char* GlslStd450DebugNames[spv::GLSLstd450Count];
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
static const char* GLSLextAMDGetDebugNames(const char*, unsigned);
|
||||||
|
static const char* GLSLextNVGetDebugNames(const char*, unsigned);
|
||||||
|
|
||||||
|
static void Kill(std::ostream& out, const char* message)
|
||||||
|
{
|
||||||
|
out << std::endl << "Disassembly failed: " << message << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// used to identify the extended instruction library imported when printing
|
||||||
|
enum ExtInstSet {
|
||||||
|
GLSL450Inst,
|
||||||
|
GLSLextAMDInst,
|
||||||
|
GLSLextNVInst,
|
||||||
|
OpenCLExtInst,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Container class for a single instance of a SPIR-V stream, with methods for disassembly.
|
||||||
|
class SpirvStream {
|
||||||
|
public:
|
||||||
|
SpirvStream(std::ostream& out, const std::vector<unsigned int>& stream) : out(out), stream(stream), word(0), nextNestedControl(0) { }
|
||||||
|
virtual ~SpirvStream() { }
|
||||||
|
|
||||||
|
void validate();
|
||||||
|
void processInstructions();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SpirvStream(const SpirvStream&);
|
||||||
|
SpirvStream& operator=(const SpirvStream&);
|
||||||
|
Op getOpCode(int id) const { return idInstruction[id] ? (Op)(stream[idInstruction[id]] & OpCodeMask) : OpNop; }
|
||||||
|
|
||||||
|
// Output methods
|
||||||
|
void outputIndent();
|
||||||
|
void formatId(Id id, std::stringstream&);
|
||||||
|
void outputResultId(Id id);
|
||||||
|
void outputTypeId(Id id);
|
||||||
|
void outputId(Id id);
|
||||||
|
void outputMask(OperandClass operandClass, unsigned mask);
|
||||||
|
void disassembleImmediates(int numOperands);
|
||||||
|
void disassembleIds(int numOperands);
|
||||||
|
int disassembleString();
|
||||||
|
void disassembleInstruction(Id resultId, Id typeId, Op opCode, int numOperands);
|
||||||
|
|
||||||
|
// Data
|
||||||
|
std::ostream& out; // where to write the disassembly
|
||||||
|
const std::vector<unsigned int>& stream; // the actual word stream
|
||||||
|
int size; // the size of the word stream
|
||||||
|
int word; // the next word of the stream to read
|
||||||
|
|
||||||
|
// map each <id> to the instruction that created it
|
||||||
|
Id bound;
|
||||||
|
std::vector<unsigned int> idInstruction; // the word offset into the stream where the instruction for result [id] starts; 0 if not yet seen (forward reference or function parameter)
|
||||||
|
|
||||||
|
std::vector<std::string> idDescriptor; // the best text string known for explaining the <id>
|
||||||
|
|
||||||
|
// schema
|
||||||
|
unsigned int schema;
|
||||||
|
|
||||||
|
// stack of structured-merge points
|
||||||
|
std::stack<Id> nestedControl;
|
||||||
|
Id nextNestedControl; // need a slight delay for when we are nested
|
||||||
|
};
|
||||||
|
|
||||||
|
void SpirvStream::validate()
|
||||||
|
{
|
||||||
|
size = (int)stream.size();
|
||||||
|
if (size < 4)
|
||||||
|
Kill(out, "stream is too short");
|
||||||
|
|
||||||
|
// Magic number
|
||||||
|
if (stream[word++] != MagicNumber) {
|
||||||
|
out << "Bad magic number";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Version
|
||||||
|
out << "// Module Version " << std::hex << stream[word++] << std::endl;
|
||||||
|
|
||||||
|
// Generator's magic number
|
||||||
|
out << "// Generated by (magic number): " << std::hex << stream[word++] << std::dec << std::endl;
|
||||||
|
|
||||||
|
// Result <id> bound
|
||||||
|
bound = stream[word++];
|
||||||
|
idInstruction.resize(bound);
|
||||||
|
idDescriptor.resize(bound);
|
||||||
|
out << "// Id's are bound by " << bound << std::endl;
|
||||||
|
out << std::endl;
|
||||||
|
|
||||||
|
// Reserved schema, must be 0 for now
|
||||||
|
schema = stream[word++];
|
||||||
|
if (schema != 0)
|
||||||
|
Kill(out, "bad schema, must be 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Loop over all the instructions, in order, processing each.
|
||||||
|
// Boiler plate for each is handled here directly, the rest is dispatched.
|
||||||
|
void SpirvStream::processInstructions()
|
||||||
|
{
|
||||||
|
// Instructions
|
||||||
|
while (word < size) {
|
||||||
|
int instructionStart = word;
|
||||||
|
|
||||||
|
// Instruction wordCount and opcode
|
||||||
|
unsigned int firstWord = stream[word];
|
||||||
|
unsigned wordCount = firstWord >> WordCountShift;
|
||||||
|
Op opCode = (Op)(firstWord & OpCodeMask);
|
||||||
|
int nextInst = word + wordCount;
|
||||||
|
++word;
|
||||||
|
|
||||||
|
// Presence of full instruction
|
||||||
|
if (nextInst > size)
|
||||||
|
Kill(out, "stream instruction terminated too early");
|
||||||
|
|
||||||
|
// Base for computing number of operands; will be updated as more is learned
|
||||||
|
unsigned numOperands = wordCount - 1;
|
||||||
|
|
||||||
|
// Type <id>
|
||||||
|
Id typeId = 0;
|
||||||
|
if (InstructionDesc[opCode].hasType()) {
|
||||||
|
typeId = stream[word++];
|
||||||
|
--numOperands;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Result <id>
|
||||||
|
Id resultId = 0;
|
||||||
|
if (InstructionDesc[opCode].hasResult()) {
|
||||||
|
resultId = stream[word++];
|
||||||
|
--numOperands;
|
||||||
|
|
||||||
|
// save instruction for future reference
|
||||||
|
idInstruction[resultId] = instructionStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
outputResultId(resultId);
|
||||||
|
outputTypeId(typeId);
|
||||||
|
outputIndent();
|
||||||
|
|
||||||
|
// Hand off the Op and all its operands
|
||||||
|
disassembleInstruction(resultId, typeId, opCode, numOperands);
|
||||||
|
if (word != nextInst) {
|
||||||
|
out << " ERROR, incorrect number of operands consumed. At " << word << " instead of " << nextInst << " instruction start was " << instructionStart;
|
||||||
|
word = nextInst;
|
||||||
|
}
|
||||||
|
out << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpirvStream::outputIndent()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (int)nestedControl.size(); ++i)
|
||||||
|
out << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpirvStream::formatId(Id id, std::stringstream& idStream)
|
||||||
|
{
|
||||||
|
if (id != 0) {
|
||||||
|
// On instructions with no IDs, this is called with "0", which does not
|
||||||
|
// have to be within ID bounds on null shaders.
|
||||||
|
if (id >= bound)
|
||||||
|
Kill(out, "Bad <id>");
|
||||||
|
|
||||||
|
idStream << id;
|
||||||
|
if (idDescriptor[id].size() > 0)
|
||||||
|
idStream << "(" << idDescriptor[id] << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpirvStream::outputResultId(Id id)
|
||||||
|
{
|
||||||
|
const int width = 16;
|
||||||
|
std::stringstream idStream;
|
||||||
|
formatId(id, idStream);
|
||||||
|
out << std::setw(width) << std::right << idStream.str();
|
||||||
|
if (id != 0)
|
||||||
|
out << ":";
|
||||||
|
else
|
||||||
|
out << " ";
|
||||||
|
|
||||||
|
if (nestedControl.size() && id == nestedControl.top())
|
||||||
|
nestedControl.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpirvStream::outputTypeId(Id id)
|
||||||
|
{
|
||||||
|
const int width = 12;
|
||||||
|
std::stringstream idStream;
|
||||||
|
formatId(id, idStream);
|
||||||
|
out << std::setw(width) << std::right << idStream.str() << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpirvStream::outputId(Id id)
|
||||||
|
{
|
||||||
|
if (id >= bound)
|
||||||
|
Kill(out, "Bad <id>");
|
||||||
|
|
||||||
|
out << id;
|
||||||
|
if (idDescriptor[id].size() > 0)
|
||||||
|
out << "(" << idDescriptor[id] << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpirvStream::outputMask(OperandClass operandClass, unsigned mask)
|
||||||
|
{
|
||||||
|
if (mask == 0)
|
||||||
|
out << "None";
|
||||||
|
else {
|
||||||
|
for (int m = 0; m < OperandClassParams[operandClass].ceiling; ++m) {
|
||||||
|
if (mask & (1 << m))
|
||||||
|
out << OperandClassParams[operandClass].getName(m) << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpirvStream::disassembleImmediates(int numOperands)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < numOperands; ++i) {
|
||||||
|
out << stream[word++];
|
||||||
|
if (i < numOperands - 1)
|
||||||
|
out << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpirvStream::disassembleIds(int numOperands)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < numOperands; ++i) {
|
||||||
|
outputId(stream[word++]);
|
||||||
|
if (i < numOperands - 1)
|
||||||
|
out << " ";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the number of operands consumed by the string
|
||||||
|
int SpirvStream::disassembleString()
|
||||||
|
{
|
||||||
|
int startWord = word;
|
||||||
|
|
||||||
|
out << " \"";
|
||||||
|
|
||||||
|
const char* wordString;
|
||||||
|
bool done = false;
|
||||||
|
do {
|
||||||
|
unsigned int content = stream[word];
|
||||||
|
wordString = (const char*)&content;
|
||||||
|
for (int charCount = 0; charCount < 4; ++charCount) {
|
||||||
|
if (*wordString == 0) {
|
||||||
|
done = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out << *(wordString++);
|
||||||
|
}
|
||||||
|
++word;
|
||||||
|
} while (! done);
|
||||||
|
|
||||||
|
out << "\"";
|
||||||
|
|
||||||
|
return word - startWord;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, int numOperands)
|
||||||
|
{
|
||||||
|
// Process the opcode
|
||||||
|
|
||||||
|
out << (OpcodeString(opCode) + 2); // leave out the "Op"
|
||||||
|
|
||||||
|
if (opCode == OpLoopMerge || opCode == OpSelectionMerge)
|
||||||
|
nextNestedControl = stream[word];
|
||||||
|
else if (opCode == OpBranchConditional || opCode == OpSwitch) {
|
||||||
|
if (nextNestedControl) {
|
||||||
|
nestedControl.push(nextNestedControl);
|
||||||
|
nextNestedControl = 0;
|
||||||
|
}
|
||||||
|
} else if (opCode == OpExtInstImport) {
|
||||||
|
idDescriptor[resultId] = (const char*)(&stream[word]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (resultId != 0 && idDescriptor[resultId].size() == 0) {
|
||||||
|
switch (opCode) {
|
||||||
|
case OpTypeInt:
|
||||||
|
switch (stream[word]) {
|
||||||
|
case 8: idDescriptor[resultId] = "int8_t"; break;
|
||||||
|
case 16: idDescriptor[resultId] = "int16_t"; break;
|
||||||
|
default: assert(0); // fallthrough
|
||||||
|
case 32: idDescriptor[resultId] = "int"; break;
|
||||||
|
case 64: idDescriptor[resultId] = "int64_t"; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OpTypeFloat:
|
||||||
|
switch (stream[word]) {
|
||||||
|
case 16: idDescriptor[resultId] = "float16_t"; break;
|
||||||
|
default: assert(0); // fallthrough
|
||||||
|
case 32: idDescriptor[resultId] = "float"; break;
|
||||||
|
case 64: idDescriptor[resultId] = "float64_t"; break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OpTypeBool:
|
||||||
|
idDescriptor[resultId] = "bool";
|
||||||
|
break;
|
||||||
|
case OpTypeStruct:
|
||||||
|
idDescriptor[resultId] = "struct";
|
||||||
|
break;
|
||||||
|
case OpTypePointer:
|
||||||
|
idDescriptor[resultId] = "ptr";
|
||||||
|
break;
|
||||||
|
case OpTypeVector:
|
||||||
|
if (idDescriptor[stream[word]].size() > 0) {
|
||||||
|
idDescriptor[resultId].append(idDescriptor[stream[word]].begin(), idDescriptor[stream[word]].begin() + 1);
|
||||||
|
if (strstr(idDescriptor[stream[word]].c_str(), "8")) {
|
||||||
|
idDescriptor[resultId].append("8");
|
||||||
|
}
|
||||||
|
if (strstr(idDescriptor[stream[word]].c_str(), "16")) {
|
||||||
|
idDescriptor[resultId].append("16");
|
||||||
|
}
|
||||||
|
if (strstr(idDescriptor[stream[word]].c_str(), "64")) {
|
||||||
|
idDescriptor[resultId].append("64");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
idDescriptor[resultId].append("vec");
|
||||||
|
switch (stream[word + 1]) {
|
||||||
|
case 2: idDescriptor[resultId].append("2"); break;
|
||||||
|
case 3: idDescriptor[resultId].append("3"); break;
|
||||||
|
case 4: idDescriptor[resultId].append("4"); break;
|
||||||
|
case 8: idDescriptor[resultId].append("8"); break;
|
||||||
|
case 16: idDescriptor[resultId].append("16"); break;
|
||||||
|
case 32: idDescriptor[resultId].append("32"); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the operands. Note, a new context-dependent set could be
|
||||||
|
// swapped in mid-traversal.
|
||||||
|
|
||||||
|
// Handle images specially, so can put out helpful strings.
|
||||||
|
if (opCode == OpTypeImage) {
|
||||||
|
out << " ";
|
||||||
|
disassembleIds(1);
|
||||||
|
out << " " << DimensionString((Dim)stream[word++]);
|
||||||
|
out << (stream[word++] != 0 ? " depth" : "");
|
||||||
|
out << (stream[word++] != 0 ? " array" : "");
|
||||||
|
out << (stream[word++] != 0 ? " multi-sampled" : "");
|
||||||
|
switch (stream[word++]) {
|
||||||
|
case 0: out << " runtime"; break;
|
||||||
|
case 1: out << " sampled"; break;
|
||||||
|
case 2: out << " nonsampled"; break;
|
||||||
|
}
|
||||||
|
out << " format:" << ImageFormatString((ImageFormat)stream[word++]);
|
||||||
|
|
||||||
|
if (numOperands == 8) {
|
||||||
|
out << " " << AccessQualifierString(stream[word++]);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle all the parameterized operands
|
||||||
|
for (int op = 0; op < InstructionDesc[opCode].operands.getNum() && numOperands > 0; ++op) {
|
||||||
|
out << " ";
|
||||||
|
OperandClass operandClass = InstructionDesc[opCode].operands.getClass(op);
|
||||||
|
switch (operandClass) {
|
||||||
|
case OperandId:
|
||||||
|
case OperandScope:
|
||||||
|
case OperandMemorySemantics:
|
||||||
|
disassembleIds(1);
|
||||||
|
--numOperands;
|
||||||
|
// Get names for printing "(XXX)" for readability, *after* this id
|
||||||
|
if (opCode == OpName)
|
||||||
|
idDescriptor[stream[word - 1]] = (const char*)(&stream[word]);
|
||||||
|
break;
|
||||||
|
case OperandVariableIds:
|
||||||
|
disassembleIds(numOperands);
|
||||||
|
return;
|
||||||
|
case OperandImageOperands:
|
||||||
|
outputMask(OperandImageOperands, stream[word++]);
|
||||||
|
--numOperands;
|
||||||
|
disassembleIds(numOperands);
|
||||||
|
return;
|
||||||
|
case OperandOptionalLiteral:
|
||||||
|
case OperandVariableLiterals:
|
||||||
|
if ((opCode == OpDecorate && stream[word - 1] == DecorationBuiltIn) ||
|
||||||
|
(opCode == OpMemberDecorate && stream[word - 1] == DecorationBuiltIn)) {
|
||||||
|
out << BuiltInString(stream[word++]);
|
||||||
|
--numOperands;
|
||||||
|
++op;
|
||||||
|
}
|
||||||
|
disassembleImmediates(numOperands);
|
||||||
|
return;
|
||||||
|
case OperandVariableIdLiteral:
|
||||||
|
while (numOperands > 0) {
|
||||||
|
out << std::endl;
|
||||||
|
outputResultId(0);
|
||||||
|
outputTypeId(0);
|
||||||
|
outputIndent();
|
||||||
|
out << " Type ";
|
||||||
|
disassembleIds(1);
|
||||||
|
out << ", member ";
|
||||||
|
disassembleImmediates(1);
|
||||||
|
numOperands -= 2;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case OperandVariableLiteralId:
|
||||||
|
while (numOperands > 0) {
|
||||||
|
out << std::endl;
|
||||||
|
outputResultId(0);
|
||||||
|
outputTypeId(0);
|
||||||
|
outputIndent();
|
||||||
|
out << " case ";
|
||||||
|
disassembleImmediates(1);
|
||||||
|
out << ": ";
|
||||||
|
disassembleIds(1);
|
||||||
|
numOperands -= 2;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case OperandLiteralNumber:
|
||||||
|
disassembleImmediates(1);
|
||||||
|
--numOperands;
|
||||||
|
if (opCode == OpExtInst) {
|
||||||
|
ExtInstSet extInstSet = GLSL450Inst;
|
||||||
|
const char* name = idDescriptor[stream[word - 2]].c_str();
|
||||||
|
if (0 == memcmp("OpenCL", name, 6)) {
|
||||||
|
extInstSet = OpenCLExtInst;
|
||||||
|
} else if (strcmp(spv::E_SPV_AMD_shader_ballot, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_AMD_shader_trinary_minmax, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_AMD_shader_explicit_vertex_parameter, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_AMD_gcn_shader, name) == 0) {
|
||||||
|
extInstSet = GLSLextAMDInst;
|
||||||
|
} else if (strcmp(spv::E_SPV_NV_sample_mask_override_coverage, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NV_geometry_shader_passthrough, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NV_viewport_array2, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NVX_multiview_per_view_attributes, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NV_fragment_shader_barycentric, name) == 0 ||
|
||||||
|
strcmp(spv::E_SPV_NV_mesh_shader, name) == 0) {
|
||||||
|
extInstSet = GLSLextNVInst;
|
||||||
|
}
|
||||||
|
unsigned entrypoint = stream[word - 1];
|
||||||
|
if (extInstSet == GLSL450Inst) {
|
||||||
|
if (entrypoint < GLSLstd450Count) {
|
||||||
|
out << "(" << GlslStd450DebugNames[entrypoint] << ")";
|
||||||
|
}
|
||||||
|
} else if (extInstSet == GLSLextAMDInst) {
|
||||||
|
out << "(" << GLSLextAMDGetDebugNames(name, entrypoint) << ")";
|
||||||
|
}
|
||||||
|
else if (extInstSet == GLSLextNVInst) {
|
||||||
|
out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case OperandOptionalLiteralString:
|
||||||
|
case OperandLiteralString:
|
||||||
|
numOperands -= disassembleString();
|
||||||
|
break;
|
||||||
|
case OperandMemoryAccess:
|
||||||
|
outputMask(OperandMemoryAccess, stream[word++]);
|
||||||
|
--numOperands;
|
||||||
|
// Aligned is the only memory access operand that uses an immediate
|
||||||
|
// value, and it is also the first operand that uses a value at all.
|
||||||
|
if (stream[word-1] & MemoryAccessAlignedMask) {
|
||||||
|
disassembleImmediates(1);
|
||||||
|
numOperands--;
|
||||||
|
if (numOperands)
|
||||||
|
out << " ";
|
||||||
|
}
|
||||||
|
disassembleIds(numOperands);
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
assert(operandClass >= OperandSource && operandClass < OperandOpcode);
|
||||||
|
|
||||||
|
if (OperandClassParams[operandClass].bitmask)
|
||||||
|
outputMask(operandClass, stream[word++]);
|
||||||
|
else
|
||||||
|
out << OperandClassParams[operandClass].getName(stream[word++]);
|
||||||
|
--numOperands;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void GLSLstd450GetDebugNames(const char** names)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < GLSLstd450Count; ++i)
|
||||||
|
names[i] = "Unknown";
|
||||||
|
|
||||||
|
names[GLSLstd450Round] = "Round";
|
||||||
|
names[GLSLstd450RoundEven] = "RoundEven";
|
||||||
|
names[GLSLstd450Trunc] = "Trunc";
|
||||||
|
names[GLSLstd450FAbs] = "FAbs";
|
||||||
|
names[GLSLstd450SAbs] = "SAbs";
|
||||||
|
names[GLSLstd450FSign] = "FSign";
|
||||||
|
names[GLSLstd450SSign] = "SSign";
|
||||||
|
names[GLSLstd450Floor] = "Floor";
|
||||||
|
names[GLSLstd450Ceil] = "Ceil";
|
||||||
|
names[GLSLstd450Fract] = "Fract";
|
||||||
|
names[GLSLstd450Radians] = "Radians";
|
||||||
|
names[GLSLstd450Degrees] = "Degrees";
|
||||||
|
names[GLSLstd450Sin] = "Sin";
|
||||||
|
names[GLSLstd450Cos] = "Cos";
|
||||||
|
names[GLSLstd450Tan] = "Tan";
|
||||||
|
names[GLSLstd450Asin] = "Asin";
|
||||||
|
names[GLSLstd450Acos] = "Acos";
|
||||||
|
names[GLSLstd450Atan] = "Atan";
|
||||||
|
names[GLSLstd450Sinh] = "Sinh";
|
||||||
|
names[GLSLstd450Cosh] = "Cosh";
|
||||||
|
names[GLSLstd450Tanh] = "Tanh";
|
||||||
|
names[GLSLstd450Asinh] = "Asinh";
|
||||||
|
names[GLSLstd450Acosh] = "Acosh";
|
||||||
|
names[GLSLstd450Atanh] = "Atanh";
|
||||||
|
names[GLSLstd450Atan2] = "Atan2";
|
||||||
|
names[GLSLstd450Pow] = "Pow";
|
||||||
|
names[GLSLstd450Exp] = "Exp";
|
||||||
|
names[GLSLstd450Log] = "Log";
|
||||||
|
names[GLSLstd450Exp2] = "Exp2";
|
||||||
|
names[GLSLstd450Log2] = "Log2";
|
||||||
|
names[GLSLstd450Sqrt] = "Sqrt";
|
||||||
|
names[GLSLstd450InverseSqrt] = "InverseSqrt";
|
||||||
|
names[GLSLstd450Determinant] = "Determinant";
|
||||||
|
names[GLSLstd450MatrixInverse] = "MatrixInverse";
|
||||||
|
names[GLSLstd450Modf] = "Modf";
|
||||||
|
names[GLSLstd450ModfStruct] = "ModfStruct";
|
||||||
|
names[GLSLstd450FMin] = "FMin";
|
||||||
|
names[GLSLstd450SMin] = "SMin";
|
||||||
|
names[GLSLstd450UMin] = "UMin";
|
||||||
|
names[GLSLstd450FMax] = "FMax";
|
||||||
|
names[GLSLstd450SMax] = "SMax";
|
||||||
|
names[GLSLstd450UMax] = "UMax";
|
||||||
|
names[GLSLstd450FClamp] = "FClamp";
|
||||||
|
names[GLSLstd450SClamp] = "SClamp";
|
||||||
|
names[GLSLstd450UClamp] = "UClamp";
|
||||||
|
names[GLSLstd450FMix] = "FMix";
|
||||||
|
names[GLSLstd450Step] = "Step";
|
||||||
|
names[GLSLstd450SmoothStep] = "SmoothStep";
|
||||||
|
names[GLSLstd450Fma] = "Fma";
|
||||||
|
names[GLSLstd450Frexp] = "Frexp";
|
||||||
|
names[GLSLstd450FrexpStruct] = "FrexpStruct";
|
||||||
|
names[GLSLstd450Ldexp] = "Ldexp";
|
||||||
|
names[GLSLstd450PackSnorm4x8] = "PackSnorm4x8";
|
||||||
|
names[GLSLstd450PackUnorm4x8] = "PackUnorm4x8";
|
||||||
|
names[GLSLstd450PackSnorm2x16] = "PackSnorm2x16";
|
||||||
|
names[GLSLstd450PackUnorm2x16] = "PackUnorm2x16";
|
||||||
|
names[GLSLstd450PackHalf2x16] = "PackHalf2x16";
|
||||||
|
names[GLSLstd450PackDouble2x32] = "PackDouble2x32";
|
||||||
|
names[GLSLstd450UnpackSnorm2x16] = "UnpackSnorm2x16";
|
||||||
|
names[GLSLstd450UnpackUnorm2x16] = "UnpackUnorm2x16";
|
||||||
|
names[GLSLstd450UnpackHalf2x16] = "UnpackHalf2x16";
|
||||||
|
names[GLSLstd450UnpackSnorm4x8] = "UnpackSnorm4x8";
|
||||||
|
names[GLSLstd450UnpackUnorm4x8] = "UnpackUnorm4x8";
|
||||||
|
names[GLSLstd450UnpackDouble2x32] = "UnpackDouble2x32";
|
||||||
|
names[GLSLstd450Length] = "Length";
|
||||||
|
names[GLSLstd450Distance] = "Distance";
|
||||||
|
names[GLSLstd450Cross] = "Cross";
|
||||||
|
names[GLSLstd450Normalize] = "Normalize";
|
||||||
|
names[GLSLstd450FaceForward] = "FaceForward";
|
||||||
|
names[GLSLstd450Reflect] = "Reflect";
|
||||||
|
names[GLSLstd450Refract] = "Refract";
|
||||||
|
names[GLSLstd450FindILsb] = "FindILsb";
|
||||||
|
names[GLSLstd450FindSMsb] = "FindSMsb";
|
||||||
|
names[GLSLstd450FindUMsb] = "FindUMsb";
|
||||||
|
names[GLSLstd450InterpolateAtCentroid] = "InterpolateAtCentroid";
|
||||||
|
names[GLSLstd450InterpolateAtSample] = "InterpolateAtSample";
|
||||||
|
names[GLSLstd450InterpolateAtOffset] = "InterpolateAtOffset";
|
||||||
|
names[GLSLstd450NMin] = "NMin";
|
||||||
|
names[GLSLstd450NMax] = "NMax";
|
||||||
|
names[GLSLstd450NClamp] = "NClamp";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* GLSLextAMDGetDebugNames(const char* name, unsigned entrypoint)
|
||||||
|
{
|
||||||
|
if (strcmp(name, spv::E_SPV_AMD_shader_ballot) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case SwizzleInvocationsAMD: return "SwizzleInvocationsAMD";
|
||||||
|
case SwizzleInvocationsMaskedAMD: return "SwizzleInvocationsMaskedAMD";
|
||||||
|
case WriteInvocationAMD: return "WriteInvocationAMD";
|
||||||
|
case MbcntAMD: return "MbcntAMD";
|
||||||
|
default: return "Bad";
|
||||||
|
}
|
||||||
|
} else if (strcmp(name, spv::E_SPV_AMD_shader_trinary_minmax) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case FMin3AMD: return "FMin3AMD";
|
||||||
|
case UMin3AMD: return "UMin3AMD";
|
||||||
|
case SMin3AMD: return "SMin3AMD";
|
||||||
|
case FMax3AMD: return "FMax3AMD";
|
||||||
|
case UMax3AMD: return "UMax3AMD";
|
||||||
|
case SMax3AMD: return "SMax3AMD";
|
||||||
|
case FMid3AMD: return "FMid3AMD";
|
||||||
|
case UMid3AMD: return "UMid3AMD";
|
||||||
|
case SMid3AMD: return "SMid3AMD";
|
||||||
|
default: return "Bad";
|
||||||
|
}
|
||||||
|
} else if (strcmp(name, spv::E_SPV_AMD_shader_explicit_vertex_parameter) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case InterpolateAtVertexAMD: return "InterpolateAtVertexAMD";
|
||||||
|
default: return "Bad";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(name, spv::E_SPV_AMD_gcn_shader) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
case CubeFaceIndexAMD: return "CubeFaceIndexAMD";
|
||||||
|
case CubeFaceCoordAMD: return "CubeFaceCoordAMD";
|
||||||
|
case TimeAMD: return "TimeAMD";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Bad";
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint)
|
||||||
|
{
|
||||||
|
if (strcmp(name, spv::E_SPV_NV_sample_mask_override_coverage) == 0 ||
|
||||||
|
strcmp(name, spv::E_SPV_NV_geometry_shader_passthrough) == 0 ||
|
||||||
|
strcmp(name, spv::E_ARB_shader_viewport_layer_array) == 0 ||
|
||||||
|
strcmp(name, spv::E_SPV_NV_viewport_array2) == 0 ||
|
||||||
|
strcmp(name, spv::E_SPV_NVX_multiview_per_view_attributes) == 0 ||
|
||||||
|
strcmp(name, spv::E_SPV_NV_fragment_shader_barycentric) == 0 ||
|
||||||
|
strcmp(name, spv::E_SPV_NV_mesh_shader) == 0 ||
|
||||||
|
strcmp(name, spv::E_SPV_NV_shader_image_footprint) == 0) {
|
||||||
|
switch (entrypoint) {
|
||||||
|
// NV builtins
|
||||||
|
case BuiltInViewportMaskNV: return "ViewportMaskNV";
|
||||||
|
case BuiltInSecondaryPositionNV: return "SecondaryPositionNV";
|
||||||
|
case BuiltInSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||||
|
case BuiltInPositionPerViewNV: return "PositionPerViewNV";
|
||||||
|
case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV";
|
||||||
|
case BuiltInBaryCoordNV: return "BaryCoordNV";
|
||||||
|
case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
||||||
|
case BuiltInTaskCountNV: return "TaskCountNV";
|
||||||
|
case BuiltInPrimitiveCountNV: return "PrimitiveCountNV";
|
||||||
|
case BuiltInPrimitiveIndicesNV: return "PrimitiveIndicesNV";
|
||||||
|
case BuiltInClipDistancePerViewNV: return "ClipDistancePerViewNV";
|
||||||
|
case BuiltInCullDistancePerViewNV: return "CullDistancePerViewNV";
|
||||||
|
case BuiltInLayerPerViewNV: return "LayerPerViewNV";
|
||||||
|
case BuiltInMeshViewCountNV: return "MeshViewCountNV";
|
||||||
|
case BuiltInMeshViewIndicesNV: return "MeshViewIndicesNV";
|
||||||
|
|
||||||
|
// NV Capabilities
|
||||||
|
case CapabilityGeometryShaderPassthroughNV: return "GeometryShaderPassthroughNV";
|
||||||
|
case CapabilityShaderViewportMaskNV: return "ShaderViewportMaskNV";
|
||||||
|
case CapabilityShaderStereoViewNV: return "ShaderStereoViewNV";
|
||||||
|
case CapabilityPerViewAttributesNV: return "PerViewAttributesNV";
|
||||||
|
case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV";
|
||||||
|
case CapabilityMeshShadingNV: return "MeshShadingNV";
|
||||||
|
case CapabilityImageFootprintNV: return "ImageFootprintNV";
|
||||||
|
case CapabilitySampleMaskOverrideCoverageNV:return "SampleMaskOverrideCoverageNV";
|
||||||
|
|
||||||
|
// NV Decorations
|
||||||
|
case DecorationOverrideCoverageNV: return "OverrideCoverageNV";
|
||||||
|
case DecorationPassthroughNV: return "PassthroughNV";
|
||||||
|
case DecorationViewportRelativeNV: return "ViewportRelativeNV";
|
||||||
|
case DecorationSecondaryViewportRelativeNV: return "SecondaryViewportRelativeNV";
|
||||||
|
case DecorationPerVertexNV: return "PerVertexNV";
|
||||||
|
case DecorationPerPrimitiveNV: return "PerPrimitiveNV";
|
||||||
|
case DecorationPerViewNV: return "PerViewNV";
|
||||||
|
case DecorationPerTaskNV: return "PerTaskNV";
|
||||||
|
|
||||||
|
default: return "Bad";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "Bad";
|
||||||
|
}
|
||||||
|
|
||||||
|
void Disassemble(std::ostream& out, const std::vector<unsigned int>& stream)
|
||||||
|
{
|
||||||
|
SpirvStream SpirvStream(out, stream);
|
||||||
|
spv::Parameterize();
|
||||||
|
GLSLstd450GetDebugNames(GlslStd450DebugNames);
|
||||||
|
SpirvStream.validate();
|
||||||
|
SpirvStream.processInstructions();
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end namespace spv
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Disassembler for SPIR-V.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef disassembler_H
|
||||||
|
#define disassembler_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
// disassemble with glslang custom disassembler
|
||||||
|
void Disassemble(std::ostream& out, const std::vector<unsigned int>&);
|
||||||
|
|
||||||
|
} // end namespace spv
|
||||||
|
|
||||||
|
#endif // disassembler_H
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,258 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2014-2015 LunarG, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Parameterize the SPIR-V enumerants.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "spirv.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
// Fill in all the parameters
|
||||||
|
void Parameterize();
|
||||||
|
|
||||||
|
// Return the English names of all the enums.
|
||||||
|
const char* SourceString(int);
|
||||||
|
const char* AddressingString(int);
|
||||||
|
const char* MemoryString(int);
|
||||||
|
const char* ExecutionModelString(int);
|
||||||
|
const char* ExecutionModeString(int);
|
||||||
|
const char* StorageClassString(int);
|
||||||
|
const char* DecorationString(int);
|
||||||
|
const char* BuiltInString(int);
|
||||||
|
const char* DimensionString(int);
|
||||||
|
const char* SelectControlString(int);
|
||||||
|
const char* LoopControlString(int);
|
||||||
|
const char* FunctionControlString(int);
|
||||||
|
const char* SamplerAddressingModeString(int);
|
||||||
|
const char* SamplerFilterModeString(int);
|
||||||
|
const char* ImageFormatString(int);
|
||||||
|
const char* ImageChannelOrderString(int);
|
||||||
|
const char* ImageChannelTypeString(int);
|
||||||
|
const char* ImageChannelDataTypeString(int type);
|
||||||
|
const char* ImageOperandsString(int format);
|
||||||
|
const char* ImageOperands(int);
|
||||||
|
const char* FPFastMathString(int);
|
||||||
|
const char* FPRoundingModeString(int);
|
||||||
|
const char* LinkageTypeString(int);
|
||||||
|
const char* FuncParamAttrString(int);
|
||||||
|
const char* AccessQualifierString(int);
|
||||||
|
const char* MemorySemanticsString(int);
|
||||||
|
const char* MemoryAccessString(int);
|
||||||
|
const char* ExecutionScopeString(int);
|
||||||
|
const char* GroupOperationString(int);
|
||||||
|
const char* KernelEnqueueFlagsString(int);
|
||||||
|
const char* KernelProfilingInfoString(int);
|
||||||
|
const char* CapabilityString(int);
|
||||||
|
const char* OpcodeString(int);
|
||||||
|
const char* ScopeString(int mem);
|
||||||
|
|
||||||
|
// For grouping opcodes into subsections
|
||||||
|
enum OpcodeClass {
|
||||||
|
OpClassMisc,
|
||||||
|
OpClassDebug,
|
||||||
|
OpClassAnnotate,
|
||||||
|
OpClassExtension,
|
||||||
|
OpClassMode,
|
||||||
|
OpClassType,
|
||||||
|
OpClassConstant,
|
||||||
|
OpClassMemory,
|
||||||
|
OpClassFunction,
|
||||||
|
OpClassImage,
|
||||||
|
OpClassConvert,
|
||||||
|
OpClassComposite,
|
||||||
|
OpClassArithmetic,
|
||||||
|
OpClassBit,
|
||||||
|
OpClassRelationalLogical,
|
||||||
|
OpClassDerivative,
|
||||||
|
OpClassFlowControl,
|
||||||
|
OpClassAtomic,
|
||||||
|
OpClassPrimitive,
|
||||||
|
OpClassBarrier,
|
||||||
|
OpClassGroup,
|
||||||
|
OpClassDeviceSideEnqueue,
|
||||||
|
OpClassPipe,
|
||||||
|
|
||||||
|
OpClassCount,
|
||||||
|
OpClassMissing // all instructions start out as missing
|
||||||
|
};
|
||||||
|
|
||||||
|
// For parameterizing operands.
|
||||||
|
enum OperandClass {
|
||||||
|
OperandNone,
|
||||||
|
OperandId,
|
||||||
|
OperandVariableIds,
|
||||||
|
OperandOptionalLiteral,
|
||||||
|
OperandOptionalLiteralString,
|
||||||
|
OperandVariableLiterals,
|
||||||
|
OperandVariableIdLiteral,
|
||||||
|
OperandVariableLiteralId,
|
||||||
|
OperandLiteralNumber,
|
||||||
|
OperandLiteralString,
|
||||||
|
OperandSource,
|
||||||
|
OperandExecutionModel,
|
||||||
|
OperandAddressing,
|
||||||
|
OperandMemory,
|
||||||
|
OperandExecutionMode,
|
||||||
|
OperandStorage,
|
||||||
|
OperandDimensionality,
|
||||||
|
OperandSamplerAddressingMode,
|
||||||
|
OperandSamplerFilterMode,
|
||||||
|
OperandSamplerImageFormat,
|
||||||
|
OperandImageChannelOrder,
|
||||||
|
OperandImageChannelDataType,
|
||||||
|
OperandImageOperands,
|
||||||
|
OperandFPFastMath,
|
||||||
|
OperandFPRoundingMode,
|
||||||
|
OperandLinkageType,
|
||||||
|
OperandAccessQualifier,
|
||||||
|
OperandFuncParamAttr,
|
||||||
|
OperandDecoration,
|
||||||
|
OperandBuiltIn,
|
||||||
|
OperandSelect,
|
||||||
|
OperandLoop,
|
||||||
|
OperandFunction,
|
||||||
|
OperandMemorySemantics,
|
||||||
|
OperandMemoryAccess,
|
||||||
|
OperandScope,
|
||||||
|
OperandGroupOperation,
|
||||||
|
OperandKernelEnqueueFlags,
|
||||||
|
OperandKernelProfilingInfo,
|
||||||
|
OperandCapability,
|
||||||
|
|
||||||
|
OperandOpcode,
|
||||||
|
|
||||||
|
OperandCount
|
||||||
|
};
|
||||||
|
|
||||||
|
// Any specific enum can have a set of capabilities that allow it:
|
||||||
|
typedef std::vector<Capability> EnumCaps;
|
||||||
|
|
||||||
|
// Parameterize a set of operands with their OperandClass(es) and descriptions.
|
||||||
|
class OperandParameters {
|
||||||
|
public:
|
||||||
|
OperandParameters() { }
|
||||||
|
void push(OperandClass oc, const char* d, bool opt = false)
|
||||||
|
{
|
||||||
|
opClass.push_back(oc);
|
||||||
|
desc.push_back(d);
|
||||||
|
optional.push_back(opt);
|
||||||
|
}
|
||||||
|
void setOptional();
|
||||||
|
OperandClass getClass(int op) const { return opClass[op]; }
|
||||||
|
const char* getDesc(int op) const { return desc[op]; }
|
||||||
|
bool isOptional(int op) const { return optional[op]; }
|
||||||
|
int getNum() const { return (int)opClass.size(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<OperandClass> opClass;
|
||||||
|
std::vector<const char*> desc;
|
||||||
|
std::vector<bool> optional;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parameterize an enumerant
|
||||||
|
class EnumParameters {
|
||||||
|
public:
|
||||||
|
EnumParameters() : desc(0) { }
|
||||||
|
const char* desc;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parameterize a set of enumerants that form an enum
|
||||||
|
class EnumDefinition : public EnumParameters {
|
||||||
|
public:
|
||||||
|
EnumDefinition() :
|
||||||
|
ceiling(0), bitmask(false), getName(0), enumParams(0), operandParams(0) { }
|
||||||
|
void set(int ceil, const char* (*name)(int), EnumParameters* ep, bool mask = false)
|
||||||
|
{
|
||||||
|
ceiling = ceil;
|
||||||
|
getName = name;
|
||||||
|
bitmask = mask;
|
||||||
|
enumParams = ep;
|
||||||
|
}
|
||||||
|
void setOperands(OperandParameters* op) { operandParams = op; }
|
||||||
|
int ceiling; // ceiling of enumerants
|
||||||
|
bool bitmask; // true if these enumerants combine into a bitmask
|
||||||
|
const char* (*getName)(int); // a function that returns the name for each enumerant value (or shift)
|
||||||
|
EnumParameters* enumParams; // parameters for each individual enumerant
|
||||||
|
OperandParameters* operandParams; // sets of operands
|
||||||
|
};
|
||||||
|
|
||||||
|
// Parameterize an instruction's logical format, including its known set of operands,
|
||||||
|
// per OperandParameters above.
|
||||||
|
class InstructionParameters {
|
||||||
|
public:
|
||||||
|
InstructionParameters() :
|
||||||
|
opDesc("TBD"),
|
||||||
|
opClass(OpClassMissing),
|
||||||
|
typePresent(true), // most normal, only exceptions have to be spelled out
|
||||||
|
resultPresent(true) // most normal, only exceptions have to be spelled out
|
||||||
|
{ }
|
||||||
|
|
||||||
|
void setResultAndType(bool r, bool t)
|
||||||
|
{
|
||||||
|
resultPresent = r;
|
||||||
|
typePresent = t;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasResult() const { return resultPresent != 0; }
|
||||||
|
bool hasType() const { return typePresent != 0; }
|
||||||
|
|
||||||
|
const char* opDesc;
|
||||||
|
OpcodeClass opClass;
|
||||||
|
OperandParameters operands;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int typePresent : 1;
|
||||||
|
int resultPresent : 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The set of objects that hold all the instruction/operand
|
||||||
|
// parameterization information.
|
||||||
|
extern InstructionParameters InstructionDesc[];
|
||||||
|
|
||||||
|
// These hold definitions of the enumerants used for operands
|
||||||
|
extern EnumDefinition OperandClassParams[];
|
||||||
|
|
||||||
|
const char* GetOperandDesc(OperandClass operand);
|
||||||
|
void PrintImmediateRow(int imm, const char* name, const EnumParameters* enumParams, bool caps, bool hex = false);
|
||||||
|
const char* AccessQualifierString(int attr);
|
||||||
|
|
||||||
|
void PrintOperands(const OperandParameters& operands, int reservedOperands);
|
||||||
|
|
||||||
|
} // end namespace spv
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Executable
+486
@@ -0,0 +1,486 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2014 LunarG, Inc.
|
||||||
|
// Copyright (C) 2015-2018 Google, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
// SPIRV-IR
|
||||||
|
//
|
||||||
|
// Simple in-memory representation (IR) of SPIRV. Just for holding
|
||||||
|
// Each function's CFG of blocks. Has this hierarchy:
|
||||||
|
// - Module, which is a list of
|
||||||
|
// - Function, which is a list of
|
||||||
|
// - Block, which is a list of
|
||||||
|
// - Instruction
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef spvIR_H
|
||||||
|
#define spvIR_H
|
||||||
|
|
||||||
|
#include "spirv.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
class Block;
|
||||||
|
class Function;
|
||||||
|
class Module;
|
||||||
|
|
||||||
|
const Id NoResult = 0;
|
||||||
|
const Id NoType = 0;
|
||||||
|
|
||||||
|
const Decoration NoPrecision = DecorationMax;
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# define POTENTIALLY_UNUSED __attribute__((unused))
|
||||||
|
#else
|
||||||
|
# define POTENTIALLY_UNUSED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
POTENTIALLY_UNUSED
|
||||||
|
const MemorySemanticsMask MemorySemanticsAllMemory =
|
||||||
|
(MemorySemanticsMask)(MemorySemanticsUniformMemoryMask |
|
||||||
|
MemorySemanticsWorkgroupMemoryMask |
|
||||||
|
MemorySemanticsAtomicCounterMemoryMask |
|
||||||
|
MemorySemanticsImageMemoryMask);
|
||||||
|
|
||||||
|
struct IdImmediate {
|
||||||
|
bool isId; // true if word is an Id, false if word is an immediate
|
||||||
|
unsigned word;
|
||||||
|
IdImmediate(bool i, unsigned w) : isId(i), word(w) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// SPIR-V IR instruction.
|
||||||
|
//
|
||||||
|
|
||||||
|
class Instruction {
|
||||||
|
public:
|
||||||
|
Instruction(Id resultId, Id typeId, Op opCode) : resultId(resultId), typeId(typeId), opCode(opCode), block(nullptr) { }
|
||||||
|
explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), block(nullptr) { }
|
||||||
|
virtual ~Instruction() {}
|
||||||
|
void addIdOperand(Id id) {
|
||||||
|
operands.push_back(id);
|
||||||
|
idOperand.push_back(true);
|
||||||
|
}
|
||||||
|
void addImmediateOperand(unsigned int immediate) {
|
||||||
|
operands.push_back(immediate);
|
||||||
|
idOperand.push_back(false);
|
||||||
|
}
|
||||||
|
void setImmediateOperand(unsigned idx, unsigned int immediate) {
|
||||||
|
assert(!idOperand[idx]);
|
||||||
|
operands[idx] = immediate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void addStringOperand(const char* str)
|
||||||
|
{
|
||||||
|
unsigned int word;
|
||||||
|
char* wordString = (char*)&word;
|
||||||
|
char* wordPtr = wordString;
|
||||||
|
int charCount = 0;
|
||||||
|
char c;
|
||||||
|
do {
|
||||||
|
c = *(str++);
|
||||||
|
*(wordPtr++) = c;
|
||||||
|
++charCount;
|
||||||
|
if (charCount == 4) {
|
||||||
|
addImmediateOperand(word);
|
||||||
|
wordPtr = wordString;
|
||||||
|
charCount = 0;
|
||||||
|
}
|
||||||
|
} while (c != 0);
|
||||||
|
|
||||||
|
// deal with partial last word
|
||||||
|
if (charCount > 0) {
|
||||||
|
// pad with 0s
|
||||||
|
for (; charCount < 4; ++charCount)
|
||||||
|
*(wordPtr++) = 0;
|
||||||
|
addImmediateOperand(word);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool isIdOperand(int op) const { return idOperand[op]; }
|
||||||
|
void setBlock(Block* b) { block = b; }
|
||||||
|
Block* getBlock() const { return block; }
|
||||||
|
Op getOpCode() const { return opCode; }
|
||||||
|
int getNumOperands() const
|
||||||
|
{
|
||||||
|
assert(operands.size() == idOperand.size());
|
||||||
|
return (int)operands.size();
|
||||||
|
}
|
||||||
|
Id getResultId() const { return resultId; }
|
||||||
|
Id getTypeId() const { return typeId; }
|
||||||
|
Id getIdOperand(int op) const {
|
||||||
|
assert(idOperand[op]);
|
||||||
|
return operands[op];
|
||||||
|
}
|
||||||
|
unsigned int getImmediateOperand(int op) const {
|
||||||
|
assert(!idOperand[op]);
|
||||||
|
return operands[op];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write out the binary form.
|
||||||
|
void dump(std::vector<unsigned int>& out) const
|
||||||
|
{
|
||||||
|
// Compute the wordCount
|
||||||
|
unsigned int wordCount = 1;
|
||||||
|
if (typeId)
|
||||||
|
++wordCount;
|
||||||
|
if (resultId)
|
||||||
|
++wordCount;
|
||||||
|
wordCount += (unsigned int)operands.size();
|
||||||
|
|
||||||
|
// Write out the beginning of the instruction
|
||||||
|
out.push_back(((wordCount) << WordCountShift) | opCode);
|
||||||
|
if (typeId)
|
||||||
|
out.push_back(typeId);
|
||||||
|
if (resultId)
|
||||||
|
out.push_back(resultId);
|
||||||
|
|
||||||
|
// Write out the operands
|
||||||
|
for (int op = 0; op < (int)operands.size(); ++op)
|
||||||
|
out.push_back(operands[op]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Instruction(const Instruction&);
|
||||||
|
Id resultId;
|
||||||
|
Id typeId;
|
||||||
|
Op opCode;
|
||||||
|
std::vector<Id> operands; // operands, both <id> and immediates (both are unsigned int)
|
||||||
|
std::vector<bool> idOperand; // true for operands that are <id>, false for immediates
|
||||||
|
Block* block;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// SPIR-V IR block.
|
||||||
|
//
|
||||||
|
|
||||||
|
class Block {
|
||||||
|
public:
|
||||||
|
Block(Id id, Function& parent);
|
||||||
|
virtual ~Block()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Id getId() { return instructions.front()->getResultId(); }
|
||||||
|
|
||||||
|
Function& getParent() const { return parent; }
|
||||||
|
void addInstruction(std::unique_ptr<Instruction> inst);
|
||||||
|
void addPredecessor(Block* pred) { predecessors.push_back(pred); pred->successors.push_back(this);}
|
||||||
|
void addLocalVariable(std::unique_ptr<Instruction> inst) { localVariables.push_back(std::move(inst)); }
|
||||||
|
const std::vector<Block*>& getPredecessors() const { return predecessors; }
|
||||||
|
const std::vector<Block*>& getSuccessors() const { return successors; }
|
||||||
|
const std::vector<std::unique_ptr<Instruction> >& getInstructions() const {
|
||||||
|
return instructions;
|
||||||
|
}
|
||||||
|
const std::vector<std::unique_ptr<Instruction> >& getLocalVariables() const { return localVariables; }
|
||||||
|
void setUnreachable() { unreachable = true; }
|
||||||
|
bool isUnreachable() const { return unreachable; }
|
||||||
|
// Returns the block's merge instruction, if one exists (otherwise null).
|
||||||
|
const Instruction* getMergeInstruction() const {
|
||||||
|
if (instructions.size() < 2) return nullptr;
|
||||||
|
const Instruction* nextToLast = (instructions.cend() - 2)->get();
|
||||||
|
switch (nextToLast->getOpCode()) {
|
||||||
|
case OpSelectionMerge:
|
||||||
|
case OpLoopMerge:
|
||||||
|
return nextToLast;
|
||||||
|
default:
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change this block into a canonical dead merge block. Delete instructions
|
||||||
|
// as necessary. A canonical dead merge block has only an OpLabel and an
|
||||||
|
// OpUnreachable.
|
||||||
|
void rewriteAsCanonicalUnreachableMerge() {
|
||||||
|
assert(localVariables.empty());
|
||||||
|
// Delete all instructions except for the label.
|
||||||
|
assert(instructions.size() > 0);
|
||||||
|
instructions.resize(1);
|
||||||
|
successors.clear();
|
||||||
|
Instruction* unreachable = new Instruction(OpUnreachable);
|
||||||
|
addInstruction(std::unique_ptr<Instruction>(unreachable));
|
||||||
|
}
|
||||||
|
// Change this block into a canonical dead continue target branching to the
|
||||||
|
// given header ID. Delete instructions as necessary. A canonical dead continue
|
||||||
|
// target has only an OpLabel and an unconditional branch back to the corresponding
|
||||||
|
// header.
|
||||||
|
void rewriteAsCanonicalUnreachableContinue(Block* header) {
|
||||||
|
assert(localVariables.empty());
|
||||||
|
// Delete all instructions except for the label.
|
||||||
|
assert(instructions.size() > 0);
|
||||||
|
instructions.resize(1);
|
||||||
|
successors.clear();
|
||||||
|
// Add OpBranch back to the header.
|
||||||
|
assert(header != nullptr);
|
||||||
|
Instruction* branch = new Instruction(OpBranch);
|
||||||
|
branch->addIdOperand(header->getId());
|
||||||
|
addInstruction(std::unique_ptr<Instruction>(branch));
|
||||||
|
successors.push_back(header);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isTerminated() const
|
||||||
|
{
|
||||||
|
switch (instructions.back()->getOpCode()) {
|
||||||
|
case OpBranch:
|
||||||
|
case OpBranchConditional:
|
||||||
|
case OpSwitch:
|
||||||
|
case OpKill:
|
||||||
|
case OpReturn:
|
||||||
|
case OpReturnValue:
|
||||||
|
case OpUnreachable:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump(std::vector<unsigned int>& out) const
|
||||||
|
{
|
||||||
|
instructions[0]->dump(out);
|
||||||
|
for (int i = 0; i < (int)localVariables.size(); ++i)
|
||||||
|
localVariables[i]->dump(out);
|
||||||
|
for (int i = 1; i < (int)instructions.size(); ++i)
|
||||||
|
instructions[i]->dump(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Block(const Block&);
|
||||||
|
Block& operator=(Block&);
|
||||||
|
|
||||||
|
// To enforce keeping parent and ownership in sync:
|
||||||
|
friend Function;
|
||||||
|
|
||||||
|
std::vector<std::unique_ptr<Instruction> > instructions;
|
||||||
|
std::vector<Block*> predecessors, successors;
|
||||||
|
std::vector<std::unique_ptr<Instruction> > localVariables;
|
||||||
|
Function& parent;
|
||||||
|
|
||||||
|
// track whether this block is known to be uncreachable (not necessarily
|
||||||
|
// true for all unreachable blocks, but should be set at least
|
||||||
|
// for the extraneous ones introduced by the builder).
|
||||||
|
bool unreachable;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The different reasons for reaching a block in the inReadableOrder traversal.
|
||||||
|
enum ReachReason {
|
||||||
|
// Reachable from the entry block via transfers of control, i.e. branches.
|
||||||
|
ReachViaControlFlow = 0,
|
||||||
|
// A continue target that is not reachable via control flow.
|
||||||
|
ReachDeadContinue,
|
||||||
|
// A merge block that is not reachable via control flow.
|
||||||
|
ReachDeadMerge
|
||||||
|
};
|
||||||
|
|
||||||
|
// Traverses the control-flow graph rooted at root in an order suited for
|
||||||
|
// readable code generation. Invokes callback at every node in the traversal
|
||||||
|
// order. The callback arguments are:
|
||||||
|
// - the block,
|
||||||
|
// - the reason we reached the block,
|
||||||
|
// - if the reason was that block is an unreachable continue or unreachable merge block
|
||||||
|
// then the last parameter is the corresponding header block.
|
||||||
|
void inReadableOrder(Block* root, std::function<void(Block*, ReachReason, Block* header)> callback);
|
||||||
|
|
||||||
|
//
|
||||||
|
// SPIR-V IR Function.
|
||||||
|
//
|
||||||
|
|
||||||
|
class Function {
|
||||||
|
public:
|
||||||
|
Function(Id id, Id resultType, Id functionType, Id firstParam, Module& parent);
|
||||||
|
virtual ~Function()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (int)parameterInstructions.size(); ++i)
|
||||||
|
delete parameterInstructions[i];
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)blocks.size(); ++i)
|
||||||
|
delete blocks[i];
|
||||||
|
}
|
||||||
|
Id getId() const { return functionInstruction.getResultId(); }
|
||||||
|
Id getParamId(int p) const { return parameterInstructions[p]->getResultId(); }
|
||||||
|
Id getParamType(int p) const { return parameterInstructions[p]->getTypeId(); }
|
||||||
|
|
||||||
|
void addBlock(Block* block) { blocks.push_back(block); }
|
||||||
|
void removeBlock(Block* block)
|
||||||
|
{
|
||||||
|
auto found = find(blocks.begin(), blocks.end(), block);
|
||||||
|
assert(found != blocks.end());
|
||||||
|
blocks.erase(found);
|
||||||
|
delete block;
|
||||||
|
}
|
||||||
|
|
||||||
|
Module& getParent() const { return parent; }
|
||||||
|
Block* getEntryBlock() const { return blocks.front(); }
|
||||||
|
Block* getLastBlock() const { return blocks.back(); }
|
||||||
|
const std::vector<Block*>& getBlocks() const { return blocks; }
|
||||||
|
void addLocalVariable(std::unique_ptr<Instruction> inst);
|
||||||
|
Id getReturnType() const { return functionInstruction.getTypeId(); }
|
||||||
|
|
||||||
|
void setImplicitThis() { implicitThis = true; }
|
||||||
|
bool hasImplicitThis() const { return implicitThis; }
|
||||||
|
|
||||||
|
void dump(std::vector<unsigned int>& out) const
|
||||||
|
{
|
||||||
|
// OpFunction
|
||||||
|
functionInstruction.dump(out);
|
||||||
|
|
||||||
|
// OpFunctionParameter
|
||||||
|
for (int p = 0; p < (int)parameterInstructions.size(); ++p)
|
||||||
|
parameterInstructions[p]->dump(out);
|
||||||
|
|
||||||
|
// Blocks
|
||||||
|
inReadableOrder(blocks[0], [&out](const Block* b, ReachReason, Block*) { b->dump(out); });
|
||||||
|
Instruction end(0, 0, OpFunctionEnd);
|
||||||
|
end.dump(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Function(const Function&);
|
||||||
|
Function& operator=(Function&);
|
||||||
|
|
||||||
|
Module& parent;
|
||||||
|
Instruction functionInstruction;
|
||||||
|
std::vector<Instruction*> parameterInstructions;
|
||||||
|
std::vector<Block*> blocks;
|
||||||
|
bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// SPIR-V IR Module.
|
||||||
|
//
|
||||||
|
|
||||||
|
class Module {
|
||||||
|
public:
|
||||||
|
Module() {}
|
||||||
|
virtual ~Module()
|
||||||
|
{
|
||||||
|
// TODO delete things
|
||||||
|
}
|
||||||
|
|
||||||
|
void addFunction(Function *fun) { functions.push_back(fun); }
|
||||||
|
|
||||||
|
void mapInstruction(Instruction *instruction)
|
||||||
|
{
|
||||||
|
spv::Id resultId = instruction->getResultId();
|
||||||
|
// map the instruction's result id
|
||||||
|
if (resultId >= idToInstruction.size())
|
||||||
|
idToInstruction.resize(resultId + 16);
|
||||||
|
idToInstruction[resultId] = instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
Instruction* getInstruction(Id id) const { return idToInstruction[id]; }
|
||||||
|
const std::vector<Function*>& getFunctions() const { return functions; }
|
||||||
|
spv::Id getTypeId(Id resultId) const {
|
||||||
|
return idToInstruction[resultId] == nullptr ? NoType : idToInstruction[resultId]->getTypeId();
|
||||||
|
}
|
||||||
|
StorageClass getStorageClass(Id typeId) const
|
||||||
|
{
|
||||||
|
assert(idToInstruction[typeId]->getOpCode() == spv::OpTypePointer);
|
||||||
|
return (StorageClass)idToInstruction[typeId]->getImmediateOperand(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump(std::vector<unsigned int>& out) const
|
||||||
|
{
|
||||||
|
for (int f = 0; f < (int)functions.size(); ++f)
|
||||||
|
functions[f]->dump(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Module(const Module&);
|
||||||
|
std::vector<Function*> functions;
|
||||||
|
|
||||||
|
// map from result id to instruction having that result id
|
||||||
|
std::vector<Instruction*> idToInstruction;
|
||||||
|
|
||||||
|
// map from a result id to its type id
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implementation (it's here due to circular type definitions).
|
||||||
|
//
|
||||||
|
|
||||||
|
// Add both
|
||||||
|
// - the OpFunction instruction
|
||||||
|
// - all the OpFunctionParameter instructions
|
||||||
|
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)
|
||||||
|
: parent(parent), functionInstruction(id, resultType, OpFunction), implicitThis(false)
|
||||||
|
{
|
||||||
|
// OpFunction
|
||||||
|
functionInstruction.addImmediateOperand(FunctionControlMaskNone);
|
||||||
|
functionInstruction.addIdOperand(functionType);
|
||||||
|
parent.mapInstruction(&functionInstruction);
|
||||||
|
parent.addFunction(this);
|
||||||
|
|
||||||
|
// OpFunctionParameter
|
||||||
|
Instruction* typeInst = parent.getInstruction(functionType);
|
||||||
|
int numParams = typeInst->getNumOperands() - 1;
|
||||||
|
for (int p = 0; p < numParams; ++p) {
|
||||||
|
Instruction* param = new Instruction(firstParamId + p, typeInst->getIdOperand(p + 1), OpFunctionParameter);
|
||||||
|
parent.mapInstruction(param);
|
||||||
|
parameterInstructions.push_back(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__inline void Function::addLocalVariable(std::unique_ptr<Instruction> inst)
|
||||||
|
{
|
||||||
|
Instruction* raw_instruction = inst.get();
|
||||||
|
blocks[0]->addLocalVariable(std::move(inst));
|
||||||
|
parent.mapInstruction(raw_instruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
__inline Block::Block(Id id, Function& parent) : parent(parent), unreachable(false)
|
||||||
|
{
|
||||||
|
instructions.push_back(std::unique_ptr<Instruction>(new Instruction(id, NoType, OpLabel)));
|
||||||
|
instructions.back()->setBlock(this);
|
||||||
|
parent.getParent().mapInstruction(instructions.back().get());
|
||||||
|
}
|
||||||
|
|
||||||
|
__inline void Block::addInstruction(std::unique_ptr<Instruction> inst)
|
||||||
|
{
|
||||||
|
Instruction* raw_instruction = inst.get();
|
||||||
|
instructions.push_back(std::move(inst));
|
||||||
|
raw_instruction->setBlock(this);
|
||||||
|
if (raw_instruction->getResultId())
|
||||||
|
parent.getParent().mapInstruction(raw_instruction);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end spv namespace
|
||||||
|
|
||||||
|
#endif // spvIR_H
|
||||||
@@ -61,11 +61,7 @@ enum TBasicType {
|
|||||||
EbtSampler,
|
EbtSampler,
|
||||||
EbtStruct,
|
EbtStruct,
|
||||||
EbtBlock,
|
EbtBlock,
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
EbtAccStructNV,
|
EbtAccStructNV,
|
||||||
#endif
|
|
||||||
|
|
||||||
EbtReference,
|
EbtReference,
|
||||||
|
|
||||||
// HLSL types that live only temporarily.
|
// HLSL types that live only temporarily.
|
||||||
@@ -94,13 +90,11 @@ enum TStorageQualifier {
|
|||||||
EvqBuffer, // read/write, shared with app
|
EvqBuffer, // read/write, shared with app
|
||||||
EvqShared, // compute shader's read/write 'shared' qualifier
|
EvqShared, // compute shader's read/write 'shared' qualifier
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
EvqPayloadNV,
|
EvqPayloadNV,
|
||||||
EvqPayloadInNV,
|
EvqPayloadInNV,
|
||||||
EvqHitAttrNV,
|
EvqHitAttrNV,
|
||||||
EvqCallableDataNV,
|
EvqCallableDataNV,
|
||||||
EvqCallableDataInNV,
|
EvqCallableDataInNV,
|
||||||
#endif
|
|
||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
|
EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter
|
||||||
@@ -221,7 +215,6 @@ enum TBuiltInVariable {
|
|||||||
EbvSampleMask,
|
EbvSampleMask,
|
||||||
EbvHelperInvocation,
|
EbvHelperInvocation,
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EbvBaryCoordNoPersp,
|
EbvBaryCoordNoPersp,
|
||||||
EbvBaryCoordNoPerspCentroid,
|
EbvBaryCoordNoPerspCentroid,
|
||||||
EbvBaryCoordNoPerspSample,
|
EbvBaryCoordNoPerspSample,
|
||||||
@@ -229,7 +222,6 @@ enum TBuiltInVariable {
|
|||||||
EbvBaryCoordSmoothCentroid,
|
EbvBaryCoordSmoothCentroid,
|
||||||
EbvBaryCoordSmoothSample,
|
EbvBaryCoordSmoothSample,
|
||||||
EbvBaryCoordPullModel,
|
EbvBaryCoordPullModel,
|
||||||
#endif
|
|
||||||
|
|
||||||
EbvViewIndex,
|
EbvViewIndex,
|
||||||
EbvDeviceIndex,
|
EbvDeviceIndex,
|
||||||
@@ -237,7 +229,6 @@ enum TBuiltInVariable {
|
|||||||
EbvFragSizeEXT,
|
EbvFragSizeEXT,
|
||||||
EbvFragInvocationCountEXT,
|
EbvFragInvocationCountEXT,
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
EbvViewportMaskNV,
|
EbvViewportMaskNV,
|
||||||
EbvSecondaryPositionNV,
|
EbvSecondaryPositionNV,
|
||||||
EbvSecondaryViewportMaskNV,
|
EbvSecondaryViewportMaskNV,
|
||||||
@@ -246,7 +237,7 @@ enum TBuiltInVariable {
|
|||||||
EbvFragFullyCoveredNV,
|
EbvFragFullyCoveredNV,
|
||||||
EbvFragmentSizeNV,
|
EbvFragmentSizeNV,
|
||||||
EbvInvocationsPerPixelNV,
|
EbvInvocationsPerPixelNV,
|
||||||
// raytracing
|
// ray tracing
|
||||||
EbvLaunchIdNV,
|
EbvLaunchIdNV,
|
||||||
EbvLaunchSizeNV,
|
EbvLaunchSizeNV,
|
||||||
EbvInstanceCustomIndexNV,
|
EbvInstanceCustomIndexNV,
|
||||||
@@ -261,8 +252,10 @@ enum TBuiltInVariable {
|
|||||||
EbvObjectToWorldNV,
|
EbvObjectToWorldNV,
|
||||||
EbvWorldToObjectNV,
|
EbvWorldToObjectNV,
|
||||||
EbvIncomingRayFlagsNV,
|
EbvIncomingRayFlagsNV,
|
||||||
|
// barycentrics
|
||||||
EbvBaryCoordNV,
|
EbvBaryCoordNV,
|
||||||
EbvBaryCoordNoPerspNV,
|
EbvBaryCoordNoPerspNV,
|
||||||
|
// mesh shaders
|
||||||
EbvTaskCountNV,
|
EbvTaskCountNV,
|
||||||
EbvPrimitiveCountNV,
|
EbvPrimitiveCountNV,
|
||||||
EbvPrimitiveIndicesNV,
|
EbvPrimitiveIndicesNV,
|
||||||
@@ -271,7 +264,12 @@ enum TBuiltInVariable {
|
|||||||
EbvLayerPerViewNV,
|
EbvLayerPerViewNV,
|
||||||
EbvMeshViewCountNV,
|
EbvMeshViewCountNV,
|
||||||
EbvMeshViewIndicesNV,
|
EbvMeshViewIndicesNV,
|
||||||
#endif
|
|
||||||
|
// sm builtins
|
||||||
|
EbvWarpsPerSM,
|
||||||
|
EbvSMCount,
|
||||||
|
EbvWarpID,
|
||||||
|
EbvSMID,
|
||||||
|
|
||||||
// HLSL built-ins that live only temporarily, until they get remapped
|
// HLSL built-ins that live only temporarily, until they get remapped
|
||||||
// to one of the above.
|
// to one of the above.
|
||||||
@@ -291,6 +289,19 @@ enum TBuiltInVariable {
|
|||||||
EbvLast
|
EbvLast
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// In this enum, order matters; users can assume higher precision is a bigger value
|
||||||
|
// and EpqNone is 0.
|
||||||
|
enum TPrecisionQualifier {
|
||||||
|
EpqNone = 0,
|
||||||
|
EpqLow,
|
||||||
|
EpqMedium,
|
||||||
|
EpqHigh
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
__inline const char* GetStorageQualifierString(TStorageQualifier q) { return ""; }
|
||||||
|
__inline const char* GetPrecisionQualifierString(TPrecisionQualifier p) { return ""; }
|
||||||
|
#else
|
||||||
// These will show up in error messages
|
// These will show up in error messages
|
||||||
__inline const char* GetStorageQualifierString(TStorageQualifier q)
|
__inline const char* GetStorageQualifierString(TStorageQualifier q)
|
||||||
{
|
{
|
||||||
@@ -317,13 +328,11 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q)
|
|||||||
case EvqPointCoord: return "gl_PointCoord"; break;
|
case EvqPointCoord: return "gl_PointCoord"; break;
|
||||||
case EvqFragColor: return "fragColor"; break;
|
case EvqFragColor: return "fragColor"; break;
|
||||||
case EvqFragDepth: return "gl_FragDepth"; break;
|
case EvqFragDepth: return "gl_FragDepth"; break;
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EvqPayloadNV: return "rayPayloadNV"; break;
|
case EvqPayloadNV: return "rayPayloadNV"; break;
|
||||||
case EvqPayloadInNV: return "rayPayloadInNV"; break;
|
case EvqPayloadInNV: return "rayPayloadInNV"; break;
|
||||||
case EvqHitAttrNV: return "hitAttributeNV"; break;
|
case EvqHitAttrNV: return "hitAttributeNV"; break;
|
||||||
case EvqCallableDataNV: return "callableDataNV"; break;
|
case EvqCallableDataNV: return "callableDataNV"; break;
|
||||||
case EvqCallableDataInNV: return "callableDataInNV"; break;
|
case EvqCallableDataInNV: return "callableDataInNV"; break;
|
||||||
#endif
|
|
||||||
default: return "unknown qualifier";
|
default: return "unknown qualifier";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -338,6 +347,8 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
|||||||
case EbvLocalInvocationId: return "LocalInvocationID";
|
case EbvLocalInvocationId: return "LocalInvocationID";
|
||||||
case EbvGlobalInvocationId: return "GlobalInvocationID";
|
case EbvGlobalInvocationId: return "GlobalInvocationID";
|
||||||
case EbvLocalInvocationIndex: return "LocalInvocationIndex";
|
case EbvLocalInvocationIndex: return "LocalInvocationIndex";
|
||||||
|
case EbvNumSubgroups: return "NumSubgroups";
|
||||||
|
case EbvSubgroupID: return "SubgroupID";
|
||||||
case EbvSubGroupSize: return "SubGroupSize";
|
case EbvSubGroupSize: return "SubGroupSize";
|
||||||
case EbvSubGroupInvocation: return "SubGroupInvocation";
|
case EbvSubGroupInvocation: return "SubGroupInvocation";
|
||||||
case EbvSubGroupEqMask: return "SubGroupEqMask";
|
case EbvSubGroupEqMask: return "SubGroupEqMask";
|
||||||
@@ -345,6 +356,13 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
|||||||
case EbvSubGroupGtMask: return "SubGroupGtMask";
|
case EbvSubGroupGtMask: return "SubGroupGtMask";
|
||||||
case EbvSubGroupLeMask: return "SubGroupLeMask";
|
case EbvSubGroupLeMask: return "SubGroupLeMask";
|
||||||
case EbvSubGroupLtMask: return "SubGroupLtMask";
|
case EbvSubGroupLtMask: return "SubGroupLtMask";
|
||||||
|
case EbvSubgroupSize2: return "SubgroupSize";
|
||||||
|
case EbvSubgroupInvocation2: return "SubgroupInvocationID";
|
||||||
|
case EbvSubgroupEqMask2: return "SubgroupEqMask";
|
||||||
|
case EbvSubgroupGeMask2: return "SubgroupGeMask";
|
||||||
|
case EbvSubgroupGtMask2: return "SubgroupGtMask";
|
||||||
|
case EbvSubgroupLeMask2: return "SubgroupLeMask";
|
||||||
|
case EbvSubgroupLtMask2: return "SubgroupLtMask";
|
||||||
case EbvVertexId: return "VertexId";
|
case EbvVertexId: return "VertexId";
|
||||||
case EbvInstanceId: return "InstanceId";
|
case EbvInstanceId: return "InstanceId";
|
||||||
case EbvVertexIndex: return "VertexIndex";
|
case EbvVertexIndex: return "VertexIndex";
|
||||||
@@ -396,7 +414,6 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
|||||||
case EbvSampleMask: return "SampleMaskIn";
|
case EbvSampleMask: return "SampleMaskIn";
|
||||||
case EbvHelperInvocation: return "HelperInvocation";
|
case EbvHelperInvocation: return "HelperInvocation";
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbvBaryCoordNoPersp: return "BaryCoordNoPersp";
|
case EbvBaryCoordNoPersp: return "BaryCoordNoPersp";
|
||||||
case EbvBaryCoordNoPerspCentroid: return "BaryCoordNoPerspCentroid";
|
case EbvBaryCoordNoPerspCentroid: return "BaryCoordNoPerspCentroid";
|
||||||
case EbvBaryCoordNoPerspSample: return "BaryCoordNoPerspSample";
|
case EbvBaryCoordNoPerspSample: return "BaryCoordNoPerspSample";
|
||||||
@@ -404,7 +421,6 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
|||||||
case EbvBaryCoordSmoothCentroid: return "BaryCoordSmoothCentroid";
|
case EbvBaryCoordSmoothCentroid: return "BaryCoordSmoothCentroid";
|
||||||
case EbvBaryCoordSmoothSample: return "BaryCoordSmoothSample";
|
case EbvBaryCoordSmoothSample: return "BaryCoordSmoothSample";
|
||||||
case EbvBaryCoordPullModel: return "BaryCoordPullModel";
|
case EbvBaryCoordPullModel: return "BaryCoordPullModel";
|
||||||
#endif
|
|
||||||
|
|
||||||
case EbvViewIndex: return "ViewIndex";
|
case EbvViewIndex: return "ViewIndex";
|
||||||
case EbvDeviceIndex: return "DeviceIndex";
|
case EbvDeviceIndex: return "DeviceIndex";
|
||||||
@@ -412,7 +428,6 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
|||||||
case EbvFragSizeEXT: return "FragSizeEXT";
|
case EbvFragSizeEXT: return "FragSizeEXT";
|
||||||
case EbvFragInvocationCountEXT: return "FragInvocationCountEXT";
|
case EbvFragInvocationCountEXT: return "FragInvocationCountEXT";
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EbvViewportMaskNV: return "ViewportMaskNV";
|
case EbvViewportMaskNV: return "ViewportMaskNV";
|
||||||
case EbvSecondaryPositionNV: return "SecondaryPositionNV";
|
case EbvSecondaryPositionNV: return "SecondaryPositionNV";
|
||||||
case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
case EbvSecondaryViewportMaskNV: return "SecondaryViewportMaskNV";
|
||||||
@@ -438,6 +453,7 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
|||||||
|
|
||||||
case EbvBaryCoordNV: return "BaryCoordNV";
|
case EbvBaryCoordNV: return "BaryCoordNV";
|
||||||
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV";
|
||||||
|
|
||||||
case EbvTaskCountNV: return "TaskCountNV";
|
case EbvTaskCountNV: return "TaskCountNV";
|
||||||
case EbvPrimitiveCountNV: return "PrimitiveCountNV";
|
case EbvPrimitiveCountNV: return "PrimitiveCountNV";
|
||||||
case EbvPrimitiveIndicesNV: return "PrimitiveIndicesNV";
|
case EbvPrimitiveIndicesNV: return "PrimitiveIndicesNV";
|
||||||
@@ -446,20 +462,16 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v)
|
|||||||
case EbvLayerPerViewNV: return "LayerPerViewNV";
|
case EbvLayerPerViewNV: return "LayerPerViewNV";
|
||||||
case EbvMeshViewCountNV: return "MeshViewCountNV";
|
case EbvMeshViewCountNV: return "MeshViewCountNV";
|
||||||
case EbvMeshViewIndicesNV: return "MeshViewIndicesNV";
|
case EbvMeshViewIndicesNV: return "MeshViewIndicesNV";
|
||||||
#endif
|
|
||||||
|
case EbvWarpsPerSM: return "WarpsPerSMNV";
|
||||||
|
case EbvSMCount: return "SMCountNV";
|
||||||
|
case EbvWarpID: return "WarpIDNV";
|
||||||
|
case EbvSMID: return "SMIDNV";
|
||||||
|
|
||||||
default: return "unknown built-in variable";
|
default: return "unknown built-in variable";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In this enum, order matters; users can assume higher precision is a bigger value
|
|
||||||
// and EpqNone is 0.
|
|
||||||
enum TPrecisionQualifier {
|
|
||||||
EpqNone = 0,
|
|
||||||
EpqLow,
|
|
||||||
EpqMedium,
|
|
||||||
EpqHigh
|
|
||||||
};
|
|
||||||
|
|
||||||
__inline const char* GetPrecisionQualifierString(TPrecisionQualifier p)
|
__inline const char* GetPrecisionQualifierString(TPrecisionQualifier p)
|
||||||
{
|
{
|
||||||
switch (p) {
|
switch (p) {
|
||||||
@@ -470,6 +482,7 @@ __inline const char* GetPrecisionQualifierString(TPrecisionQualifier p)
|
|||||||
default: return "unknown precision qualifier";
|
default: return "unknown precision qualifier";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
__inline bool isTypeSignedInt(TBasicType type)
|
__inline bool isTypeSignedInt(TBasicType type)
|
||||||
{
|
{
|
||||||
@@ -514,7 +527,8 @@ __inline bool isTypeFloat(TBasicType type)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__inline int getTypeRank(TBasicType type) {
|
__inline int getTypeRank(TBasicType type)
|
||||||
|
{
|
||||||
int res = -1;
|
int res = -1;
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
|
|||||||
@@ -213,6 +213,28 @@ public:
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt:
|
||||||
|
if (constant.iConst == iConst)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EbtUint:
|
||||||
|
if (constant.uConst == uConst)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EbtBool:
|
||||||
|
if (constant.bConst == bConst)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case EbtDouble:
|
||||||
|
if (constant.dConst == dConst)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
if (constant.i16Const == i16Const)
|
if (constant.i16Const == i16Const)
|
||||||
return true;
|
return true;
|
||||||
@@ -232,16 +254,6 @@ public:
|
|||||||
if (constant.u8Const == u8Const)
|
if (constant.u8Const == u8Const)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
break;
|
|
||||||
case EbtInt:
|
|
||||||
if (constant.iConst == iConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case EbtUint:
|
|
||||||
if (constant.uConst == uConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
if (constant.i64Const == i64Const)
|
if (constant.i64Const == i64Const)
|
||||||
@@ -253,16 +265,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case EbtDouble:
|
#endif
|
||||||
if (constant.dConst == dConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case EbtBool:
|
|
||||||
if (constant.bConst == bConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
assert(false && "Default missing");
|
assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
@@ -329,6 +332,22 @@ public:
|
|||||||
{
|
{
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt:
|
||||||
|
if (iConst > constant.iConst)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
case EbtUint:
|
||||||
|
if (uConst > constant.uConst)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
case EbtDouble:
|
||||||
|
if (dConst > constant.dConst)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
if (i8Const > constant.i8Const)
|
if (i8Const > constant.i8Const)
|
||||||
return true;
|
return true;
|
||||||
@@ -348,16 +367,6 @@ public:
|
|||||||
if (u16Const > constant.u16Const)
|
if (u16Const > constant.u16Const)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
|
||||||
case EbtInt:
|
|
||||||
if (iConst > constant.iConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
case EbtUint:
|
|
||||||
if (uConst > constant.uConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
if (i64Const > constant.i64Const)
|
if (i64Const > constant.i64Const)
|
||||||
@@ -369,11 +378,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
case EbtDouble:
|
#endif
|
||||||
if (dConst > constant.dConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
default:
|
default:
|
||||||
assert(false && "Default missing");
|
assert(false && "Default missing");
|
||||||
return false;
|
return false;
|
||||||
@@ -384,6 +389,7 @@ public:
|
|||||||
{
|
{
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
if (i8Const < constant.i8Const)
|
if (i8Const < constant.i8Const)
|
||||||
return true;
|
return true;
|
||||||
@@ -402,17 +408,6 @@ public:
|
|||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
if (u16Const < constant.u16Const)
|
if (u16Const < constant.u16Const)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
|
||||||
case EbtInt:
|
|
||||||
if (iConst < constant.iConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
case EbtUint:
|
|
||||||
if (uConst < constant.uConst)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
if (i64Const < constant.i64Const)
|
if (i64Const < constant.i64Const)
|
||||||
@@ -424,10 +419,21 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
#endif
|
||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
if (dConst < constant.dConst)
|
if (dConst < constant.dConst)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
case EbtInt:
|
||||||
|
if (iConst < constant.iConst)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
case EbtUint:
|
||||||
|
if (uConst < constant.uConst)
|
||||||
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
default:
|
default:
|
||||||
assert(false && "Default missing");
|
assert(false && "Default missing");
|
||||||
@@ -440,15 +446,17 @@ public:
|
|||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setUConst(uConst + constant.uConst); break;
|
||||||
|
case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8: returnValue.setI8Const(i8Const + constant.i8Const); break;
|
case EbtInt8: returnValue.setI8Const(i8Const + constant.i8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(i16Const + constant.i16Const); break;
|
case EbtInt16: returnValue.setI16Const(i16Const + constant.i16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst + constant.iConst); break;
|
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const + constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const + constant.u8Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const + constant.u16Const); break;
|
case EbtUint16: returnValue.setU16Const(u16Const + constant.u16Const); break;
|
||||||
case EbtUint: returnValue.setUConst(uConst + constant.uConst); break;
|
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break;
|
||||||
case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break;
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,15 +468,17 @@ public:
|
|||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setUConst(uConst - constant.uConst); break;
|
||||||
|
case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8: returnValue.setI8Const(i8Const - constant.i8Const); break;
|
case EbtInt8: returnValue.setI8Const(i8Const - constant.i8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(i16Const - constant.i16Const); break;
|
case EbtInt16: returnValue.setI16Const(i16Const - constant.i16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst - constant.iConst); break;
|
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const - constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const - constant.u8Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const - constant.u16Const); break;
|
case EbtUint16: returnValue.setU16Const(u16Const - constant.u16Const); break;
|
||||||
case EbtUint: returnValue.setUConst(uConst - constant.uConst); break;
|
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break;
|
||||||
case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break;
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,15 +490,17 @@ public:
|
|||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setUConst(uConst * constant.uConst); break;
|
||||||
|
case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8: returnValue.setI8Const(i8Const * constant.i8Const); break;
|
case EbtInt8: returnValue.setI8Const(i8Const * constant.i8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(i16Const * constant.i16Const); break;
|
case EbtInt16: returnValue.setI16Const(i16Const * constant.i16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst * constant.iConst); break;
|
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const * constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const * constant.u8Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const * constant.u16Const); break;
|
case EbtUint16: returnValue.setU16Const(u16Const * constant.u16Const); break;
|
||||||
case EbtUint: returnValue.setUConst(uConst * constant.uConst); break;
|
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break;
|
||||||
case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break;
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,14 +512,16 @@ public:
|
|||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setUConst(uConst % constant.uConst); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8: returnValue.setI8Const(i8Const % constant.i8Const); break;
|
case EbtInt8: returnValue.setI8Const(i8Const % constant.i8Const); break;
|
||||||
case EbtInt16: returnValue.setI8Const(i8Const % constant.i16Const); break;
|
case EbtInt16: returnValue.setI8Const(i8Const % constant.i16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst % constant.iConst); break;
|
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const % constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const % constant.u8Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const % constant.u16Const); break;
|
case EbtUint16: returnValue.setU16Const(u16Const % constant.u16Const); break;
|
||||||
case EbtUint: returnValue.setUConst(uConst % constant.uConst); break;
|
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,6 +532,7 @@ public:
|
|||||||
{
|
{
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
case EbtInt8: returnValue.setI8Const(i8Const >> constant.i8Const); break;
|
case EbtInt8: returnValue.setI8Const(i8Const >> constant.i8Const); break;
|
||||||
@@ -570,32 +585,38 @@ public:
|
|||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8: returnValue.setIConst(iConst >> constant.i8Const); break;
|
case EbtInt8: returnValue.setIConst(iConst >> constant.i8Const); break;
|
||||||
case EbtUint8: returnValue.setIConst(iConst >> constant.u8Const); break;
|
case EbtUint8: returnValue.setIConst(iConst >> constant.u8Const); break;
|
||||||
case EbtInt16: returnValue.setIConst(iConst >> constant.i16Const); break;
|
case EbtInt16: returnValue.setIConst(iConst >> constant.i16Const); break;
|
||||||
case EbtUint16: returnValue.setIConst(iConst >> constant.u16Const); break;
|
case EbtUint16: returnValue.setIConst(iConst >> constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst >> constant.iConst); break;
|
|
||||||
case EbtUint: returnValue.setIConst(iConst >> constant.uConst); break;
|
|
||||||
case EbtInt64: returnValue.setIConst(iConst >> constant.i64Const); break;
|
case EbtInt64: returnValue.setIConst(iConst >> constant.i64Const); break;
|
||||||
case EbtUint64: returnValue.setIConst(iConst >> constant.u64Const); break;
|
case EbtUint64: returnValue.setIConst(iConst >> constant.u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EbtUint:
|
case EbtUint:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
|
case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8: returnValue.setUConst(uConst >> constant.i8Const); break;
|
case EbtInt8: returnValue.setUConst(uConst >> constant.i8Const); break;
|
||||||
case EbtUint8: returnValue.setUConst(uConst >> constant.u8Const); break;
|
case EbtUint8: returnValue.setUConst(uConst >> constant.u8Const); break;
|
||||||
case EbtInt16: returnValue.setUConst(uConst >> constant.i16Const); break;
|
case EbtInt16: returnValue.setUConst(uConst >> constant.i16Const); break;
|
||||||
case EbtUint16: returnValue.setUConst(uConst >> constant.u16Const); break;
|
case EbtUint16: returnValue.setUConst(uConst >> constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setUConst(uConst >> constant.iConst); break;
|
|
||||||
case EbtUint: returnValue.setUConst(uConst >> constant.uConst); break;
|
|
||||||
case EbtInt64: returnValue.setUConst(uConst >> constant.i64Const); break;
|
case EbtInt64: returnValue.setUConst(uConst >> constant.i64Const); break;
|
||||||
case EbtUint64: returnValue.setUConst(uConst >> constant.u64Const); break;
|
case EbtUint64: returnValue.setUConst(uConst >> constant.u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
case EbtInt8: returnValue.setI64Const(i64Const >> constant.i8Const); break;
|
case EbtInt8: returnValue.setI64Const(i64Const >> constant.i8Const); break;
|
||||||
@@ -622,6 +643,7 @@ public:
|
|||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -632,6 +654,7 @@ public:
|
|||||||
{
|
{
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
case EbtInt8: returnValue.setI8Const(i8Const << constant.i8Const); break;
|
case EbtInt8: returnValue.setI8Const(i8Const << constant.i8Const); break;
|
||||||
@@ -684,32 +707,6 @@ public:
|
|||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EbtInt:
|
|
||||||
switch (constant.type) {
|
|
||||||
case EbtInt8: returnValue.setIConst(iConst << constant.i8Const); break;
|
|
||||||
case EbtUint8: returnValue.setIConst(iConst << constant.u8Const); break;
|
|
||||||
case EbtInt16: returnValue.setIConst(iConst << constant.i16Const); break;
|
|
||||||
case EbtUint16: returnValue.setIConst(iConst << constant.u16Const); break;
|
|
||||||
case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
|
|
||||||
case EbtUint: returnValue.setIConst(iConst << constant.uConst); break;
|
|
||||||
case EbtInt64: returnValue.setIConst(iConst << constant.i64Const); break;
|
|
||||||
case EbtUint64: returnValue.setIConst(iConst << constant.u64Const); break;
|
|
||||||
default: assert(false && "Default missing");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EbtUint:
|
|
||||||
switch (constant.type) {
|
|
||||||
case EbtInt8: returnValue.setUConst(uConst << constant.i8Const); break;
|
|
||||||
case EbtUint8: returnValue.setUConst(uConst << constant.u8Const); break;
|
|
||||||
case EbtInt16: returnValue.setUConst(uConst << constant.i16Const); break;
|
|
||||||
case EbtUint16: returnValue.setUConst(uConst << constant.u16Const); break;
|
|
||||||
case EbtInt: returnValue.setUConst(uConst << constant.iConst); break;
|
|
||||||
case EbtUint: returnValue.setUConst(uConst << constant.uConst); break;
|
|
||||||
case EbtInt64: returnValue.setUConst(uConst << constant.i64Const); break;
|
|
||||||
case EbtUint64: returnValue.setUConst(uConst << constant.u64Const); break;
|
|
||||||
default: assert(false && "Default missing");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
switch (constant.type) {
|
switch (constant.type) {
|
||||||
case EbtInt8: returnValue.setI64Const(i64Const << constant.i8Const); break;
|
case EbtInt8: returnValue.setI64Const(i64Const << constant.i8Const); break;
|
||||||
@@ -736,6 +733,37 @@ public:
|
|||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
case EbtInt:
|
||||||
|
switch (constant.type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst << constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setIConst(iConst << constant.uConst); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
case EbtInt8: returnValue.setIConst(iConst << constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setIConst(iConst << constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setIConst(iConst << constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setIConst(iConst << constant.u16Const); break;
|
||||||
|
case EbtInt64: returnValue.setIConst(iConst << constant.i64Const); break;
|
||||||
|
case EbtUint64: returnValue.setIConst(iConst << constant.u64Const); break;
|
||||||
|
#endif
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EbtUint:
|
||||||
|
switch (constant.type) {
|
||||||
|
case EbtInt: returnValue.setUConst(uConst << constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setUConst(uConst << constant.uConst); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
case EbtInt8: returnValue.setUConst(uConst << constant.i8Const); break;
|
||||||
|
case EbtUint8: returnValue.setUConst(uConst << constant.u8Const); break;
|
||||||
|
case EbtInt16: returnValue.setUConst(uConst << constant.i16Const); break;
|
||||||
|
case EbtUint16: returnValue.setUConst(uConst << constant.u16Const); break;
|
||||||
|
case EbtInt64: returnValue.setUConst(uConst << constant.i64Const); break;
|
||||||
|
case EbtUint64: returnValue.setUConst(uConst << constant.u64Const); break;
|
||||||
|
#endif
|
||||||
|
default: assert(false && "Default missing");
|
||||||
|
}
|
||||||
|
break;
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -747,14 +775,16 @@ public:
|
|||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst & constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setUConst(uConst & constant.uConst); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8: returnValue.setI8Const(i8Const & constant.i8Const); break;
|
case EbtInt8: returnValue.setI8Const(i8Const & constant.i8Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const & constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const & constant.u8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(i16Const & constant.i16Const); break;
|
case EbtInt16: returnValue.setI16Const(i16Const & constant.i16Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const & constant.u16Const); break;
|
case EbtUint16: returnValue.setU16Const(u16Const & constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst & constant.iConst); break;
|
|
||||||
case EbtUint: returnValue.setUConst(uConst & constant.uConst); break;
|
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break;
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const & constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const & constant.u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -766,14 +796,16 @@ public:
|
|||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst | constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setUConst(uConst | constant.uConst); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8: returnValue.setI8Const(i8Const | constant.i8Const); break;
|
case EbtInt8: returnValue.setI8Const(i8Const | constant.i8Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const | constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const | constant.u8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(i16Const | constant.i16Const); break;
|
case EbtInt16: returnValue.setI16Const(i16Const | constant.i16Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const | constant.u16Const); break;
|
case EbtUint16: returnValue.setU16Const(u16Const | constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst | constant.iConst); break;
|
|
||||||
case EbtUint: returnValue.setUConst(uConst | constant.uConst); break;
|
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break;
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const | constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const | constant.u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,14 +817,16 @@ public:
|
|||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
assert(type == constant.type);
|
assert(type == constant.type);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break;
|
||||||
|
case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8: returnValue.setI8Const(i8Const ^ constant.i8Const); break;
|
case EbtInt8: returnValue.setI8Const(i8Const ^ constant.i8Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(u8Const ^ constant.u8Const); break;
|
case EbtUint8: returnValue.setU8Const(u8Const ^ constant.u8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(i16Const ^ constant.i16Const); break;
|
case EbtInt16: returnValue.setI16Const(i16Const ^ constant.i16Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(u16Const ^ constant.u16Const); break;
|
case EbtUint16: returnValue.setU16Const(u16Const ^ constant.u16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(iConst ^ constant.iConst); break;
|
|
||||||
case EbtUint: returnValue.setUConst(uConst ^ constant.uConst); break;
|
|
||||||
case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break;
|
case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break;
|
||||||
case EbtUint64: returnValue.setU64Const(u64Const ^ constant.u64Const); break;
|
case EbtUint64: returnValue.setU64Const(u64Const ^ constant.u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,14 +837,16 @@ public:
|
|||||||
{
|
{
|
||||||
TConstUnion returnValue;
|
TConstUnion returnValue;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
case EbtInt: returnValue.setIConst(~iConst); break;
|
||||||
|
case EbtUint: returnValue.setUConst(~uConst); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8: returnValue.setI8Const(~i8Const); break;
|
case EbtInt8: returnValue.setI8Const(~i8Const); break;
|
||||||
case EbtUint8: returnValue.setU8Const(~u8Const); break;
|
case EbtUint8: returnValue.setU8Const(~u8Const); break;
|
||||||
case EbtInt16: returnValue.setI16Const(~i16Const); break;
|
case EbtInt16: returnValue.setI16Const(~i16Const); break;
|
||||||
case EbtUint16: returnValue.setU16Const(~u16Const); break;
|
case EbtUint16: returnValue.setU16Const(~u16Const); break;
|
||||||
case EbtInt: returnValue.setIConst(~iConst); break;
|
|
||||||
case EbtUint: returnValue.setUConst(~uConst); break;
|
|
||||||
case EbtInt64: returnValue.setI64Const(~i64Const); break;
|
case EbtInt64: returnValue.setI64Const(~i64Const); break;
|
||||||
case EbtUint64: returnValue.setU64Const(~u64Const); break;
|
case EbtUint64: returnValue.setU64Const(~u64Const); break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -304,7 +304,6 @@ public:
|
|||||||
size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); }
|
size_type max_size() const { return static_cast<size_type>(-1) / sizeof(T); }
|
||||||
size_type max_size(int size) const { return static_cast<size_type>(-1) / size; }
|
size_type max_size(int size) const { return static_cast<size_type>(-1) / size; }
|
||||||
|
|
||||||
void setAllocator(TPoolAllocator* a) { allocator = *a; }
|
|
||||||
TPoolAllocator& getAllocator() const { return allocator; }
|
TPoolAllocator& getAllocator() const { return allocator; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -275,6 +275,10 @@ enum TOperator {
|
|||||||
EOpConvUint64ToPtr,
|
EOpConvUint64ToPtr,
|
||||||
EOpConvPtrToUint64,
|
EOpConvPtrToUint64,
|
||||||
|
|
||||||
|
// uvec2 <-> pointer
|
||||||
|
EOpConvUvec2ToPtr,
|
||||||
|
EOpConvPtrToUvec2,
|
||||||
|
|
||||||
//
|
//
|
||||||
// binary operations
|
// binary operations
|
||||||
//
|
//
|
||||||
@@ -422,11 +426,9 @@ enum TOperator {
|
|||||||
EOpReflect,
|
EOpReflect,
|
||||||
EOpRefract,
|
EOpRefract,
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpMin3,
|
EOpMin3,
|
||||||
EOpMax3,
|
EOpMax3,
|
||||||
EOpMid3,
|
EOpMid3,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpDPdx, // Fragment only
|
EOpDPdx, // Fragment only
|
||||||
EOpDPdy, // Fragment only
|
EOpDPdy, // Fragment only
|
||||||
@@ -441,10 +443,7 @@ enum TOperator {
|
|||||||
EOpInterpolateAtCentroid, // Fragment only
|
EOpInterpolateAtCentroid, // Fragment only
|
||||||
EOpInterpolateAtSample, // Fragment only
|
EOpInterpolateAtSample, // Fragment only
|
||||||
EOpInterpolateAtOffset, // Fragment only
|
EOpInterpolateAtOffset, // Fragment only
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpInterpolateAtVertex,
|
EOpInterpolateAtVertex,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpMatrixTimesMatrix,
|
EOpMatrixTimesMatrix,
|
||||||
EOpOuterProduct,
|
EOpOuterProduct,
|
||||||
@@ -534,7 +533,6 @@ enum TOperator {
|
|||||||
EOpSubgroupQuadSwapVertical,
|
EOpSubgroupQuadSwapVertical,
|
||||||
EOpSubgroupQuadSwapDiagonal,
|
EOpSubgroupQuadSwapDiagonal,
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
EOpSubgroupPartition,
|
EOpSubgroupPartition,
|
||||||
EOpSubgroupPartitionedAdd,
|
EOpSubgroupPartitionedAdd,
|
||||||
EOpSubgroupPartitionedMul,
|
EOpSubgroupPartitionedMul,
|
||||||
@@ -557,11 +555,9 @@ enum TOperator {
|
|||||||
EOpSubgroupPartitionedExclusiveAnd,
|
EOpSubgroupPartitionedExclusiveAnd,
|
||||||
EOpSubgroupPartitionedExclusiveOr,
|
EOpSubgroupPartitionedExclusiveOr,
|
||||||
EOpSubgroupPartitionedExclusiveXor,
|
EOpSubgroupPartitionedExclusiveXor,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpSubgroupGuardStop,
|
EOpSubgroupGuardStop,
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpMinInvocations,
|
EOpMinInvocations,
|
||||||
EOpMaxInvocations,
|
EOpMaxInvocations,
|
||||||
EOpAddInvocations,
|
EOpAddInvocations,
|
||||||
@@ -588,7 +584,6 @@ enum TOperator {
|
|||||||
EOpCubeFaceIndex,
|
EOpCubeFaceIndex,
|
||||||
EOpCubeFaceCoord,
|
EOpCubeFaceCoord,
|
||||||
EOpTime,
|
EOpTime,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpAtomicAdd,
|
EOpAtomicAdd,
|
||||||
EOpAtomicMin,
|
EOpAtomicMin,
|
||||||
@@ -621,6 +616,11 @@ enum TOperator {
|
|||||||
EOpCooperativeMatrixStore,
|
EOpCooperativeMatrixStore,
|
||||||
EOpCooperativeMatrixMulAdd,
|
EOpCooperativeMatrixMulAdd,
|
||||||
|
|
||||||
|
EOpBeginInvocationInterlock, // Fragment only
|
||||||
|
EOpEndInvocationInterlock, // Fragment only
|
||||||
|
|
||||||
|
EOpIsHelperInvocation,
|
||||||
|
|
||||||
//
|
//
|
||||||
// Branch
|
// Branch
|
||||||
//
|
//
|
||||||
@@ -631,6 +631,7 @@ enum TOperator {
|
|||||||
EOpContinue,
|
EOpContinue,
|
||||||
EOpCase,
|
EOpCase,
|
||||||
EOpDefault,
|
EOpDefault,
|
||||||
|
EOpDemote, // Fragment only
|
||||||
|
|
||||||
//
|
//
|
||||||
// Constructors
|
// Constructors
|
||||||
@@ -648,9 +649,21 @@ enum TOperator {
|
|||||||
EOpConstructBool,
|
EOpConstructBool,
|
||||||
EOpConstructFloat,
|
EOpConstructFloat,
|
||||||
EOpConstructDouble,
|
EOpConstructDouble,
|
||||||
|
// Keep vector and matrix constructors in a consistent relative order for
|
||||||
|
// TParseContext::constructBuiltIn, which converts between 8/16/32 bit
|
||||||
|
// vector constructors
|
||||||
EOpConstructVec2,
|
EOpConstructVec2,
|
||||||
EOpConstructVec3,
|
EOpConstructVec3,
|
||||||
EOpConstructVec4,
|
EOpConstructVec4,
|
||||||
|
EOpConstructMat2x2,
|
||||||
|
EOpConstructMat2x3,
|
||||||
|
EOpConstructMat2x4,
|
||||||
|
EOpConstructMat3x2,
|
||||||
|
EOpConstructMat3x3,
|
||||||
|
EOpConstructMat3x4,
|
||||||
|
EOpConstructMat4x2,
|
||||||
|
EOpConstructMat4x3,
|
||||||
|
EOpConstructMat4x4,
|
||||||
EOpConstructDVec2,
|
EOpConstructDVec2,
|
||||||
EOpConstructDVec3,
|
EOpConstructDVec3,
|
||||||
EOpConstructDVec4,
|
EOpConstructDVec4,
|
||||||
@@ -681,15 +694,6 @@ enum TOperator {
|
|||||||
EOpConstructU64Vec2,
|
EOpConstructU64Vec2,
|
||||||
EOpConstructU64Vec3,
|
EOpConstructU64Vec3,
|
||||||
EOpConstructU64Vec4,
|
EOpConstructU64Vec4,
|
||||||
EOpConstructMat2x2,
|
|
||||||
EOpConstructMat2x3,
|
|
||||||
EOpConstructMat2x4,
|
|
||||||
EOpConstructMat3x2,
|
|
||||||
EOpConstructMat3x3,
|
|
||||||
EOpConstructMat3x4,
|
|
||||||
EOpConstructMat4x2,
|
|
||||||
EOpConstructMat4x3,
|
|
||||||
EOpConstructMat4x4,
|
|
||||||
EOpConstructDMat2x2,
|
EOpConstructDMat2x2,
|
||||||
EOpConstructDMat2x3,
|
EOpConstructDMat2x3,
|
||||||
EOpConstructDMat2x4,
|
EOpConstructDMat2x4,
|
||||||
@@ -786,10 +790,8 @@ enum TOperator {
|
|||||||
EOpImageQuerySamples,
|
EOpImageQuerySamples,
|
||||||
EOpImageLoad,
|
EOpImageLoad,
|
||||||
EOpImageStore,
|
EOpImageStore,
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpImageLoadLod,
|
EOpImageLoadLod,
|
||||||
EOpImageStoreLod,
|
EOpImageStoreLod,
|
||||||
#endif
|
|
||||||
EOpImageAtomicAdd,
|
EOpImageAtomicAdd,
|
||||||
EOpImageAtomicMin,
|
EOpImageAtomicMin,
|
||||||
EOpImageAtomicMax,
|
EOpImageAtomicMax,
|
||||||
@@ -804,9 +806,7 @@ enum TOperator {
|
|||||||
EOpSubpassLoad,
|
EOpSubpassLoad,
|
||||||
EOpSubpassLoadMS,
|
EOpSubpassLoadMS,
|
||||||
EOpSparseImageLoad,
|
EOpSparseImageLoad,
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpSparseImageLoadLod,
|
EOpSparseImageLoadLod,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpImageGuardEnd,
|
EOpImageGuardEnd,
|
||||||
|
|
||||||
@@ -844,13 +844,11 @@ enum TOperator {
|
|||||||
EOpTextureOffsetClamp,
|
EOpTextureOffsetClamp,
|
||||||
EOpTextureGradClamp,
|
EOpTextureGradClamp,
|
||||||
EOpTextureGradOffsetClamp,
|
EOpTextureGradOffsetClamp,
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpTextureGatherLod,
|
EOpTextureGatherLod,
|
||||||
EOpTextureGatherLodOffset,
|
EOpTextureGatherLodOffset,
|
||||||
EOpTextureGatherLodOffsets,
|
EOpTextureGatherLodOffsets,
|
||||||
EOpFragmentMaskFetch,
|
EOpFragmentMaskFetch,
|
||||||
EOpFragmentFetch,
|
EOpFragmentFetch,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpSparseTextureGuardBegin,
|
EOpSparseTextureGuardBegin,
|
||||||
|
|
||||||
@@ -870,15 +868,12 @@ enum TOperator {
|
|||||||
EOpSparseTextureOffsetClamp,
|
EOpSparseTextureOffsetClamp,
|
||||||
EOpSparseTextureGradClamp,
|
EOpSparseTextureGradClamp,
|
||||||
EOpSparseTextureGradOffsetClamp,
|
EOpSparseTextureGradOffsetClamp,
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
EOpSparseTextureGatherLod,
|
EOpSparseTextureGatherLod,
|
||||||
EOpSparseTextureGatherLodOffset,
|
EOpSparseTextureGatherLodOffset,
|
||||||
EOpSparseTextureGatherLodOffsets,
|
EOpSparseTextureGatherLodOffsets,
|
||||||
#endif
|
|
||||||
|
|
||||||
EOpSparseTextureGuardEnd,
|
EOpSparseTextureGuardEnd,
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
EOpImageFootprintGuardBegin,
|
EOpImageFootprintGuardBegin,
|
||||||
EOpImageSampleFootprintNV,
|
EOpImageSampleFootprintNV,
|
||||||
EOpImageSampleFootprintClampNV,
|
EOpImageSampleFootprintClampNV,
|
||||||
@@ -886,7 +881,6 @@ enum TOperator {
|
|||||||
EOpImageSampleFootprintGradNV,
|
EOpImageSampleFootprintGradNV,
|
||||||
EOpImageSampleFootprintGradClampNV,
|
EOpImageSampleFootprintGradClampNV,
|
||||||
EOpImageFootprintGuardEnd,
|
EOpImageFootprintGuardEnd,
|
||||||
#endif
|
|
||||||
EOpSamplingGuardEnd,
|
EOpSamplingGuardEnd,
|
||||||
EOpTextureGuardEnd,
|
EOpTextureGuardEnd,
|
||||||
|
|
||||||
@@ -905,14 +899,21 @@ enum TOperator {
|
|||||||
EOpFindLSB,
|
EOpFindLSB,
|
||||||
EOpFindMSB,
|
EOpFindMSB,
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
EOpCountLeadingZeros,
|
||||||
|
EOpCountTrailingZeros,
|
||||||
|
EOpAbsDifference,
|
||||||
|
EOpAddSaturate,
|
||||||
|
EOpSubSaturate,
|
||||||
|
EOpAverage,
|
||||||
|
EOpAverageRounded,
|
||||||
|
EOpMul32x16,
|
||||||
|
|
||||||
EOpTraceNV,
|
EOpTraceNV,
|
||||||
EOpReportIntersectionNV,
|
EOpReportIntersectionNV,
|
||||||
EOpIgnoreIntersectionNV,
|
EOpIgnoreIntersectionNV,
|
||||||
EOpTerminateRayNV,
|
EOpTerminateRayNV,
|
||||||
EOpExecuteCallableNV,
|
EOpExecuteCallableNV,
|
||||||
EOpWritePackedPrimitiveIndices4x8NV,
|
EOpWritePackedPrimitiveIndices4x8NV,
|
||||||
#endif
|
|
||||||
//
|
//
|
||||||
// HLSL operations
|
// HLSL operations
|
||||||
//
|
//
|
||||||
@@ -996,6 +997,10 @@ enum TOperator {
|
|||||||
EOpWaveGetLaneIndex, // Will decompose to gl_SubgroupInvocationID.
|
EOpWaveGetLaneIndex, // Will decompose to gl_SubgroupInvocationID.
|
||||||
EOpWaveActiveCountBits, // Will decompose to subgroupBallotBitCount(subgroupBallot()).
|
EOpWaveActiveCountBits, // Will decompose to subgroupBallotBitCount(subgroupBallot()).
|
||||||
EOpWavePrefixCountBits, // Will decompose to subgroupBallotInclusiveBitCount(subgroupBallot()).
|
EOpWavePrefixCountBits, // Will decompose to subgroupBallotInclusiveBitCount(subgroupBallot()).
|
||||||
|
|
||||||
|
// Shader Clock Ops
|
||||||
|
EOpReadClockSubgroupKHR,
|
||||||
|
EOpReadClockDeviceKHR,
|
||||||
};
|
};
|
||||||
|
|
||||||
class TIntermTraverser;
|
class TIntermTraverser;
|
||||||
@@ -1097,6 +1102,8 @@ public:
|
|||||||
virtual bool isStruct() const { return type.isStruct(); }
|
virtual bool isStruct() const { return type.isStruct(); }
|
||||||
virtual bool isFloatingDomain() const { return type.isFloatingDomain(); }
|
virtual bool isFloatingDomain() const { return type.isFloatingDomain(); }
|
||||||
virtual bool isIntegerDomain() const { return type.isIntegerDomain(); }
|
virtual bool isIntegerDomain() const { return type.isIntegerDomain(); }
|
||||||
|
bool isAtomic() const { return type.isAtomic(); }
|
||||||
|
bool isReference() const { return type.isReference(); }
|
||||||
TString getCompleteString() const { return type.getCompleteString(); }
|
TString getCompleteString() const { return type.getCompleteString(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -1191,6 +1198,7 @@ public:
|
|||||||
virtual void traverse(TIntermTraverser*);
|
virtual void traverse(TIntermTraverser*);
|
||||||
TOperator getFlowOp() const { return flowOp; }
|
TOperator getFlowOp() const { return flowOp; }
|
||||||
TIntermTyped* getExpression() const { return expression; }
|
TIntermTyped* getExpression() const { return expression; }
|
||||||
|
void setExpression(TIntermTyped* pExpression) { expression = pExpression; }
|
||||||
protected:
|
protected:
|
||||||
TOperator flowOp;
|
TOperator flowOp;
|
||||||
TIntermTyped* expression;
|
TIntermTyped* expression;
|
||||||
@@ -1224,7 +1232,7 @@ public:
|
|||||||
// it is essential to use "symbol = sym" to assign to symbol
|
// it is essential to use "symbol = sym" to assign to symbol
|
||||||
TIntermSymbol(int i, const TString& n, const TType& t)
|
TIntermSymbol(int i, const TString& n, const TType& t)
|
||||||
: TIntermTyped(t), id(i),
|
: TIntermTyped(t), id(i),
|
||||||
#ifdef ENABLE_HLSL
|
#ifndef GLSLANG_WEB
|
||||||
flattenSubset(-1),
|
flattenSubset(-1),
|
||||||
#endif
|
#endif
|
||||||
constSubtree(nullptr)
|
constSubtree(nullptr)
|
||||||
@@ -1239,7 +1247,7 @@ public:
|
|||||||
const TConstUnionArray& getConstArray() const { return constArray; }
|
const TConstUnionArray& getConstArray() const { return constArray; }
|
||||||
void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
|
void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
|
||||||
TIntermTyped* getConstSubtree() const { return constSubtree; }
|
TIntermTyped* getConstSubtree() const { return constSubtree; }
|
||||||
#ifdef ENABLE_HLSL
|
#ifndef GLSLANG_WEB
|
||||||
void setFlattenSubset(int subset) { flattenSubset = subset; }
|
void setFlattenSubset(int subset) { flattenSubset = subset; }
|
||||||
int getFlattenSubset() const { return flattenSubset; } // -1 means full object
|
int getFlattenSubset() const { return flattenSubset; } // -1 means full object
|
||||||
#endif
|
#endif
|
||||||
@@ -1250,7 +1258,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
int id; // the unique id of the symbol this node represents
|
int id; // the unique id of the symbol this node represents
|
||||||
#ifdef ENABLE_HLSL
|
#ifndef GLSLANG_WEB
|
||||||
int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced
|
int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced
|
||||||
#endif
|
#endif
|
||||||
TString name; // the name of the symbol this node represents
|
TString name; // the name of the symbol this node represents
|
||||||
@@ -1290,9 +1298,7 @@ struct TCrackedTextureOp {
|
|||||||
bool grad;
|
bool grad;
|
||||||
bool subpass;
|
bool subpass;
|
||||||
bool lodClamp;
|
bool lodClamp;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
bool fragMask;
|
bool fragMask;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -1308,12 +1314,19 @@ public:
|
|||||||
bool isConstructor() const;
|
bool isConstructor() const;
|
||||||
bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; }
|
bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; }
|
||||||
bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; }
|
bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; }
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
bool isImage() const { return false; }
|
||||||
|
bool isSparseTexture() const { return false; }
|
||||||
|
bool isImageFootprint() const { return false; }
|
||||||
|
bool isSparseImage() const { return false; }
|
||||||
|
bool isSubgroup() const { return false; }
|
||||||
|
#else
|
||||||
bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
|
bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
|
||||||
bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
|
bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; }
|
bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; }
|
||||||
#endif
|
|
||||||
bool isSparseImage() const { return op == EOpSparseImageLoad; }
|
bool isSparseImage() const { return op == EOpSparseImageLoad; }
|
||||||
|
bool isSubgroup() const { return op > EOpSubgroupGuardStart && op < EOpSubgroupGuardStop; }
|
||||||
|
#endif
|
||||||
|
|
||||||
void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; }
|
void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; }
|
||||||
TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ?
|
TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ?
|
||||||
@@ -1343,9 +1356,7 @@ public:
|
|||||||
cracked.grad = false;
|
cracked.grad = false;
|
||||||
cracked.subpass = false;
|
cracked.subpass = false;
|
||||||
cracked.lodClamp = false;
|
cracked.lodClamp = false;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
cracked.fragMask = false;
|
cracked.fragMask = false;
|
||||||
#endif
|
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case EOpImageQuerySize:
|
case EOpImageQuerySize:
|
||||||
@@ -1360,10 +1371,6 @@ public:
|
|||||||
case EOpTexture:
|
case EOpTexture:
|
||||||
case EOpSparseTexture:
|
case EOpSparseTexture:
|
||||||
break;
|
break;
|
||||||
case EOpTextureClamp:
|
|
||||||
case EOpSparseTextureClamp:
|
|
||||||
cracked.lodClamp = true;
|
|
||||||
break;
|
|
||||||
case EOpTextureProj:
|
case EOpTextureProj:
|
||||||
cracked.proj = true;
|
cracked.proj = true;
|
||||||
break;
|
break;
|
||||||
@@ -1375,22 +1382,17 @@ public:
|
|||||||
case EOpSparseTextureOffset:
|
case EOpSparseTextureOffset:
|
||||||
cracked.offset = true;
|
cracked.offset = true;
|
||||||
break;
|
break;
|
||||||
case EOpTextureOffsetClamp:
|
|
||||||
case EOpSparseTextureOffsetClamp:
|
|
||||||
cracked.offset = true;
|
|
||||||
cracked.lodClamp = true;
|
|
||||||
break;
|
|
||||||
case EOpTextureFetch:
|
case EOpTextureFetch:
|
||||||
case EOpSparseTextureFetch:
|
case EOpSparseTextureFetch:
|
||||||
cracked.fetch = true;
|
cracked.fetch = true;
|
||||||
if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D)
|
if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D)
|
||||||
cracked.lod = true;
|
cracked.lod = true;
|
||||||
break;
|
break;
|
||||||
case EOpTextureFetchOffset:
|
case EOpTextureFetchOffset:
|
||||||
case EOpSparseTextureFetchOffset:
|
case EOpSparseTextureFetchOffset:
|
||||||
cracked.fetch = true;
|
cracked.fetch = true;
|
||||||
cracked.offset = true;
|
cracked.offset = true;
|
||||||
if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D)
|
if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D)
|
||||||
cracked.lod = true;
|
cracked.lod = true;
|
||||||
break;
|
break;
|
||||||
case EOpTextureProjOffset:
|
case EOpTextureProjOffset:
|
||||||
@@ -1415,11 +1417,6 @@ public:
|
|||||||
case EOpSparseTextureGrad:
|
case EOpSparseTextureGrad:
|
||||||
cracked.grad = true;
|
cracked.grad = true;
|
||||||
break;
|
break;
|
||||||
case EOpTextureGradClamp:
|
|
||||||
case EOpSparseTextureGradClamp:
|
|
||||||
cracked.grad = true;
|
|
||||||
cracked.lodClamp = true;
|
|
||||||
break;
|
|
||||||
case EOpTextureGradOffset:
|
case EOpTextureGradOffset:
|
||||||
case EOpSparseTextureGradOffset:
|
case EOpSparseTextureGradOffset:
|
||||||
cracked.grad = true;
|
cracked.grad = true;
|
||||||
@@ -1434,6 +1431,21 @@ public:
|
|||||||
cracked.offset = true;
|
cracked.offset = true;
|
||||||
cracked.proj = true;
|
cracked.proj = true;
|
||||||
break;
|
break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
case EOpTextureClamp:
|
||||||
|
case EOpSparseTextureClamp:
|
||||||
|
cracked.lodClamp = true;
|
||||||
|
break;
|
||||||
|
case EOpTextureOffsetClamp:
|
||||||
|
case EOpSparseTextureOffsetClamp:
|
||||||
|
cracked.offset = true;
|
||||||
|
cracked.lodClamp = true;
|
||||||
|
break;
|
||||||
|
case EOpTextureGradClamp:
|
||||||
|
case EOpSparseTextureGradClamp:
|
||||||
|
cracked.grad = true;
|
||||||
|
cracked.lodClamp = true;
|
||||||
|
break;
|
||||||
case EOpTextureGradOffsetClamp:
|
case EOpTextureGradOffsetClamp:
|
||||||
case EOpSparseTextureGradOffsetClamp:
|
case EOpSparseTextureGradOffsetClamp:
|
||||||
cracked.grad = true;
|
cracked.grad = true;
|
||||||
@@ -1454,7 +1466,6 @@ public:
|
|||||||
cracked.gather = true;
|
cracked.gather = true;
|
||||||
cracked.offsets = true;
|
cracked.offsets = true;
|
||||||
break;
|
break;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpTextureGatherLod:
|
case EOpTextureGatherLod:
|
||||||
case EOpSparseTextureGatherLod:
|
case EOpSparseTextureGatherLod:
|
||||||
cracked.gather = true;
|
cracked.gather = true;
|
||||||
@@ -1485,8 +1496,6 @@ public:
|
|||||||
cracked.subpass = sampler.dim == EsdSubpass;
|
cracked.subpass = sampler.dim == EsdSubpass;
|
||||||
cracked.fragMask = true;
|
cracked.fragMask = true;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EOpImageSampleFootprintNV:
|
case EOpImageSampleFootprintNV:
|
||||||
break;
|
break;
|
||||||
case EOpImageSampleFootprintClampNV:
|
case EOpImageSampleFootprintClampNV:
|
||||||
@@ -1502,11 +1511,11 @@ public:
|
|||||||
cracked.lodClamp = true;
|
cracked.lodClamp = true;
|
||||||
cracked.grad = true;
|
cracked.grad = true;
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
case EOpSubpassLoad:
|
case EOpSubpassLoad:
|
||||||
case EOpSubpassLoadMS:
|
case EOpSubpassLoadMS:
|
||||||
cracked.subpass = true;
|
cracked.subpass = true;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
// This header is generated by the make-revision script.
|
// This header is generated by the make-revision script.
|
||||||
|
|
||||||
#define GLSLANG_PATCH_LEVEL 3226
|
#define GLSLANG_PATCH_LEVEL 3559
|
||||||
|
|||||||
@@ -189,6 +189,24 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
|||||||
else
|
else
|
||||||
newConstArray[i].setDConst((double)NAN);
|
newConstArray[i].setDConst((double)NAN);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EbtInt:
|
||||||
|
if (rightUnionArray[i] == 0)
|
||||||
|
newConstArray[i].setIConst(0x7FFFFFFF);
|
||||||
|
else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == (int)-0x80000000ll)
|
||||||
|
newConstArray[i].setIConst((int)-0x80000000ll);
|
||||||
|
else
|
||||||
|
newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EbtUint:
|
||||||
|
if (rightUnionArray[i] == 0u)
|
||||||
|
newConstArray[i].setUConst(0xFFFFFFFFu);
|
||||||
|
else
|
||||||
|
newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
if (rightUnionArray[i] == (signed char)0)
|
if (rightUnionArray[i] == (signed char)0)
|
||||||
newConstArray[i].setI8Const((signed char)0x7F);
|
newConstArray[i].setI8Const((signed char)0x7F);
|
||||||
@@ -221,22 +239,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
|||||||
newConstArray[i].setU16Const(leftUnionArray[i].getU16Const() / rightUnionArray[i].getU16Const());
|
newConstArray[i].setU16Const(leftUnionArray[i].getU16Const() / rightUnionArray[i].getU16Const());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EbtInt:
|
|
||||||
if (rightUnionArray[i] == 0)
|
|
||||||
newConstArray[i].setIConst(0x7FFFFFFF);
|
|
||||||
else if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == (int)-0x80000000ll)
|
|
||||||
newConstArray[i].setIConst((int)-0x80000000ll);
|
|
||||||
else
|
|
||||||
newConstArray[i].setIConst(leftUnionArray[i].getIConst() / rightUnionArray[i].getIConst());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EbtUint:
|
|
||||||
if (rightUnionArray[i] == 0u)
|
|
||||||
newConstArray[i].setUConst(0xFFFFFFFFu);
|
|
||||||
else
|
|
||||||
newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
if (rightUnionArray[i] == 0ll)
|
if (rightUnionArray[i] == 0ll)
|
||||||
newConstArray[i].setI64Const(0x7FFFFFFFFFFFFFFFll);
|
newConstArray[i].setI64Const(0x7FFFFFFFFFFFFFFFll);
|
||||||
@@ -254,6 +256,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -292,13 +295,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right
|
|||||||
newConstArray[i].setIConst(0);
|
newConstArray[i].setIConst(0);
|
||||||
break;
|
break;
|
||||||
} else goto modulo_default;
|
} else goto modulo_default;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == LLONG_MIN) {
|
if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == LLONG_MIN) {
|
||||||
newConstArray[i].setI64Const(0);
|
newConstArray[i].setI64Const(0);
|
||||||
break;
|
break;
|
||||||
} else goto modulo_default;
|
} else goto modulo_default;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbtInt16:
|
case EbtInt16:
|
||||||
if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == SHRT_MIN) {
|
if (rightUnionArray[i].getIConst() == -1 && leftUnionArray[i].getIConst() == SHRT_MIN) {
|
||||||
newConstArray[i].setIConst(0);
|
newConstArray[i].setIConst(0);
|
||||||
@@ -415,8 +417,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
|
|
||||||
case EOpEmitStreamVertex:
|
case EOpEmitStreamVertex:
|
||||||
case EOpEndStreamPrimitive:
|
case EOpEndStreamPrimitive:
|
||||||
// These don't actually fold
|
// These don't fold
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
case EOpPackSnorm2x16:
|
case EOpPackSnorm2x16:
|
||||||
case EOpPackUnorm2x16:
|
case EOpPackUnorm2x16:
|
||||||
@@ -491,8 +493,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out
|
|
||||||
|
|
||||||
case EOpPackSnorm2x16:
|
case EOpPackSnorm2x16:
|
||||||
case EOpPackUnorm2x16:
|
case EOpPackUnorm2x16:
|
||||||
case EOpPackHalf2x16:
|
case EOpPackHalf2x16:
|
||||||
@@ -510,7 +510,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
case EOpDeterminant:
|
case EOpDeterminant:
|
||||||
case EOpMatrixInverse:
|
case EOpMatrixInverse:
|
||||||
case EOpTranspose:
|
case EOpTranspose:
|
||||||
return 0;
|
return nullptr;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(componentWise);
|
assert(componentWise);
|
||||||
@@ -529,16 +529,18 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
|
case EbtFloat: newConstArray[i].setDConst(-unionArray[i].getDConst()); break;
|
||||||
|
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
|
||||||
|
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8: newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break;
|
case EbtInt8: newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break;
|
||||||
case EbtUint8: newConstArray[i].setU8Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU8Const()))); break;
|
case EbtUint8: newConstArray[i].setU8Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU8Const()))); break;
|
||||||
case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break;
|
case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break;
|
||||||
case EbtUint16:newConstArray[i].setU16Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU16Const()))); break;
|
case EbtUint16:newConstArray[i].setU16Const(static_cast<unsigned int>(-static_cast<signed int>(unionArray[i].getU16Const()))); break;
|
||||||
case EbtInt: newConstArray[i].setIConst(-unionArray[i].getIConst()); break;
|
|
||||||
case EbtUint: newConstArray[i].setUConst(static_cast<unsigned int>(-static_cast<int>(unionArray[i].getUConst()))); break;
|
|
||||||
case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
|
case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break;
|
||||||
case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned long long>(-static_cast<long long>(unionArray[i].getU64Const()))); break;
|
case EbtUint64: newConstArray[i].setU64Const(static_cast<unsigned long long>(-static_cast<long long>(unionArray[i].getU64Const()))); break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EOpLogicalNot:
|
case EOpLogicalNot:
|
||||||
@@ -546,7 +548,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
switch (getType().getBasicType()) {
|
switch (getType().getBasicType()) {
|
||||||
case EbtBool: newConstArray[i].setBConst(!unionArray[i].getBConst()); break;
|
case EbtBool: newConstArray[i].setBConst(!unionArray[i].getBConst()); break;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EOpBitwiseNot:
|
case EOpBitwiseNot:
|
||||||
@@ -671,6 +673,48 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case EOpConvIntToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getIConst() != 0); break;
|
||||||
|
case EOpConvUintToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getUConst() != 0); break;
|
||||||
|
case EOpConvBoolToInt:
|
||||||
|
newConstArray[i].setIConst(unionArray[i].getBConst()); break;
|
||||||
|
case EOpConvBoolToUint:
|
||||||
|
newConstArray[i].setUConst(unionArray[i].getBConst()); break;
|
||||||
|
case EOpConvIntToUint:
|
||||||
|
newConstArray[i].setUConst(unionArray[i].getIConst()); break;
|
||||||
|
case EOpConvUintToInt:
|
||||||
|
newConstArray[i].setIConst(unionArray[i].getUConst()); break;
|
||||||
|
|
||||||
|
case EOpConvFloatToBool:
|
||||||
|
case EOpConvDoubleToBool:
|
||||||
|
newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
|
||||||
|
|
||||||
|
case EOpConvBoolToFloat:
|
||||||
|
case EOpConvBoolToDouble:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getBConst()); break;
|
||||||
|
|
||||||
|
case EOpConvIntToFloat:
|
||||||
|
case EOpConvIntToDouble:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getIConst()); break;
|
||||||
|
|
||||||
|
case EOpConvUintToFloat:
|
||||||
|
case EOpConvUintToDouble:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getUConst()); break;
|
||||||
|
|
||||||
|
case EOpConvDoubleToFloat:
|
||||||
|
case EOpConvFloatToDouble:
|
||||||
|
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
||||||
|
|
||||||
|
case EOpConvFloatToUint:
|
||||||
|
case EOpConvDoubleToUint:
|
||||||
|
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getDConst())); break;
|
||||||
|
|
||||||
|
case EOpConvFloatToInt:
|
||||||
|
case EOpConvDoubleToInt:
|
||||||
|
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EOpConvInt8ToBool:
|
case EOpConvInt8ToBool:
|
||||||
newConstArray[i].setBConst(unionArray[i].getI8Const() != 0); break;
|
newConstArray[i].setBConst(unionArray[i].getI8Const() != 0); break;
|
||||||
case EOpConvUint8ToBool:
|
case EOpConvUint8ToBool:
|
||||||
@@ -679,20 +723,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
newConstArray[i].setBConst(unionArray[i].getI16Const() != 0); break;
|
newConstArray[i].setBConst(unionArray[i].getI16Const() != 0); break;
|
||||||
case EOpConvUint16ToBool:
|
case EOpConvUint16ToBool:
|
||||||
newConstArray[i].setBConst(unionArray[i].getU16Const() != 0); break;
|
newConstArray[i].setBConst(unionArray[i].getU16Const() != 0); break;
|
||||||
case EOpConvIntToBool:
|
|
||||||
newConstArray[i].setBConst(unionArray[i].getIConst() != 0); break;
|
|
||||||
case EOpConvUintToBool:
|
|
||||||
newConstArray[i].setBConst(unionArray[i].getUConst() != 0); break;
|
|
||||||
case EOpConvInt64ToBool:
|
case EOpConvInt64ToBool:
|
||||||
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
|
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
|
||||||
case EOpConvUint64ToBool:
|
case EOpConvUint64ToBool:
|
||||||
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
|
newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break;
|
||||||
case EOpConvFloat16ToBool:
|
case EOpConvFloat16ToBool:
|
||||||
newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
|
newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
|
||||||
case EOpConvFloatToBool:
|
|
||||||
newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
|
|
||||||
case EOpConvDoubleToBool:
|
|
||||||
newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break;
|
|
||||||
|
|
||||||
case EOpConvBoolToInt8:
|
case EOpConvBoolToInt8:
|
||||||
newConstArray[i].setI8Const(unionArray[i].getBConst()); break;
|
newConstArray[i].setI8Const(unionArray[i].getBConst()); break;
|
||||||
@@ -702,20 +738,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
newConstArray[i].setI16Const(unionArray[i].getBConst()); break;
|
newConstArray[i].setI16Const(unionArray[i].getBConst()); break;
|
||||||
case EOpConvBoolToUint16:
|
case EOpConvBoolToUint16:
|
||||||
newConstArray[i].setU16Const(unionArray[i].getBConst()); break;
|
newConstArray[i].setU16Const(unionArray[i].getBConst()); break;
|
||||||
case EOpConvBoolToInt:
|
|
||||||
newConstArray[i].setIConst(unionArray[i].getBConst()); break;
|
|
||||||
case EOpConvBoolToUint:
|
|
||||||
newConstArray[i].setUConst(unionArray[i].getBConst()); break;
|
|
||||||
case EOpConvBoolToInt64:
|
case EOpConvBoolToInt64:
|
||||||
newConstArray[i].setI64Const(unionArray[i].getBConst()); break;
|
newConstArray[i].setI64Const(unionArray[i].getBConst()); break;
|
||||||
case EOpConvBoolToUint64:
|
case EOpConvBoolToUint64:
|
||||||
newConstArray[i].setU64Const(unionArray[i].getBConst()); break;
|
newConstArray[i].setU64Const(unionArray[i].getBConst()); break;
|
||||||
case EOpConvBoolToFloat16:
|
case EOpConvBoolToFloat16:
|
||||||
newConstArray[i].setDConst(unionArray[i].getBConst()); break;
|
newConstArray[i].setDConst(unionArray[i].getBConst()); break;
|
||||||
case EOpConvBoolToFloat:
|
|
||||||
newConstArray[i].setDConst(unionArray[i].getBConst()); break;
|
|
||||||
case EOpConvBoolToDouble:
|
|
||||||
newConstArray[i].setDConst(unionArray[i].getBConst()); break;
|
|
||||||
|
|
||||||
case EOpConvInt8ToInt16:
|
case EOpConvInt8ToInt16:
|
||||||
newConstArray[i].setI16Const(unionArray[i].getI8Const()); break;
|
newConstArray[i].setI16Const(unionArray[i].getI8Const()); break;
|
||||||
@@ -810,8 +838,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
newConstArray[i].setU8Const((unsigned char)unionArray[i].getIConst()); break;
|
newConstArray[i].setU8Const((unsigned char)unionArray[i].getIConst()); break;
|
||||||
case EOpConvIntToUint16:
|
case EOpConvIntToUint16:
|
||||||
newConstArray[i].setU16Const((unsigned char)unionArray[i].getIConst()); break;
|
newConstArray[i].setU16Const((unsigned char)unionArray[i].getIConst()); break;
|
||||||
case EOpConvIntToUint:
|
|
||||||
newConstArray[i].setUConst(unionArray[i].getIConst()); break;
|
|
||||||
case EOpConvIntToUint64:
|
case EOpConvIntToUint64:
|
||||||
newConstArray[i].setU64Const(unionArray[i].getIConst()); break;
|
newConstArray[i].setU64Const(unionArray[i].getIConst()); break;
|
||||||
|
|
||||||
@@ -819,8 +845,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
newConstArray[i].setI8Const((signed char)unionArray[i].getUConst()); break;
|
newConstArray[i].setI8Const((signed char)unionArray[i].getUConst()); break;
|
||||||
case EOpConvUintToInt16:
|
case EOpConvUintToInt16:
|
||||||
newConstArray[i].setI16Const((signed short)unionArray[i].getUConst()); break;
|
newConstArray[i].setI16Const((signed short)unionArray[i].getUConst()); break;
|
||||||
case EOpConvUintToInt:
|
|
||||||
newConstArray[i].setIConst(unionArray[i].getUConst()); break;
|
|
||||||
case EOpConvUintToInt64:
|
case EOpConvUintToInt64:
|
||||||
newConstArray[i].setI64Const(unionArray[i].getUConst()); break;
|
newConstArray[i].setI64Const(unionArray[i].getUConst()); break;
|
||||||
case EOpConvUintToUint8:
|
case EOpConvUintToUint8:
|
||||||
@@ -831,16 +855,8 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
newConstArray[i].setU64Const(unionArray[i].getUConst()); break;
|
newConstArray[i].setU64Const(unionArray[i].getUConst()); break;
|
||||||
case EOpConvIntToFloat16:
|
case EOpConvIntToFloat16:
|
||||||
newConstArray[i].setDConst(unionArray[i].getIConst()); break;
|
newConstArray[i].setDConst(unionArray[i].getIConst()); break;
|
||||||
case EOpConvIntToFloat:
|
|
||||||
newConstArray[i].setDConst(unionArray[i].getIConst()); break;
|
|
||||||
case EOpConvIntToDouble:
|
|
||||||
newConstArray[i].setDConst(unionArray[i].getIConst()); break;
|
|
||||||
case EOpConvUintToFloat16:
|
case EOpConvUintToFloat16:
|
||||||
newConstArray[i].setDConst(unionArray[i].getUConst()); break;
|
newConstArray[i].setDConst(unionArray[i].getUConst()); break;
|
||||||
case EOpConvUintToFloat:
|
|
||||||
newConstArray[i].setDConst(unionArray[i].getUConst()); break;
|
|
||||||
case EOpConvUintToDouble:
|
|
||||||
newConstArray[i].setDConst(unionArray[i].getUConst()); break;
|
|
||||||
case EOpConvInt64ToInt8:
|
case EOpConvInt64ToInt8:
|
||||||
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getI64Const())); break;
|
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getI64Const())); break;
|
||||||
case EOpConvInt64ToInt16:
|
case EOpConvInt64ToInt16:
|
||||||
@@ -905,48 +921,35 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
|
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvFloatToInt16:
|
case EOpConvFloatToInt16:
|
||||||
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
|
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvFloatToInt:
|
|
||||||
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
|
|
||||||
case EOpConvFloatToInt64:
|
case EOpConvFloatToInt64:
|
||||||
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
|
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvFloatToUint8:
|
case EOpConvFloatToUint8:
|
||||||
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
|
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvFloatToUint16:
|
case EOpConvFloatToUint16:
|
||||||
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
|
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvFloatToUint:
|
|
||||||
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getDConst())); break;
|
|
||||||
case EOpConvFloatToUint64:
|
case EOpConvFloatToUint64:
|
||||||
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
|
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvFloatToFloat16:
|
case EOpConvFloatToFloat16:
|
||||||
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
||||||
case EOpConvFloatToDouble:
|
|
||||||
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
|
||||||
case EOpConvDoubleToInt8:
|
case EOpConvDoubleToInt8:
|
||||||
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
|
newConstArray[i].setI8Const(static_cast<signed char>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvDoubleToInt16:
|
case EOpConvDoubleToInt16:
|
||||||
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
|
newConstArray[i].setI16Const(static_cast<signed short>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvDoubleToInt:
|
|
||||||
newConstArray[i].setIConst(static_cast<int>(unionArray[i].getDConst())); break;
|
|
||||||
case EOpConvDoubleToInt64:
|
case EOpConvDoubleToInt64:
|
||||||
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
|
newConstArray[i].setI64Const(static_cast<long long>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvDoubleToUint8:
|
case EOpConvDoubleToUint8:
|
||||||
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
|
newConstArray[i].setU8Const(static_cast<unsigned char>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvDoubleToUint16:
|
case EOpConvDoubleToUint16:
|
||||||
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
|
newConstArray[i].setU16Const(static_cast<unsigned short>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvDoubleToUint:
|
|
||||||
newConstArray[i].setUConst(static_cast<unsigned int>(unionArray[i].getDConst())); break;
|
|
||||||
case EOpConvDoubleToUint64:
|
case EOpConvDoubleToUint64:
|
||||||
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
|
newConstArray[i].setU64Const(static_cast<unsigned long long>(unionArray[i].getDConst())); break;
|
||||||
case EOpConvDoubleToFloat16:
|
case EOpConvDoubleToFloat16:
|
||||||
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
||||||
case EOpConvDoubleToFloat:
|
|
||||||
newConstArray[i].setDConst(unionArray[i].getDConst()); break;
|
|
||||||
case EOpConvPtrToUint64:
|
case EOpConvPtrToUint64:
|
||||||
case EOpConvUint64ToPtr:
|
case EOpConvUint64ToPtr:
|
||||||
case EOpConstructReference:
|
case EOpConstructReference:
|
||||||
newConstArray[i].setU64Const(unionArray[i].getU64Const()); break;
|
newConstArray[i].setU64Const(unionArray[i].getU64Const()); break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out
|
// TODO: 3.0 Functionality: unary constant folding: the rest of the ops have to be fleshed out
|
||||||
|
|
||||||
@@ -970,7 +973,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType)
|
|||||||
case EOpInt16BitsToFloat16:
|
case EOpInt16BitsToFloat16:
|
||||||
case EOpUint16BitsToFloat16:
|
case EOpUint16BitsToFloat16:
|
||||||
default:
|
default:
|
||||||
return 0;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1078,6 +1081,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
|||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
newConstArray[comp].setDConst(std::min(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
||||||
break;
|
break;
|
||||||
|
case EbtInt:
|
||||||
|
newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
|
||||||
|
break;
|
||||||
|
case EbtUint:
|
||||||
|
newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
|
||||||
|
break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
newConstArray[comp].setI8Const(std::min(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
|
newConstArray[comp].setI8Const(std::min(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
|
||||||
break;
|
break;
|
||||||
@@ -1090,18 +1100,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
|||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
newConstArray[comp].setU16Const(std::min(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()));
|
newConstArray[comp].setU16Const(std::min(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()));
|
||||||
break;
|
break;
|
||||||
case EbtInt:
|
|
||||||
newConstArray[comp].setIConst(std::min(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
|
|
||||||
break;
|
|
||||||
case EbtUint:
|
|
||||||
newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
|
|
||||||
break;
|
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
newConstArray[comp].setI64Const(std::min(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
|
newConstArray[comp].setI64Const(std::min(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
|
||||||
break;
|
break;
|
||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
|
newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1112,6 +1117,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
|||||||
case EbtDouble:
|
case EbtDouble:
|
||||||
newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
newConstArray[comp].setDConst(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()));
|
||||||
break;
|
break;
|
||||||
|
case EbtInt:
|
||||||
|
newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
|
||||||
|
break;
|
||||||
|
case EbtUint:
|
||||||
|
newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
|
||||||
|
break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
newConstArray[comp].setI8Const(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
|
newConstArray[comp].setI8Const(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()));
|
||||||
break;
|
break;
|
||||||
@@ -1124,18 +1136,13 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
|||||||
case EbtUint16:
|
case EbtUint16:
|
||||||
newConstArray[comp].setU16Const(std::max(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()));
|
newConstArray[comp].setU16Const(std::max(childConstUnions[0][arg0comp].getU16Const(), childConstUnions[1][arg1comp].getU16Const()));
|
||||||
break;
|
break;
|
||||||
case EbtInt:
|
|
||||||
newConstArray[comp].setIConst(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()));
|
|
||||||
break;
|
|
||||||
case EbtUint:
|
|
||||||
newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()));
|
|
||||||
break;
|
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
newConstArray[comp].setI64Const(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
|
newConstArray[comp].setI64Const(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()));
|
||||||
break;
|
break;
|
||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
|
newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()));
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1147,6 +1154,11 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
|||||||
newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()),
|
newConstArray[comp].setDConst(std::min(std::max(childConstUnions[0][arg0comp].getDConst(), childConstUnions[1][arg1comp].getDConst()),
|
||||||
childConstUnions[2][arg2comp].getDConst()));
|
childConstUnions[2][arg2comp].getDConst()));
|
||||||
break;
|
break;
|
||||||
|
case EbtUint:
|
||||||
|
newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()),
|
||||||
|
childConstUnions[2][arg2comp].getUConst()));
|
||||||
|
break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EbtInt8:
|
case EbtInt8:
|
||||||
newConstArray[comp].setI8Const(std::min(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()),
|
newConstArray[comp].setI8Const(std::min(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()),
|
||||||
childConstUnions[2][arg2comp].getI8Const()));
|
childConstUnions[2][arg2comp].getI8Const()));
|
||||||
@@ -1167,10 +1179,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
|||||||
newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()),
|
newConstArray[comp].setIConst(std::min(std::max(childConstUnions[0][arg0comp].getIConst(), childConstUnions[1][arg1comp].getIConst()),
|
||||||
childConstUnions[2][arg2comp].getIConst()));
|
childConstUnions[2][arg2comp].getIConst()));
|
||||||
break;
|
break;
|
||||||
case EbtUint:
|
|
||||||
newConstArray[comp].setUConst(std::min(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst()),
|
|
||||||
childConstUnions[2][arg2comp].getUConst()));
|
|
||||||
break;
|
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
newConstArray[comp].setI64Const(std::min(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()),
|
newConstArray[comp].setI64Const(std::min(std::max(childConstUnions[0][arg0comp].getI64Const(), childConstUnions[1][arg1comp].getI64Const()),
|
||||||
childConstUnions[2][arg2comp].getI64Const()));
|
childConstUnions[2][arg2comp].getI64Const()));
|
||||||
@@ -1179,6 +1187,7 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
|||||||
newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()),
|
newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()),
|
||||||
childConstUnions[2][arg2comp].getU64Const()));
|
childConstUnions[2][arg2comp].getU64Const()));
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default: assert(false && "Default missing");
|
default: assert(false && "Default missing");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1201,12 +1210,17 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode)
|
|||||||
newConstArray[comp].setBConst(childConstUnions[0][arg0comp] != childConstUnions[1][arg1comp]);
|
newConstArray[comp].setBConst(childConstUnions[0][arg0comp] != childConstUnions[1][arg1comp]);
|
||||||
break;
|
break;
|
||||||
case EOpMix:
|
case EOpMix:
|
||||||
if (children[2]->getAsTyped()->getBasicType() == EbtBool)
|
if (!children[0]->getAsTyped()->isFloatingDomain())
|
||||||
newConstArray[comp].setDConst(childConstUnions[2][arg2comp].getBConst() ? childConstUnions[1][arg1comp].getDConst() :
|
return aggrNode;
|
||||||
childConstUnions[0][arg0comp].getDConst());
|
if (children[2]->getAsTyped()->getBasicType() == EbtBool) {
|
||||||
else
|
newConstArray[comp].setDConst(childConstUnions[2][arg2comp].getBConst()
|
||||||
newConstArray[comp].setDConst(childConstUnions[0][arg0comp].getDConst() * (1.0 - childConstUnions[2][arg2comp].getDConst()) +
|
? childConstUnions[1][arg1comp].getDConst()
|
||||||
|
: childConstUnions[0][arg0comp].getDConst());
|
||||||
|
} else {
|
||||||
|
newConstArray[comp].setDConst(
|
||||||
|
childConstUnions[0][arg0comp].getDConst() * (1.0 - childConstUnions[2][arg2comp].getDConst()) +
|
||||||
childConstUnions[1][arg1comp].getDConst() * childConstUnions[2][arg2comp].getDConst());
|
childConstUnions[1][arg1comp].getDConst() * childConstUnions[2][arg2comp].getDConst());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case EOpStep:
|
case EOpStep:
|
||||||
newConstArray[comp].setDConst(childConstUnions[1][arg1comp].getDConst() < childConstUnions[0][arg0comp].getDConst() ? 0.0 : 1.0);
|
newConstArray[comp].setDConst(childConstUnions[1][arg1comp].getDConst() < childConstUnions[0][arg0comp].getDConst() ? 0.0 : 1.0);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -91,6 +91,8 @@ public:
|
|||||||
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources);
|
void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void addTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion);
|
||||||
|
void relateTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage, TSymbolTable&);
|
||||||
void add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion);
|
void add2ndGenerationSamplingImaging(int version, EProfile profile, const SpvVersion& spvVersion);
|
||||||
void addSubpassSampling(TSampler, const TString& typeName, int version, EProfile profile);
|
void addSubpassSampling(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
void addQueryFunctions(TSampler, const TString& typeName, int version, EProfile profile);
|
void addQueryFunctions(TSampler, const TString& typeName, int version, EProfile profile);
|
||||||
|
|||||||
Regular → Executable
+511
-649
File diff suppressed because it is too large
Load Diff
@@ -67,6 +67,8 @@ void TParseContextBase::outputMessage(const TSourceLoc& loc, const char* szReaso
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL)
|
||||||
|
|
||||||
void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason, const char* szToken,
|
void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, ...)
|
const char* szExtraInfoFormat, ...)
|
||||||
{
|
{
|
||||||
@@ -113,6 +115,8 @@ void C_DECL TParseContextBase::ppWarn(const TSourceLoc& loc, const char* szReaso
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Both test and if necessary, spit out an error, to see if the node is really
|
// Both test and if necessary, spit out an error, to see if the node is really
|
||||||
// an l-value that can be operated on this way.
|
// an l-value that can be operated on this way.
|
||||||
@@ -149,15 +153,13 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
|
|||||||
case EvqConst: message = "can't modify a const"; break;
|
case EvqConst: message = "can't modify a const"; break;
|
||||||
case EvqConstReadOnly: message = "can't modify a const"; break;
|
case EvqConstReadOnly: message = "can't modify a const"; break;
|
||||||
case EvqUniform: message = "can't modify a uniform"; break;
|
case EvqUniform: message = "can't modify a uniform"; break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EvqBuffer:
|
case EvqBuffer:
|
||||||
if (node->getQualifier().readonly)
|
if (node->getQualifier().isReadOnly())
|
||||||
message = "can't modify a readonly buffer";
|
message = "can't modify a readonly buffer";
|
||||||
#ifdef NV_EXTENSIONS
|
if (node->getQualifier().isShaderRecordNV())
|
||||||
if (node->getQualifier().layoutShaderRecordNV)
|
|
||||||
message = "can't modify a shaderrecordnv qualified buffer";
|
message = "can't modify a shaderrecordnv qualified buffer";
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EvqHitAttrNV:
|
case EvqHitAttrNV:
|
||||||
if (language != EShLangIntersectNV)
|
if (language != EShLangIntersectNV)
|
||||||
message = "cannot modify hitAttributeNV in this stage";
|
message = "cannot modify hitAttributeNV in this stage";
|
||||||
@@ -172,13 +174,13 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op,
|
|||||||
case EbtSampler:
|
case EbtSampler:
|
||||||
message = "can't modify a sampler";
|
message = "can't modify a sampler";
|
||||||
break;
|
break;
|
||||||
case EbtAtomicUint:
|
|
||||||
message = "can't modify an atomic_uint";
|
|
||||||
break;
|
|
||||||
case EbtVoid:
|
case EbtVoid:
|
||||||
message = "can't modify void";
|
message = "can't modify void";
|
||||||
break;
|
break;
|
||||||
#ifdef NV_EXTENSIONS
|
#ifndef GLSLANG_WEB
|
||||||
|
case EbtAtomicUint:
|
||||||
|
message = "can't modify an atomic_uint";
|
||||||
|
break;
|
||||||
case EbtAccStructNV:
|
case EbtAccStructNV:
|
||||||
message = "can't modify accelerationStructureNV";
|
message = "can't modify accelerationStructureNV";
|
||||||
break;
|
break;
|
||||||
@@ -234,7 +236,7 @@ void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op,
|
|||||||
}
|
}
|
||||||
|
|
||||||
TIntermSymbol* symNode = node->getAsSymbolNode();
|
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());
|
error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,11 +256,17 @@ void TParseContextBase::trackLinkage(TSymbol& symbol)
|
|||||||
// Give an error if not.
|
// Give an error if not.
|
||||||
void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int& index)
|
void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int& index)
|
||||||
{
|
{
|
||||||
|
const auto sizeIsSpecializationExpression = [&type]() {
|
||||||
|
return type.containsSpecializationSize() &&
|
||||||
|
type.getArraySizes()->getOuterNode() != nullptr &&
|
||||||
|
type.getArraySizes()->getOuterNode()->getAsSymbolNode() == nullptr; };
|
||||||
|
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
error(loc, "", "[", "index out of range '%d'", index);
|
error(loc, "", "[", "index out of range '%d'", index);
|
||||||
index = 0;
|
index = 0;
|
||||||
} else if (type.isArray()) {
|
} else if (type.isArray()) {
|
||||||
if (type.isSizedArray() && index >= type.getOuterArraySize()) {
|
if (type.isSizedArray() && !sizeIsSpecializationExpression() &&
|
||||||
|
index >= type.getOuterArraySize()) {
|
||||||
error(loc, "", "[", "array index out of range '%d'", index);
|
error(loc, "", "[", "array index out of range '%d'", index);
|
||||||
index = type.getOuterArraySize() - 1;
|
index = type.getOuterArraySize() - 1;
|
||||||
}
|
}
|
||||||
@@ -568,6 +576,7 @@ void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TStrin
|
|||||||
selector.push_back(0);
|
selector.push_back(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
//
|
//
|
||||||
// Make the passed-in variable information become a member of the
|
// Make the passed-in variable information become a member of the
|
||||||
// global uniform block. If this doesn't exist yet, make it.
|
// global uniform block. If this doesn't exist yet, make it.
|
||||||
@@ -612,6 +621,7 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem
|
|||||||
|
|
||||||
++firstNewMember;
|
++firstNewMember;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void TParseContextBase::finish()
|
void TParseContextBase::finish()
|
||||||
{
|
{
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -85,6 +85,7 @@ public:
|
|||||||
statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
|
statementNestingLevel(0), loopNestingLevel(0), structNestingLevel(0), controlFlowNestingLevel(0),
|
||||||
postEntryPointReturn(false),
|
postEntryPointReturn(false),
|
||||||
contextPragma(true, false),
|
contextPragma(true, false),
|
||||||
|
beginInvocationInterlockCount(0), endInvocationInterlockCount(0),
|
||||||
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
|
parsingBuiltins(parsingBuiltins), scanContext(nullptr), ppContext(nullptr),
|
||||||
limits(resources.limits),
|
limits(resources.limits),
|
||||||
globalUniformBlock(nullptr),
|
globalUniformBlock(nullptr),
|
||||||
@@ -96,6 +97,7 @@ public:
|
|||||||
}
|
}
|
||||||
virtual ~TParseContextBase() { }
|
virtual ~TParseContextBase() { }
|
||||||
|
|
||||||
|
#if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL)
|
||||||
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, ...);
|
const char* szExtraInfoFormat, ...);
|
||||||
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
|
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
@@ -104,6 +106,7 @@ public:
|
|||||||
const char* szExtraInfoFormat, ...);
|
const char* szExtraInfoFormat, ...);
|
||||||
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, ...);
|
const char* szExtraInfoFormat, ...);
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual void setLimits(const TBuiltInResource&) = 0;
|
virtual void setLimits(const TBuiltInResource&) = 0;
|
||||||
|
|
||||||
@@ -149,8 +152,10 @@ public:
|
|||||||
extensionCallback(line, extension, behavior);
|
extensionCallback(line, extension, behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
|
// Manage the global uniform block (default uniforms in GLSL, $Global in HLSL)
|
||||||
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
|
virtual void growGlobalUniformBlock(const TSourceLoc&, TType&, const TString& memberName, TTypeList* typeList = nullptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Potentially rename shader entry point function
|
// Potentially rename shader entry point function
|
||||||
void renameShaderFunction(TString*& name) const
|
void renameShaderFunction(TString*& name) const
|
||||||
@@ -182,6 +187,8 @@ public:
|
|||||||
// the statementNestingLevel the current switch statement is at, which must match the level of its case statements
|
// the statementNestingLevel the current switch statement is at, which must match the level of its case statements
|
||||||
TList<int> switchLevel;
|
TList<int> switchLevel;
|
||||||
struct TPragma contextPragma;
|
struct TPragma contextPragma;
|
||||||
|
int beginInvocationInterlockCount;
|
||||||
|
int endInvocationInterlockCount;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TParseContextBase(TParseContextBase&);
|
TParseContextBase(TParseContextBase&);
|
||||||
@@ -276,7 +283,7 @@ public:
|
|||||||
const TString* entryPoint = nullptr);
|
const TString* entryPoint = nullptr);
|
||||||
virtual ~TParseContext();
|
virtual ~TParseContext();
|
||||||
|
|
||||||
bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); };
|
bool obeyPrecisionQualifiers() const { return precisionManager.respectingPrecisionQualifiers(); }
|
||||||
void setPrecisionDefaults();
|
void setPrecisionDefaults();
|
||||||
|
|
||||||
void setLimits(const TBuiltInResource&) override;
|
void setLimits(const TBuiltInResource&) override;
|
||||||
@@ -294,10 +301,12 @@ public:
|
|||||||
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
|
TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
|
||||||
void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
|
void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index);
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
void makeEditable(TSymbol*&) override;
|
void makeEditable(TSymbol*&) override;
|
||||||
|
void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
||||||
|
#endif
|
||||||
bool isIoResizeArray(const TType&) const;
|
bool isIoResizeArray(const TType&) const;
|
||||||
void fixIoArraySize(const TSourceLoc&, TType&);
|
void fixIoArraySize(const TSourceLoc&, TType&);
|
||||||
void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier);
|
|
||||||
void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
|
void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base);
|
||||||
void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false);
|
void checkIoArraysConsistency(const TSourceLoc&, bool tailOnly = false);
|
||||||
int getIoArrayImplicitSize(const TQualifier&, TString* featureString = nullptr) const;
|
int getIoArrayImplicitSize(const TQualifier&, TString* featureString = nullptr) const;
|
||||||
@@ -401,6 +410,7 @@ public:
|
|||||||
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&);
|
TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&);
|
||||||
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
|
TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&);
|
||||||
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
|
TIntermTyped* constructBuiltIn(const TType&, TOperator, TIntermTyped*, const TSourceLoc&, bool subset);
|
||||||
|
void inheritMemoryQualifiers(const TQualifier& from, TQualifier& to);
|
||||||
void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
|
void declareBlock(const TSourceLoc&, TTypeList& typeList, const TString* instanceName = 0, TArraySizes* arraySizes = 0);
|
||||||
void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
|
void blockStageIoCheck(const TSourceLoc&, const TQualifier&);
|
||||||
void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName);
|
void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName);
|
||||||
@@ -414,6 +424,7 @@ public:
|
|||||||
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode);
|
||||||
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
|
TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body);
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
TAttributeType attributeFromName(const TString& name) const;
|
TAttributeType attributeFromName(const TString& name) const;
|
||||||
TAttributes* makeAttributes(const TString& identifier) const;
|
TAttributes* makeAttributes(const TString& identifier) const;
|
||||||
TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const;
|
TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const;
|
||||||
@@ -422,11 +433,11 @@ public:
|
|||||||
// Determine selection control from attributes
|
// Determine selection control from attributes
|
||||||
void handleSelectionAttributes(const TAttributes& attributes, TIntermNode*);
|
void handleSelectionAttributes(const TAttributes& attributes, TIntermNode*);
|
||||||
void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*);
|
void handleSwitchAttributes(const TAttributes& attributes, TIntermNode*);
|
||||||
|
|
||||||
// Determine loop control from attributes
|
// Determine loop control from attributes
|
||||||
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
|
void handleLoopAttributes(const TAttributes& attributes, TIntermNode*);
|
||||||
|
#endif
|
||||||
|
|
||||||
void resizeMeshViewDimension(const TSourceLoc&, TType&);
|
void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
|
void nonInitConstCheck(const TSourceLoc&, TString& identifier, TType& type);
|
||||||
@@ -438,7 +449,9 @@ protected:
|
|||||||
bool isRuntimeLength(const TIntermTyped&) const;
|
bool isRuntimeLength(const TIntermTyped&) const;
|
||||||
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
|
TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable);
|
||||||
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
|
TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer);
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
void finish() override;
|
void finish() override;
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//
|
//
|
||||||
@@ -464,10 +477,11 @@ protected:
|
|||||||
TQualifier globalUniformDefaults;
|
TQualifier globalUniformDefaults;
|
||||||
TQualifier globalInputDefaults;
|
TQualifier globalInputDefaults;
|
||||||
TQualifier globalOutputDefaults;
|
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)
|
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;
|
bool anyIndexLimits;
|
||||||
|
TIdSetType inductiveLoopIds;
|
||||||
TVector<TIntermTyped*> needsIndexLimitationChecking;
|
TVector<TIntermTyped*> needsIndexLimitationChecking;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -503,6 +517,7 @@ protected:
|
|||||||
// array-sizing declarations
|
// array-sizing declarations
|
||||||
//
|
//
|
||||||
TVector<TSymbol*> ioArraySymbolResizeList;
|
TVector<TSymbol*> ioArraySymbolResizeList;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Executable → Regular
+88
-34
@@ -288,6 +288,11 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi
|
|||||||
EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable,
|
EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable,
|
||||||
TSymbolTable** symbolTables)
|
TSymbolTable** symbolTables)
|
||||||
{
|
{
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
profile = EEsProfile;
|
||||||
|
version = 310;
|
||||||
|
#endif
|
||||||
|
|
||||||
(*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]);
|
(*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]);
|
||||||
InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source,
|
InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source,
|
||||||
infoSink, *symbolTables[language]);
|
infoSink, *symbolTables[language]);
|
||||||
@@ -304,6 +309,11 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi
|
|||||||
//
|
//
|
||||||
bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables, int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
|
bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables, int version, EProfile profile, const SpvVersion& spvVersion, EShSource source)
|
||||||
{
|
{
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
profile = EEsProfile;
|
||||||
|
version = 310;
|
||||||
|
#endif
|
||||||
|
|
||||||
std::unique_ptr<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));
|
std::unique_ptr<TBuiltInParseables> builtInParseables(CreateBuiltInParseables(infoSink, source));
|
||||||
|
|
||||||
if (builtInParseables == nullptr)
|
if (builtInParseables == nullptr)
|
||||||
@@ -326,6 +336,7 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
|
|||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
// check for tessellation
|
// check for tessellation
|
||||||
if ((profile != EEsProfile && version >= 150) ||
|
if ((profile != EEsProfile && version >= 150) ||
|
||||||
(profile == EEsProfile && version >= 310)) {
|
(profile == EEsProfile && version >= 310)) {
|
||||||
@@ -340,6 +351,7 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
|
|||||||
(profile == EEsProfile && version >= 310))
|
(profile == EEsProfile && version >= 310))
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangGeometry, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
|
#endif
|
||||||
|
|
||||||
// check for compute
|
// check for compute
|
||||||
if ((profile != EEsProfile && version >= 420) ||
|
if ((profile != EEsProfile && version >= 420) ||
|
||||||
@@ -347,7 +359,6 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
|
|||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
// check for ray tracing stages
|
// check for ray tracing stages
|
||||||
if (profile != EEsProfile && version >= 450) {
|
if (profile != EEsProfile && version >= 450) {
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGenNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGenNV, source,
|
||||||
@@ -375,9 +386,6 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS
|
|||||||
(profile == EEsProfile && version >= 320))
|
(profile == EEsProfile && version >= 320))
|
||||||
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source,
|
InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source,
|
||||||
infoSink, commonTable, symbolTables);
|
infoSink, commonTable, symbolTables);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -479,11 +487,13 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp
|
|||||||
// Function to Print all builtins
|
// Function to Print all builtins
|
||||||
void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable)
|
void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable)
|
||||||
{
|
{
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
infoSink.debug << "BuiltinSymbolTable {\n";
|
infoSink.debug << "BuiltinSymbolTable {\n";
|
||||||
|
|
||||||
symbolTable.dump(infoSink, true);
|
symbolTable.dump(infoSink, true);
|
||||||
|
|
||||||
infoSink.debug << "}\n";
|
infoSink.debug << "}\n";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return true if the shader was correctly specified for version/profile/stage.
|
// Return true if the shader was correctly specified for version/profile/stage.
|
||||||
@@ -581,6 +591,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
// Correct for stage type...
|
// Correct for stage type...
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case EShLangGeometry:
|
case EShLangGeometry:
|
||||||
@@ -612,7 +623,6 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
|||||||
version = profile == EEsProfile ? 310 : 420;
|
version = profile == EEsProfile ? 310 : 420;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EShLangRayGenNV:
|
case EShLangRayGenNV:
|
||||||
case EShLangIntersectNV:
|
case EShLangIntersectNV:
|
||||||
case EShLangAnyHitNV:
|
case EShLangAnyHitNV:
|
||||||
@@ -633,7 +643,6 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
|||||||
infoSink.info.message(EPrefixError, "#version: mesh/task shaders require es profile with version 320 or above, or non-es profile with version 450 or above");
|
infoSink.info.message(EPrefixError, "#version: mesh/task shaders require es profile with version 320 or above, or non-es profile with version 450 or above");
|
||||||
version = profile == EEsProfile ? 320 : 450;
|
version = profile == EEsProfile ? 320 : 450;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -647,14 +656,9 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
|||||||
if (spvVersion.spv != 0) {
|
if (spvVersion.spv != 0) {
|
||||||
switch (profile) {
|
switch (profile) {
|
||||||
case EEsProfile:
|
case EEsProfile:
|
||||||
if (spvVersion.vulkan > 0 && version < 310) {
|
if (version < 310) {
|
||||||
correct = false;
|
correct = false;
|
||||||
infoSink.info.message(EPrefixError, "#version: ES shaders for Vulkan SPIR-V require version 310 or higher");
|
infoSink.info.message(EPrefixError, "#version: ES shaders for SPIR-V require version 310 or higher");
|
||||||
version = 310;
|
|
||||||
}
|
|
||||||
if (spvVersion.openGl >= 100) {
|
|
||||||
correct = false;
|
|
||||||
infoSink.info.message(EPrefixError, "#version: ES shaders for OpenGL SPIR-V are not supported");
|
|
||||||
version = 310;
|
version = 310;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -675,6 +679,7 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return correct;
|
return correct;
|
||||||
}
|
}
|
||||||
@@ -833,13 +838,17 @@ bool ProcessDeferred(
|
|||||||
|
|
||||||
// Get all the stages, languages, clients, and other environment
|
// Get all the stages, languages, clients, and other environment
|
||||||
// stuff sorted out.
|
// stuff sorted out.
|
||||||
EShSource source = (messages & EShMsgReadHlsl) != 0 ? EShSourceHlsl : EShSourceGlsl;
|
EShSource sourceGuess = (messages & EShMsgReadHlsl) != 0 ? EShSourceHlsl : EShSourceGlsl;
|
||||||
SpvVersion spvVersion;
|
SpvVersion spvVersion;
|
||||||
EShLanguage stage = compiler->getLanguage();
|
EShLanguage stage = compiler->getLanguage();
|
||||||
TranslateEnvironment(environment, messages, source, stage, spvVersion);
|
TranslateEnvironment(environment, messages, sourceGuess, stage, spvVersion);
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
|
EShSource source = sourceGuess;
|
||||||
if (environment != nullptr && environment->target.hlslFunctionality1)
|
if (environment != nullptr && environment->target.hlslFunctionality1)
|
||||||
intermediate.setHlslFunctionality1();
|
intermediate.setHlslFunctionality1();
|
||||||
|
#else
|
||||||
|
const EShSource source = EShSourceGlsl;
|
||||||
|
#endif
|
||||||
// First, without using the preprocessor or parser, find the #version, so we know what
|
// First, without using the preprocessor or parser, find the #version, so we know what
|
||||||
// symbol tables, processing rules, etc. to set up. This does not need the extra strings
|
// symbol tables, processing rules, etc. to set up. This does not need the extra strings
|
||||||
// outlined above, just the user shader, after the system and user preambles.
|
// outlined above, just the user shader, after the system and user preambles.
|
||||||
@@ -852,6 +861,7 @@ bool ProcessDeferred(
|
|||||||
: userInput.scanVersion(version, profile, versionNotFirstToken);
|
: userInput.scanVersion(version, profile, versionNotFirstToken);
|
||||||
bool versionNotFound = version == 0;
|
bool versionNotFound = version == 0;
|
||||||
if (forceDefaultVersionAndProfile && source == EShSourceGlsl) {
|
if (forceDefaultVersionAndProfile && source == EShSourceGlsl) {
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
|
if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound &&
|
||||||
(version != defaultVersion || profile != defaultProfile)) {
|
(version != defaultVersion || profile != defaultProfile)) {
|
||||||
compiler->infoSink.info << "Warning, (version, profile) forced to be ("
|
compiler->infoSink.info << "Warning, (version, profile) forced to be ("
|
||||||
@@ -859,7 +869,7 @@ bool ProcessDeferred(
|
|||||||
<< "), while in source code it is ("
|
<< "), while in source code it is ("
|
||||||
<< version << ", " << ProfileName(profile) << ")\n";
|
<< version << ", " << ProfileName(profile) << ")\n";
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (versionNotFound) {
|
if (versionNotFound) {
|
||||||
versionNotFirstToken = false;
|
versionNotFirstToken = false;
|
||||||
versionNotFirst = false;
|
versionNotFirst = false;
|
||||||
@@ -871,7 +881,13 @@ bool ProcessDeferred(
|
|||||||
|
|
||||||
bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage,
|
bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage,
|
||||||
versionNotFirst, defaultVersion, source, version, profile, spvVersion);
|
versionNotFirst, defaultVersion, source, version, profile, spvVersion);
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
profile = EEsProfile;
|
||||||
|
version = 310;
|
||||||
|
#endif
|
||||||
|
|
||||||
bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst));
|
bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst));
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
bool warnVersionNotFirst = false;
|
bool warnVersionNotFirst = false;
|
||||||
if (! versionWillBeError && versionNotFirstToken) {
|
if (! versionWillBeError && versionNotFirstToken) {
|
||||||
if (messages & EShMsgRelaxedErrors)
|
if (messages & EShMsgRelaxedErrors)
|
||||||
@@ -879,6 +895,7 @@ bool ProcessDeferred(
|
|||||||
else
|
else
|
||||||
versionWillBeError = true;
|
versionWillBeError = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
intermediate.setSource(source);
|
intermediate.setSource(source);
|
||||||
intermediate.setVersion(version);
|
intermediate.setVersion(version);
|
||||||
@@ -887,8 +904,10 @@ bool ProcessDeferred(
|
|||||||
RecordProcesses(intermediate, messages, sourceEntryPointName);
|
RecordProcesses(intermediate, messages, sourceEntryPointName);
|
||||||
if (spvVersion.vulkan > 0)
|
if (spvVersion.vulkan > 0)
|
||||||
intermediate.setOriginUpperLeft();
|
intermediate.setOriginUpperLeft();
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
if ((messages & EShMsgHlslOffsets) || source == EShSourceHlsl)
|
if ((messages & EShMsgHlslOffsets) || source == EShSourceHlsl)
|
||||||
intermediate.setHlslOffsets();
|
intermediate.setHlslOffsets();
|
||||||
|
#endif
|
||||||
if (messages & EShMsgDebugInfo) {
|
if (messages & EShMsgDebugInfo) {
|
||||||
intermediate.setSourceFile(names[numPre]);
|
intermediate.setSourceFile(names[numPre]);
|
||||||
for (int s = 0; s < numStrings; ++s) {
|
for (int s = 0; s < numStrings; ++s) {
|
||||||
@@ -938,11 +957,13 @@ bool ProcessDeferred(
|
|||||||
parseContext->setLimits(*resources);
|
parseContext->setLimits(*resources);
|
||||||
if (! goodVersion)
|
if (! goodVersion)
|
||||||
parseContext->addError();
|
parseContext->addError();
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (warnVersionNotFirst) {
|
if (warnVersionNotFirst) {
|
||||||
TSourceLoc loc;
|
TSourceLoc loc;
|
||||||
loc.init();
|
loc.init();
|
||||||
parseContext->warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", "");
|
parseContext->warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", "");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
parseContext->initializeExtensionBehavior();
|
parseContext->initializeExtensionBehavior();
|
||||||
|
|
||||||
@@ -973,6 +994,8 @@ bool ProcessDeferred(
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
// Responsible for keeping track of the most recent source string and line in
|
// Responsible for keeping track of the most recent source string and line in
|
||||||
// the preprocessor and outputting newlines appropriately if the source string
|
// the preprocessor and outputting newlines appropriately if the source string
|
||||||
// or line changes.
|
// or line changes.
|
||||||
@@ -1169,6 +1192,8 @@ struct DoPreprocessing {
|
|||||||
std::string* outputString;
|
std::string* outputString;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// DoFullParse is a valid ProcessingConext template argument for fully
|
// DoFullParse is a valid ProcessingConext template argument for fully
|
||||||
// parsing the shader. It populates the "intermediate" with the AST.
|
// parsing the shader. It populates the "intermediate" with the AST.
|
||||||
struct DoFullParse{
|
struct DoFullParse{
|
||||||
@@ -1199,6 +1224,7 @@ struct DoFullParse{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
// Take a single compilation unit, and run the preprocessor on it.
|
// Take a single compilation unit, and run the preprocessor on it.
|
||||||
// Return: True if there were no issues found in preprocessing,
|
// Return: True if there were no issues found in preprocessing,
|
||||||
// False if during preprocessing any unknown version, pragmas or
|
// False if during preprocessing any unknown version, pragmas or
|
||||||
@@ -1231,6 +1257,7 @@ bool PreprocessDeferred(
|
|||||||
forwardCompatible, messages, intermediate, parser,
|
forwardCompatible, messages, intermediate, parser,
|
||||||
false, includer);
|
false, includer);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// do a partial compile on the given strings for a single compilation unit
|
// do a partial compile on the given strings for a single compilation unit
|
||||||
@@ -1749,6 +1776,11 @@ void TShader::addProcesses(const std::vector<std::string>& p)
|
|||||||
intermediate->addProcesses(p);
|
intermediate->addProcesses(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
|
||||||
|
void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); }
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
// Set binding base for given resource type
|
// Set binding base for given resource type
|
||||||
void TShader::setShiftBinding(TResourceType res, unsigned int base) {
|
void TShader::setShiftBinding(TResourceType res, unsigned int base) {
|
||||||
intermediate->setShiftBinding(res, base);
|
intermediate->setShiftBinding(res, base);
|
||||||
@@ -1776,7 +1808,7 @@ void TShader::setShiftSsboBinding(unsigned int base) { setShiftBinding(EResSs
|
|||||||
// Enables binding automapping using TIoMapper
|
// Enables binding automapping using TIoMapper
|
||||||
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
|
void TShader::setAutoMapBindings(bool map) { intermediate->setAutoMapBindings(map); }
|
||||||
// Enables position.Y output negation in vertex shader
|
// Enables position.Y output negation in vertex shader
|
||||||
void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); }
|
|
||||||
// Fragile: currently within one stage: simple auto-assignment of location
|
// Fragile: currently within one stage: simple auto-assignment of location
|
||||||
void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); }
|
void TShader::setAutoMapLocations(bool map) { intermediate->setAutoMapLocations(map); }
|
||||||
void TShader::addUniformLocationOverride(const char* name, int loc)
|
void TShader::addUniformLocationOverride(const char* name, int loc)
|
||||||
@@ -1787,12 +1819,16 @@ void TShader::setUniformLocationBase(int base)
|
|||||||
{
|
{
|
||||||
intermediate->setUniformLocationBase(base);
|
intermediate->setUniformLocationBase(base);
|
||||||
}
|
}
|
||||||
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
|
|
||||||
void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
|
|
||||||
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
|
|
||||||
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
|
void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); }
|
||||||
void TShader::setResourceSetBinding(const std::vector<std::string>& base) { intermediate->setResourceSetBinding(base); }
|
void TShader::setResourceSetBinding(const std::vector<std::string>& base) { intermediate->setResourceSetBinding(base); }
|
||||||
void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
|
void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
|
// See comment above TDefaultHlslIoMapper in iomapper.cpp:
|
||||||
|
void TShader::setHlslIoMapping(bool hlslIoMap) { intermediate->setHlslIoMapping(hlslIoMap); }
|
||||||
|
void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlattenUniformArrays(flatten); }
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Turn the shader strings into a parse tree in the TIntermediate.
|
// Turn the shader strings into a parse tree in the TIntermediate.
|
||||||
@@ -1816,6 +1852,7 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion
|
|||||||
&environment);
|
&environment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
// Fill in a string with the result of preprocessing ShaderStrings
|
// Fill in a string with the result of preprocessing ShaderStrings
|
||||||
// Returns true if all extensions, pragmas and version strings were valid.
|
// Returns true if all extensions, pragmas and version strings were valid.
|
||||||
//
|
//
|
||||||
@@ -1840,6 +1877,7 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources,
|
|||||||
defaultProfile, forceDefaultVersionAndProfile,
|
defaultProfile, forceDefaultVersionAndProfile,
|
||||||
forwardCompatible, message, includer, *intermediate, output_string);
|
forwardCompatible, message, includer, *intermediate, output_string);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
const char* TShader::getInfoLog()
|
const char* TShader::getInfoLog()
|
||||||
{
|
{
|
||||||
@@ -1851,7 +1889,11 @@ const char* TShader::getInfoDebugLog()
|
|||||||
return infoSink->debug.c_str();
|
return infoSink->debug.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
TProgram::TProgram() : reflection(0), ioMapper(nullptr), linked(false)
|
TProgram::TProgram() :
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
reflection(0),
|
||||||
|
#endif
|
||||||
|
linked(false)
|
||||||
{
|
{
|
||||||
pool = new TPoolAllocator;
|
pool = new TPoolAllocator;
|
||||||
infoSink = new TInfoSink;
|
infoSink = new TInfoSink;
|
||||||
@@ -1863,9 +1905,10 @@ TProgram::TProgram() : reflection(0), ioMapper(nullptr), linked(false)
|
|||||||
|
|
||||||
TProgram::~TProgram()
|
TProgram::~TProgram()
|
||||||
{
|
{
|
||||||
delete ioMapper;
|
|
||||||
delete infoSink;
|
delete infoSink;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
delete reflection;
|
delete reflection;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int s = 0; s < EShLangCount; ++s)
|
for (int s = 0; s < EShLangCount; ++s)
|
||||||
if (newedIntermediate[s])
|
if (newedIntermediate[s])
|
||||||
@@ -1910,6 +1953,7 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
|
|||||||
if (stages[stage].size() == 0)
|
if (stages[stage].size() == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
int numEsShaders = 0, numNonEsShaders = 0;
|
int numEsShaders = 0, numNonEsShaders = 0;
|
||||||
for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) {
|
for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) {
|
||||||
if ((*it)->intermediate->getProfile() == EEsProfile) {
|
if ((*it)->intermediate->getProfile() == EEsProfile) {
|
||||||
@@ -1958,7 +2002,9 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages)
|
|||||||
for (it = stages[stage].begin(); it != stages[stage].end(); ++it)
|
for (it = stages[stage].begin(); it != stages[stage].end(); ++it)
|
||||||
intermediate[stage]->merge(*infoSink, *(*it)->intermediate);
|
intermediate[stage]->merge(*infoSink, *(*it)->intermediate);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
intermediate[stage] = stages[stage].front()->intermediate;
|
||||||
|
#endif
|
||||||
intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0);
|
intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0);
|
||||||
|
|
||||||
if (messages & EShMsgAST)
|
if (messages & EShMsgAST)
|
||||||
@@ -1977,13 +2023,15 @@ const char* TProgram::getInfoDebugLog()
|
|||||||
return infoSink->debug.c_str();
|
return infoSink->debug.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
//
|
//
|
||||||
// Reflection implementation.
|
// Reflection implementation.
|
||||||
//
|
//
|
||||||
|
|
||||||
bool TProgram::buildReflection(int opts)
|
bool TProgram::buildReflection(int opts)
|
||||||
{
|
{
|
||||||
if (! linked || reflection)
|
if (! linked || reflection != nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int firstStage = EShLangVertex, lastStage = EShLangFragment;
|
int firstStage = EShLangVertex, lastStage = EShLangFragment;
|
||||||
@@ -2015,6 +2063,8 @@ bool TProgram::buildReflection(int opts)
|
|||||||
|
|
||||||
unsigned TProgram::getLocalSize(int dim) const { return reflection->getLocalSize(dim); }
|
unsigned TProgram::getLocalSize(int dim) const { return reflection->getLocalSize(dim); }
|
||||||
int TProgram::getReflectionIndex(const char* name) const { return reflection->getIndex(name); }
|
int TProgram::getReflectionIndex(const char* name) const { return reflection->getIndex(name); }
|
||||||
|
int TProgram::getReflectionPipeIOIndex(const char* name, const bool inOrOut) const
|
||||||
|
{ return reflection->getPipeIOIndex(name, inOrOut); }
|
||||||
|
|
||||||
int TProgram::getNumUniformVariables() const { return reflection->getNumUniforms(); }
|
int TProgram::getNumUniformVariables() const { return reflection->getNumUniforms(); }
|
||||||
const TObjectReflection& TProgram::getUniform(int index) const { return reflection->getUniform(index); }
|
const TObjectReflection& TProgram::getUniform(int index) const { return reflection->getUniform(index); }
|
||||||
@@ -2030,27 +2080,31 @@ int TProgram::getNumBufferBlocks() const { return r
|
|||||||
const TObjectReflection& TProgram::getBufferBlock(int index) const { return reflection->getStorageBufferBlock(index); }
|
const TObjectReflection& TProgram::getBufferBlock(int index) const { return reflection->getStorageBufferBlock(index); }
|
||||||
int TProgram::getNumAtomicCounters() const { return reflection->getNumAtomicCounters(); }
|
int TProgram::getNumAtomicCounters() const { return reflection->getNumAtomicCounters(); }
|
||||||
const TObjectReflection& TProgram::getAtomicCounter(int index) const { return reflection->getAtomicCounter(index); }
|
const TObjectReflection& TProgram::getAtomicCounter(int index) const { return reflection->getAtomicCounter(index); }
|
||||||
|
void TProgram::dumpReflection() { if (reflection != nullptr) reflection->dump(); }
|
||||||
void TProgram::dumpReflection() { reflection->dump(); }
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// I/O mapping implementation.
|
// I/O mapping implementation.
|
||||||
//
|
//
|
||||||
bool TProgram::mapIO(TIoMapResolver* resolver)
|
bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper)
|
||||||
{
|
{
|
||||||
if (! linked || ioMapper)
|
if (! linked)
|
||||||
return false;
|
return false;
|
||||||
|
TIoMapper* ioMapper = nullptr;
|
||||||
ioMapper = new TIoMapper;
|
TIoMapper defaultIOMapper;
|
||||||
|
if (pIoMapper == nullptr)
|
||||||
|
ioMapper = &defaultIOMapper;
|
||||||
|
else
|
||||||
|
ioMapper = pIoMapper;
|
||||||
for (int s = 0; s < EShLangCount; ++s) {
|
for (int s = 0; s < EShLangCount; ++s) {
|
||||||
if (intermediate[s]) {
|
if (intermediate[s]) {
|
||||||
if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, resolver))
|
if (! ioMapper->addStage((EShLanguage)s, *intermediate[s], *infoSink, pResolver))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return ioMapper->doMap(pResolver, *infoSink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // GLSLANG_WEB
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|||||||
Executable → Regular
+25
-17
@@ -61,63 +61,66 @@ void TType::buildMangledName(TString& mangledName) const
|
|||||||
|
|
||||||
switch (basicType) {
|
switch (basicType) {
|
||||||
case EbtFloat: mangledName += 'f'; break;
|
case EbtFloat: mangledName += 'f'; break;
|
||||||
case EbtDouble: mangledName += 'd'; break;
|
|
||||||
case EbtFloat16: mangledName += "f16"; break;
|
|
||||||
case EbtInt: mangledName += 'i'; break;
|
case EbtInt: mangledName += 'i'; break;
|
||||||
case EbtUint: mangledName += 'u'; break;
|
case EbtUint: mangledName += 'u'; break;
|
||||||
|
case EbtBool: mangledName += 'b'; break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
case EbtDouble: mangledName += 'd'; break;
|
||||||
|
case EbtFloat16: mangledName += "f16"; break;
|
||||||
case EbtInt8: mangledName += "i8"; break;
|
case EbtInt8: mangledName += "i8"; break;
|
||||||
case EbtUint8: mangledName += "u8"; break;
|
case EbtUint8: mangledName += "u8"; break;
|
||||||
case EbtInt16: mangledName += "i16"; break;
|
case EbtInt16: mangledName += "i16"; break;
|
||||||
case EbtUint16: mangledName += "u16"; break;
|
case EbtUint16: mangledName += "u16"; break;
|
||||||
case EbtInt64: mangledName += "i64"; break;
|
case EbtInt64: mangledName += "i64"; break;
|
||||||
case EbtUint64: mangledName += "u64"; break;
|
case EbtUint64: mangledName += "u64"; break;
|
||||||
case EbtBool: mangledName += 'b'; break;
|
|
||||||
case EbtAtomicUint: mangledName += "au"; break;
|
case EbtAtomicUint: mangledName += "au"; break;
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EbtAccStructNV: mangledName += "asnv"; break;
|
case EbtAccStructNV: mangledName += "asnv"; break;
|
||||||
#endif
|
#endif
|
||||||
case EbtSampler:
|
case EbtSampler:
|
||||||
switch (sampler.type) {
|
switch (sampler.type) {
|
||||||
#ifdef AMD_EXTENSIONS
|
#ifndef GLSLANG_WEB
|
||||||
case EbtFloat16: mangledName += "f16"; break;
|
case EbtFloat16: mangledName += "f16"; break;
|
||||||
#endif
|
#endif
|
||||||
case EbtInt: mangledName += "i"; break;
|
case EbtInt: mangledName += "i"; break;
|
||||||
case EbtUint: mangledName += "u"; break;
|
case EbtUint: mangledName += "u"; break;
|
||||||
default: break; // some compilers want this
|
default: break; // some compilers want this
|
||||||
}
|
}
|
||||||
if (sampler.image)
|
if (sampler.isImageClass())
|
||||||
mangledName += "I"; // a normal image
|
mangledName += "I"; // a normal image or subpass
|
||||||
else if (sampler.sampler)
|
else if (sampler.isPureSampler())
|
||||||
mangledName += "p"; // a "pure" sampler
|
mangledName += "p"; // a "pure" sampler
|
||||||
else if (!sampler.combined)
|
else if (!sampler.isCombined())
|
||||||
mangledName += "t"; // a "pure" texture
|
mangledName += "t"; // a "pure" texture
|
||||||
else
|
else
|
||||||
mangledName += "s"; // traditional combined sampler
|
mangledName += "s"; // traditional combined sampler
|
||||||
if (sampler.arrayed)
|
if (sampler.isArrayed())
|
||||||
mangledName += "A";
|
mangledName += "A";
|
||||||
if (sampler.shadow)
|
if (sampler.isShadow())
|
||||||
mangledName += "S";
|
mangledName += "S";
|
||||||
if (sampler.external)
|
if (sampler.isExternal())
|
||||||
mangledName += "E";
|
mangledName += "E";
|
||||||
if (sampler.yuv)
|
if (sampler.isYuv())
|
||||||
mangledName += "Y";
|
mangledName += "Y";
|
||||||
switch (sampler.dim) {
|
switch (sampler.dim) {
|
||||||
case Esd1D: mangledName += "1"; break;
|
|
||||||
case Esd2D: mangledName += "2"; break;
|
case Esd2D: mangledName += "2"; break;
|
||||||
case Esd3D: mangledName += "3"; break;
|
case Esd3D: mangledName += "3"; break;
|
||||||
case EsdCube: mangledName += "C"; break;
|
case EsdCube: mangledName += "C"; break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
case Esd1D: mangledName += "1"; break;
|
||||||
case EsdRect: mangledName += "R2"; break;
|
case EsdRect: mangledName += "R2"; break;
|
||||||
case EsdBuffer: mangledName += "B"; break;
|
case EsdBuffer: mangledName += "B"; break;
|
||||||
case EsdSubpass: mangledName += "P"; break;
|
case EsdSubpass: mangledName += "P"; break;
|
||||||
|
#endif
|
||||||
default: break; // some compilers want this
|
default: break; // some compilers want this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
if (sampler.hasReturnStruct()) {
|
if (sampler.hasReturnStruct()) {
|
||||||
// Name mangle for sampler return struct uses struct table index.
|
// Name mangle for sampler return struct uses struct table index.
|
||||||
mangledName += "-tx-struct";
|
mangledName += "-tx-struct";
|
||||||
|
|
||||||
char text[16]; // plenty enough space for the small integers.
|
char text[16]; // plenty enough space for the small integers.
|
||||||
snprintf(text, sizeof(text), "%d-", sampler.structReturnIndex);
|
snprintf(text, sizeof(text), "%d-", sampler.getStructReturnIndex());
|
||||||
mangledName += text;
|
mangledName += text;
|
||||||
} else {
|
} else {
|
||||||
switch (sampler.getVectorSize()) {
|
switch (sampler.getVectorSize()) {
|
||||||
@@ -127,8 +130,9 @@ void TType::buildMangledName(TString& mangledName) const
|
|||||||
case 4: break; // default to prior name mangle behavior
|
case 4: break; // default to prior name mangle behavior
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (sampler.ms)
|
if (sampler.isMultiSample())
|
||||||
mangledName += "M";
|
mangledName += "M";
|
||||||
break;
|
break;
|
||||||
case EbtStruct:
|
case EbtStruct:
|
||||||
@@ -172,6 +176,8 @@ void TType::buildMangledName(TString& mangledName) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
//
|
//
|
||||||
// Dump functions.
|
// Dump functions.
|
||||||
//
|
//
|
||||||
@@ -229,7 +235,7 @@ void TFunction::dump(TInfoSink& infoSink, bool complete) const
|
|||||||
infoSink.debug << "\n";
|
infoSink.debug << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void TAnonMember::dump(TInfoSink& TInfoSink, bool complete) const
|
void TAnonMember::dump(TInfoSink& TInfoSink, bool) const
|
||||||
{
|
{
|
||||||
TInfoSink.debug << "anonymous member " << getMemberNumber() << " of " << getAnonContainer().getName().c_str()
|
TInfoSink.debug << "anonymous member " << getMemberNumber() << " of " << getAnonContainer().getName().c_str()
|
||||||
<< "\n";
|
<< "\n";
|
||||||
@@ -250,6 +256,8 @@ void TSymbolTable::dump(TInfoSink& infoSink, bool complete) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Functions have buried pointers to delete.
|
// Functions have buried pointers to delete.
|
||||||
//
|
//
|
||||||
|
|||||||
Executable → Regular
+13
@@ -116,8 +116,11 @@ public:
|
|||||||
}
|
}
|
||||||
virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); }
|
virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); }
|
||||||
virtual const char** getExtensions() const { return extensions->data(); }
|
virtual const char** getExtensions() const { return extensions->data(); }
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0;
|
virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0;
|
||||||
void dumpExtensions(TInfoSink& infoSink) const;
|
void dumpExtensions(TInfoSink& infoSink) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual bool isReadOnly() const { return ! writable; }
|
virtual bool isReadOnly() const { return ! writable; }
|
||||||
virtual void makeReadOnly() { writable = false; }
|
virtual void makeReadOnly() { writable = false; }
|
||||||
@@ -193,7 +196,9 @@ public:
|
|||||||
}
|
}
|
||||||
virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); }
|
virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); }
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
virtual void dump(TInfoSink& infoSink, bool complete = false) const;
|
virtual void dump(TInfoSink& infoSink, bool complete = false) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit TVariable(const TVariable&);
|
explicit TVariable(const TVariable&);
|
||||||
@@ -314,7 +319,9 @@ public:
|
|||||||
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
|
||||||
virtual const TParameter& operator[](int i) const { 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;
|
virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit TFunction(const TFunction&);
|
explicit TFunction(const TFunction&);
|
||||||
@@ -374,7 +381,9 @@ public:
|
|||||||
virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); }
|
virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); }
|
||||||
|
|
||||||
virtual int getAnonId() const { return anonId; }
|
virtual int getAnonId() const { return anonId; }
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
|
virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit TAnonMember(const TAnonMember&);
|
explicit TAnonMember(const TAnonMember&);
|
||||||
@@ -542,7 +551,9 @@ public:
|
|||||||
|
|
||||||
void relateToOperator(const char* name, TOperator op);
|
void relateToOperator(const char* name, TOperator op);
|
||||||
void setFunctionExtensions(const char* name, int num, const char* const extensions[]);
|
void setFunctionExtensions(const char* name, int num, const char* const extensions[]);
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
void dump(TInfoSink& infoSink, bool complete = false) const;
|
void dump(TInfoSink& infoSink, bool complete = false) const;
|
||||||
|
#endif
|
||||||
TSymbolTableLevel* clone() const;
|
TSymbolTableLevel* clone() const;
|
||||||
void readOnly();
|
void readOnly();
|
||||||
|
|
||||||
@@ -843,7 +854,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int getMaxSymbolId() { return uniqueId; }
|
int getMaxSymbolId() { return uniqueId; }
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
void dump(TInfoSink& infoSink, bool complete = false) const;
|
void dump(TInfoSink& infoSink, bool complete = false) const;
|
||||||
|
#endif
|
||||||
void copyTable(const TSymbolTable& copyOf);
|
void copyTable(const TSymbolTable& copyOf);
|
||||||
|
|
||||||
void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); }
|
void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); }
|
||||||
|
|||||||
@@ -145,6 +145,8 @@
|
|||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
//
|
//
|
||||||
// Initialize all extensions, almost always to 'disable', as once their features
|
// Initialize all extensions, almost always to 'disable', as once their features
|
||||||
// are incorporated into a core version, their features are supported through allowing that
|
// are incorporated into a core version, their features are supported through allowing that
|
||||||
@@ -171,8 +173,10 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_ARB_tessellation_shader] = EBhDisable;
|
extensionBehavior[E_GL_ARB_tessellation_shader] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_enhanced_layouts] = EBhDisable;
|
extensionBehavior[E_GL_ARB_enhanced_layouts] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_texture_cube_map_array] = EBhDisable;
|
extensionBehavior[E_GL_ARB_texture_cube_map_array] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_ARB_texture_multisample] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_shader_texture_lod] = EBhDisable;
|
extensionBehavior[E_GL_ARB_shader_texture_lod] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_explicit_attrib_location] = EBhDisable;
|
extensionBehavior[E_GL_ARB_explicit_attrib_location] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_ARB_explicit_uniform_location] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_shader_image_load_store] = EBhDisable;
|
extensionBehavior[E_GL_ARB_shader_image_load_store] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_shader_atomic_counters] = EBhDisable;
|
extensionBehavior[E_GL_ARB_shader_atomic_counters] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_shader_draw_parameters] = EBhDisable;
|
extensionBehavior[E_GL_ARB_shader_draw_parameters] = EBhDisable;
|
||||||
@@ -181,6 +185,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_ARB_shader_texture_image_samples] = EBhDisable;
|
extensionBehavior[E_GL_ARB_shader_texture_image_samples] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_viewport_array] = EBhDisable;
|
extensionBehavior[E_GL_ARB_viewport_array] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_gpu_shader_int64] = EBhDisable;
|
extensionBehavior[E_GL_ARB_gpu_shader_int64] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_ARB_gpu_shader_fp64] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_shader_ballot] = EBhDisable;
|
extensionBehavior[E_GL_ARB_shader_ballot] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_sparse_texture2] = EBhDisable;
|
extensionBehavior[E_GL_ARB_sparse_texture2] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_sparse_texture_clamp] = EBhDisable;
|
extensionBehavior[E_GL_ARB_sparse_texture_clamp] = EBhDisable;
|
||||||
@@ -188,6 +193,10 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
// extensionBehavior[E_GL_ARB_cull_distance] = EBhDisable; // present for 4.5, but need extension control over block members
|
// extensionBehavior[E_GL_ARB_cull_distance] = EBhDisable; // present for 4.5, but need extension control over block members
|
||||||
extensionBehavior[E_GL_ARB_post_depth_coverage] = EBhDisable;
|
extensionBehavior[E_GL_ARB_post_depth_coverage] = EBhDisable;
|
||||||
extensionBehavior[E_GL_ARB_shader_viewport_layer_array] = EBhDisable;
|
extensionBehavior[E_GL_ARB_shader_viewport_layer_array] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_ARB_fragment_shader_interlock] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_ARB_shader_clock] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_ARB_uniform_buffer_object] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_ARB_sample_shading] = EBhDisable;
|
||||||
|
|
||||||
extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable;
|
extensionBehavior[E_GL_KHR_shader_subgroup_basic] = EBhDisable;
|
||||||
extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable;
|
extensionBehavior[E_GL_KHR_shader_subgroup_vote] = EBhDisable;
|
||||||
@@ -211,6 +220,8 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_EXT_fragment_invocation_density] = EBhDisable;
|
extensionBehavior[E_GL_EXT_fragment_invocation_density] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_buffer_reference] = EBhDisable;
|
extensionBehavior[E_GL_EXT_buffer_reference] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_buffer_reference2] = EBhDisable;
|
extensionBehavior[E_GL_EXT_buffer_reference2] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_buffer_reference_uvec2] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_demote_to_helper_invocation] = EBhDisable;
|
||||||
|
|
||||||
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_16bit_storage] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable;
|
||||||
@@ -219,7 +230,6 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
|
extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable;
|
||||||
extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable;
|
extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable;
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
extensionBehavior[E_GL_AMD_shader_ballot] = EBhDisable;
|
extensionBehavior[E_GL_AMD_shader_ballot] = EBhDisable;
|
||||||
extensionBehavior[E_GL_AMD_shader_trinary_minmax] = EBhDisable;
|
extensionBehavior[E_GL_AMD_shader_trinary_minmax] = EBhDisable;
|
||||||
extensionBehavior[E_GL_AMD_shader_explicit_vertex_parameter] = EBhDisable;
|
extensionBehavior[E_GL_AMD_shader_explicit_vertex_parameter] = EBhDisable;
|
||||||
@@ -230,9 +240,9 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_AMD_shader_image_load_store_lod] = EBhDisable;
|
extensionBehavior[E_GL_AMD_shader_image_load_store_lod] = EBhDisable;
|
||||||
extensionBehavior[E_GL_AMD_shader_fragment_mask] = EBhDisable;
|
extensionBehavior[E_GL_AMD_shader_fragment_mask] = EBhDisable;
|
||||||
extensionBehavior[E_GL_AMD_gpu_shader_half_float_fetch] = EBhDisable;
|
extensionBehavior[E_GL_AMD_gpu_shader_half_float_fetch] = EBhDisable;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
extensionBehavior[E_GL_INTEL_shader_integer_functions2] = EBhDisable;
|
||||||
|
|
||||||
extensionBehavior[E_GL_NV_sample_mask_override_coverage] = EBhDisable;
|
extensionBehavior[E_GL_NV_sample_mask_override_coverage] = EBhDisable;
|
||||||
extensionBehavior[E_SPV_NV_geometry_shader_passthrough] = EBhDisable;
|
extensionBehavior[E_SPV_NV_geometry_shader_passthrough] = EBhDisable;
|
||||||
extensionBehavior[E_GL_NV_viewport_array2] = EBhDisable;
|
extensionBehavior[E_GL_NV_viewport_array2] = EBhDisable;
|
||||||
@@ -248,9 +258,10 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable;
|
extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable;
|
||||||
extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable;
|
extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable;
|
||||||
extensionBehavior[E_GL_NV_mesh_shader] = EBhDisable;
|
extensionBehavior[E_GL_NV_mesh_shader] = EBhDisable;
|
||||||
#endif
|
|
||||||
|
|
||||||
extensionBehavior[E_GL_NV_cooperative_matrix] = EBhDisable;
|
extensionBehavior[E_GL_NV_cooperative_matrix] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_shader_sm_builtins] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_NV_integer_cooperative_matrix] = EBhDisable;
|
||||||
|
|
||||||
// AEP
|
// AEP
|
||||||
extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable;
|
extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable;
|
||||||
@@ -283,6 +294,7 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
// EXT extensions
|
// EXT extensions
|
||||||
extensionBehavior[E_GL_EXT_device_group] = EBhDisable;
|
extensionBehavior[E_GL_EXT_device_group] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_multiview] = EBhDisable;
|
extensionBehavior[E_GL_EXT_multiview] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_shader_realtime_clock] = EBhDisable;
|
||||||
|
|
||||||
// OVR extensions
|
// OVR extensions
|
||||||
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
|
extensionBehavior[E_GL_OVR_multiview] = EBhDisable;
|
||||||
@@ -297,16 +309,26 @@ void TParseVersions::initializeExtensionBehavior()
|
|||||||
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float16] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float16] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float32] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float32] = EBhDisable;
|
||||||
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float64] = EBhDisable;
|
extensionBehavior[E_GL_EXT_shader_explicit_arithmetic_types_float64] = EBhDisable;
|
||||||
|
|
||||||
|
// subgroup extended types
|
||||||
|
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int8] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int16] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_int64] = EBhDisable;
|
||||||
|
extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_float16] = EBhDisable;
|
||||||
}
|
}
|
||||||
|
#endif // GLSLANG_WEB
|
||||||
|
|
||||||
// Get code that is not part of a shared symbol table, is specific to this shader,
|
// Get code that is not part of a shared symbol table, is specific to this shader,
|
||||||
// or needed by the preprocessor (which does not use a shared symbol table).
|
// or needed by the preprocessor (which does not use a shared symbol table).
|
||||||
void TParseVersions::getPreamble(std::string& preamble)
|
void TParseVersions::getPreamble(std::string& preamble)
|
||||||
{
|
{
|
||||||
if (profile == EEsProfile) {
|
if (isEsProfile()) {
|
||||||
preamble =
|
preamble =
|
||||||
"#define GL_ES 1\n"
|
"#define GL_ES 1\n"
|
||||||
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
|
"#define GL_FRAGMENT_PRECISION_HIGH 1\n"
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
;
|
||||||
|
#else
|
||||||
"#define GL_EXT_texture_array 1\n"
|
"#define GL_EXT_texture_array 1\n"
|
||||||
"#define GL_OES_texture_3D 1\n"
|
"#define GL_OES_texture_3D 1\n"
|
||||||
"#define GL_OES_standard_derivatives 1\n"
|
"#define GL_OES_standard_derivatives 1\n"
|
||||||
@@ -319,7 +341,6 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
|
|
||||||
// AEP
|
// AEP
|
||||||
"#define GL_ANDROID_extension_pack_es31a 1\n"
|
"#define GL_ANDROID_extension_pack_es31a 1\n"
|
||||||
"#define GL_KHR_blend_equation_advanced 1\n"
|
|
||||||
"#define GL_OES_sample_variables 1\n"
|
"#define GL_OES_sample_variables 1\n"
|
||||||
"#define GL_OES_shader_image_atomic 1\n"
|
"#define GL_OES_shader_image_atomic 1\n"
|
||||||
"#define GL_OES_shader_multisample_interpolation 1\n"
|
"#define GL_OES_shader_multisample_interpolation 1\n"
|
||||||
@@ -347,11 +368,9 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
if (isEsProfile() && version >= 300) {
|
||||||
if (profile == EEsProfile && version >= 300) {
|
|
||||||
preamble += "#define GL_NV_shader_noperspective_interpolation 1\n";
|
preamble += "#define GL_NV_shader_noperspective_interpolation 1\n";
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
preamble =
|
preamble =
|
||||||
@@ -366,8 +385,10 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_ARB_tessellation_shader 1\n"
|
"#define GL_ARB_tessellation_shader 1\n"
|
||||||
"#define GL_ARB_enhanced_layouts 1\n"
|
"#define GL_ARB_enhanced_layouts 1\n"
|
||||||
"#define GL_ARB_texture_cube_map_array 1\n"
|
"#define GL_ARB_texture_cube_map_array 1\n"
|
||||||
|
"#define GL_ARB_texture_multisample 1\n"
|
||||||
"#define GL_ARB_shader_texture_lod 1\n"
|
"#define GL_ARB_shader_texture_lod 1\n"
|
||||||
"#define GL_ARB_explicit_attrib_location 1\n"
|
"#define GL_ARB_explicit_attrib_location 1\n"
|
||||||
|
"#define GL_ARB_explicit_uniform_location 1\n"
|
||||||
"#define GL_ARB_shader_image_load_store 1\n"
|
"#define GL_ARB_shader_image_load_store 1\n"
|
||||||
"#define GL_ARB_shader_atomic_counters 1\n"
|
"#define GL_ARB_shader_atomic_counters 1\n"
|
||||||
"#define GL_ARB_shader_draw_parameters 1\n"
|
"#define GL_ARB_shader_draw_parameters 1\n"
|
||||||
@@ -376,12 +397,16 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_ARB_shader_texture_image_samples 1\n"
|
"#define GL_ARB_shader_texture_image_samples 1\n"
|
||||||
"#define GL_ARB_viewport_array 1\n"
|
"#define GL_ARB_viewport_array 1\n"
|
||||||
"#define GL_ARB_gpu_shader_int64 1\n"
|
"#define GL_ARB_gpu_shader_int64 1\n"
|
||||||
|
"#define GL_ARB_gpu_shader_fp64 1\n"
|
||||||
"#define GL_ARB_shader_ballot 1\n"
|
"#define GL_ARB_shader_ballot 1\n"
|
||||||
"#define GL_ARB_sparse_texture2 1\n"
|
"#define GL_ARB_sparse_texture2 1\n"
|
||||||
"#define GL_ARB_sparse_texture_clamp 1\n"
|
"#define GL_ARB_sparse_texture_clamp 1\n"
|
||||||
"#define GL_ARB_shader_stencil_export 1\n"
|
"#define GL_ARB_shader_stencil_export 1\n"
|
||||||
|
"#define GL_ARB_sample_shading 1\n"
|
||||||
// "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members
|
// "#define GL_ARB_cull_distance 1\n" // present for 4.5, but need extension control over block members
|
||||||
"#define GL_ARB_post_depth_coverage 1\n"
|
"#define GL_ARB_post_depth_coverage 1\n"
|
||||||
|
"#define GL_ARB_fragment_shader_interlock 1\n"
|
||||||
|
"#define GL_ARB_uniform_buffer_object 1\n"
|
||||||
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
"#define GL_EXT_shader_non_constant_global_initializers 1\n"
|
||||||
"#define GL_EXT_shader_image_load_formatted 1\n"
|
"#define GL_EXT_shader_image_load_formatted 1\n"
|
||||||
"#define GL_EXT_post_depth_coverage 1\n"
|
"#define GL_EXT_post_depth_coverage 1\n"
|
||||||
@@ -394,6 +419,8 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_EXT_fragment_invocation_density 1\n"
|
"#define GL_EXT_fragment_invocation_density 1\n"
|
||||||
"#define GL_EXT_buffer_reference 1\n"
|
"#define GL_EXT_buffer_reference 1\n"
|
||||||
"#define GL_EXT_buffer_reference2 1\n"
|
"#define GL_EXT_buffer_reference2 1\n"
|
||||||
|
"#define GL_EXT_buffer_reference_uvec2 1\n"
|
||||||
|
"#define GL_EXT_demote_to_helper_invocation 1\n"
|
||||||
|
|
||||||
// GL_KHR_shader_subgroup
|
// GL_KHR_shader_subgroup
|
||||||
"#define GL_KHR_shader_subgroup_basic 1\n"
|
"#define GL_KHR_shader_subgroup_basic 1\n"
|
||||||
@@ -406,8 +433,8 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_KHR_shader_subgroup_quad 1\n"
|
"#define GL_KHR_shader_subgroup_quad 1\n"
|
||||||
|
|
||||||
"#define E_GL_EXT_shader_atomic_int64 1\n"
|
"#define E_GL_EXT_shader_atomic_int64 1\n"
|
||||||
|
"#define E_GL_EXT_shader_realtime_clock 1\n"
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
"#define GL_AMD_shader_ballot 1\n"
|
"#define GL_AMD_shader_ballot 1\n"
|
||||||
"#define GL_AMD_shader_trinary_minmax 1\n"
|
"#define GL_AMD_shader_trinary_minmax 1\n"
|
||||||
"#define GL_AMD_shader_explicit_vertex_parameter 1\n"
|
"#define GL_AMD_shader_explicit_vertex_parameter 1\n"
|
||||||
@@ -418,9 +445,9 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_AMD_shader_image_load_store_lod 1\n"
|
"#define GL_AMD_shader_image_load_store_lod 1\n"
|
||||||
"#define GL_AMD_shader_fragment_mask 1\n"
|
"#define GL_AMD_shader_fragment_mask 1\n"
|
||||||
"#define GL_AMD_gpu_shader_half_float_fetch 1\n"
|
"#define GL_AMD_gpu_shader_half_float_fetch 1\n"
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
"#define GL_INTEL_shader_integer_functions2 1\n"
|
||||||
|
|
||||||
"#define GL_NV_sample_mask_override_coverage 1\n"
|
"#define GL_NV_sample_mask_override_coverage 1\n"
|
||||||
"#define GL_NV_geometry_shader_passthrough 1\n"
|
"#define GL_NV_geometry_shader_passthrough 1\n"
|
||||||
"#define GL_NV_viewport_array2 1\n"
|
"#define GL_NV_viewport_array2 1\n"
|
||||||
@@ -433,8 +460,8 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_NV_compute_shader_derivatives 1\n"
|
"#define GL_NV_compute_shader_derivatives 1\n"
|
||||||
"#define GL_NV_shader_texture_footprint 1\n"
|
"#define GL_NV_shader_texture_footprint 1\n"
|
||||||
"#define GL_NV_mesh_shader 1\n"
|
"#define GL_NV_mesh_shader 1\n"
|
||||||
#endif
|
|
||||||
"#define GL_NV_cooperative_matrix 1\n"
|
"#define GL_NV_cooperative_matrix 1\n"
|
||||||
|
"#define GL_NV_integer_cooperative_matrix 1\n"
|
||||||
|
|
||||||
"#define GL_EXT_shader_explicit_arithmetic_types 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types 1\n"
|
||||||
"#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n"
|
||||||
@@ -444,6 +471,11 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
"#define GL_EXT_shader_explicit_arithmetic_types_float16 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types_float16 1\n"
|
||||||
"#define GL_EXT_shader_explicit_arithmetic_types_float32 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types_float32 1\n"
|
||||||
"#define GL_EXT_shader_explicit_arithmetic_types_float64 1\n"
|
"#define GL_EXT_shader_explicit_arithmetic_types_float64 1\n"
|
||||||
|
|
||||||
|
"#define GL_EXT_shader_subgroup_extended_types_int8 1\n"
|
||||||
|
"#define GL_EXT_shader_subgroup_extended_types_int16 1\n"
|
||||||
|
"#define GL_EXT_shader_subgroup_extended_types_int64 1\n"
|
||||||
|
"#define GL_EXT_shader_subgroup_extended_types_float16 1\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
if (version >= 150) {
|
if (version >= 150) {
|
||||||
@@ -453,13 +485,16 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
if (profile == ECompatibilityProfile)
|
if (profile == ECompatibilityProfile)
|
||||||
preamble += "#define GL_compatibility_profile 1\n";
|
preamble += "#define GL_compatibility_profile 1\n";
|
||||||
}
|
}
|
||||||
|
#endif // GLSLANG_WEB
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((profile != EEsProfile && version >= 140) ||
|
#ifndef GLSLANG_WEB
|
||||||
(profile == EEsProfile && version >= 310)) {
|
if ((!isEsProfile() && version >= 140) ||
|
||||||
|
(isEsProfile() && version >= 310)) {
|
||||||
preamble +=
|
preamble +=
|
||||||
"#define GL_EXT_device_group 1\n"
|
"#define GL_EXT_device_group 1\n"
|
||||||
"#define GL_EXT_multiview 1\n"
|
"#define GL_EXT_multiview 1\n"
|
||||||
|
"#define GL_NV_shader_sm_builtins 1\n"
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -474,7 +509,9 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
preamble +=
|
preamble +=
|
||||||
"#define GL_GOOGLE_cpp_style_line_directive 1\n"
|
"#define GL_GOOGLE_cpp_style_line_directive 1\n"
|
||||||
"#define GL_GOOGLE_include_directive 1\n"
|
"#define GL_GOOGLE_include_directive 1\n"
|
||||||
|
"#define GL_KHR_blend_equation_advanced 1\n"
|
||||||
;
|
;
|
||||||
|
#endif
|
||||||
|
|
||||||
// #define VULKAN XXXX
|
// #define VULKAN XXXX
|
||||||
const int numberBufSize = 12;
|
const int numberBufSize = 12;
|
||||||
@@ -485,6 +522,8 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
preamble += numberBuf;
|
preamble += numberBuf;
|
||||||
preamble += "\n";
|
preamble += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
// #define GL_SPIRV XXXX
|
// #define GL_SPIRV XXXX
|
||||||
if (spvVersion.openGl > 0) {
|
if (spvVersion.openGl > 0) {
|
||||||
preamble += "#define GL_SPIRV ";
|
preamble += "#define GL_SPIRV ";
|
||||||
@@ -492,22 +531,7 @@ void TParseVersions::getPreamble(std::string& preamble)
|
|||||||
preamble += numberBuf;
|
preamble += numberBuf;
|
||||||
preamble += "\n";
|
preamble += "\n";
|
||||||
}
|
}
|
||||||
|
#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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -517,12 +541,12 @@ const char* StageName(EShLanguage stage)
|
|||||||
{
|
{
|
||||||
switch(stage) {
|
switch(stage) {
|
||||||
case EShLangVertex: return "vertex";
|
case EShLangVertex: return "vertex";
|
||||||
|
case EShLangFragment: return "fragment";
|
||||||
|
case EShLangCompute: return "compute";
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case EShLangTessControl: return "tessellation control";
|
case EShLangTessControl: return "tessellation control";
|
||||||
case EShLangTessEvaluation: return "tessellation evaluation";
|
case EShLangTessEvaluation: return "tessellation evaluation";
|
||||||
case EShLangGeometry: return "geometry";
|
case EShLangGeometry: return "geometry";
|
||||||
case EShLangFragment: return "fragment";
|
|
||||||
case EShLangCompute: return "compute";
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EShLangRayGenNV: return "ray-generation";
|
case EShLangRayGenNV: return "ray-generation";
|
||||||
case EShLangIntersectNV: return "intersection";
|
case EShLangIntersectNV: return "intersection";
|
||||||
case EShLangAnyHitNV: return "any-hit";
|
case EShLangAnyHitNV: return "any-hit";
|
||||||
@@ -536,53 +560,6 @@ const char* StageName(EShLanguage stage)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// When to use profileRequires():
|
|
||||||
//
|
|
||||||
// If a set of profiles have the same requirements for what version or extensions
|
|
||||||
// are needed to support a feature.
|
|
||||||
//
|
|
||||||
// It must be called for each profile that needs protection. Use requireProfile() first
|
|
||||||
// to reduce that set of profiles.
|
|
||||||
//
|
|
||||||
// Operation: Will issue warnings/errors based on the current profile, version, and extension
|
|
||||||
// behaviors. It only checks extensions when the current profile is one of the profileMask.
|
|
||||||
//
|
|
||||||
// A minVersion of 0 means no version of the profileMask support this in core,
|
|
||||||
// the extension must be present.
|
|
||||||
//
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
{
|
|
||||||
if (profile & profileMask) {
|
|
||||||
bool okay = false;
|
|
||||||
if (minVersion > 0 && version >= minVersion)
|
|
||||||
okay = true;
|
|
||||||
for (int i = 0; i < numExtensions; ++i) {
|
|
||||||
switch (getExtensionBehavior(extensions[i])) {
|
|
||||||
case EBhWarn:
|
|
||||||
infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc);
|
|
||||||
// fall through
|
|
||||||
case EBhRequire:
|
|
||||||
case EBhEnable:
|
|
||||||
okay = true;
|
|
||||||
break;
|
|
||||||
default: break; // some compilers want this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! okay)
|
|
||||||
error(loc, "not supported for this version or the enabled extensions", featureDesc, "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
{
|
|
||||||
profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// When to use requireStage()
|
// When to use requireStage()
|
||||||
//
|
//
|
||||||
@@ -603,6 +580,75 @@ void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguage stage, cons
|
|||||||
requireStage(loc, static_cast<EShLanguageMask>(1 << stage), featureDesc);
|
requireStage(loc, static_cast<EShLanguageMask>(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():
|
||||||
|
//
|
||||||
|
// If a set of profiles have the same requirements for what version or extensions
|
||||||
|
// are needed to support a feature.
|
||||||
|
//
|
||||||
|
// It must be called for each profile that needs protection. Use requireProfile() first
|
||||||
|
// to reduce that set of profiles.
|
||||||
|
//
|
||||||
|
// Operation: Will issue warnings/errors based on the current profile, version, and extension
|
||||||
|
// behaviors. It only checks extensions when the current profile is one of the profileMask.
|
||||||
|
//
|
||||||
|
// A minVersion of 0 means no version of the profileMask support this in core,
|
||||||
|
// the extension must be present.
|
||||||
|
//
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
if (profile & profileMask) {
|
||||||
|
bool okay = minVersion > 0 && version >= minVersion;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
for (int i = 0; i < numExtensions; ++i) {
|
||||||
|
switch (getExtensionBehavior(extensions[i])) {
|
||||||
|
case EBhWarn:
|
||||||
|
infoSink.info.message(EPrefixWarning, ("extension " + TString(extensions[i]) + " is being used for " + featureDesc).c_str(), loc);
|
||||||
|
// fall through
|
||||||
|
case EBhRequire:
|
||||||
|
case EBhEnable:
|
||||||
|
okay = true;
|
||||||
|
break;
|
||||||
|
default: break; // some compilers want this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (! okay)
|
||||||
|
error(loc, "not supported for this version or the enabled extensions", featureDesc, "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
profileRequires(loc, profileMask, minVersion, extension ? 1 : 0, &extension, featureDesc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TParseVersions::unimplemented(const TSourceLoc& loc, const char* featureDesc)
|
||||||
|
{
|
||||||
|
error(loc, "feature not yet implemented", featureDesc, "");
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Within a set of profiles, see if a feature is deprecated and give an error or warning based on whether
|
// Within a set of profiles, see if a feature is deprecated and give an error or warning based on whether
|
||||||
// a future compatibility context is being use.
|
// a future compatibility context is being use.
|
||||||
@@ -636,11 +682,6 @@ void TParseVersions::requireNotRemoved(const TSourceLoc& loc, int profileMask, i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TParseVersions::unimplemented(const TSourceLoc& loc, const char* featureDesc)
|
|
||||||
{
|
|
||||||
error(loc, "feature not yet implemented", featureDesc, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false.
|
// Returns true if at least one of the extensions in the extensions parameter is requested. Otherwise, returns false.
|
||||||
// Warns appropriately if the requested behavior of an extension is "warn".
|
// Warns appropriately if the requested behavior of an extension is "warn".
|
||||||
bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
bool TParseVersions::checkExtensionsRequested(const TSourceLoc& loc, int numExtensions, const char* const extensions[], const char* featureDesc)
|
||||||
@@ -809,12 +850,22 @@ void TParseVersions::updateExtensionBehavior(int line, const char* extension, co
|
|||||||
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
||||||
else if (strcmp(extension, "GL_KHR_shader_subgroup_quad") == 0)
|
else if (strcmp(extension, "GL_KHR_shader_subgroup_quad") == 0)
|
||||||
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
else if (strcmp(extension, "GL_NV_shader_subgroup_partitioned") == 0)
|
else if (strcmp(extension, "GL_NV_shader_subgroup_partitioned") == 0)
|
||||||
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
updateExtensionBehavior(line, "GL_KHR_shader_subgroup_basic", behaviorString);
|
||||||
#endif
|
else if (strcmp(extension, "GL_EXT_buffer_reference2") == 0 ||
|
||||||
else if (strcmp(extension, "GL_EXT_buffer_reference2") == 0)
|
strcmp(extension, "GL_EXT_buffer_reference_uvec2") == 0)
|
||||||
updateExtensionBehavior(line, "GL_EXT_buffer_reference", behaviorString);
|
updateExtensionBehavior(line, "GL_EXT_buffer_reference", behaviorString);
|
||||||
|
else if (strcmp(extension, "GL_NV_integer_cooperative_matrix") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_NV_cooperative_matrix", behaviorString);
|
||||||
|
// subgroup extended types to explicit types
|
||||||
|
else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_int8") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_int8", behaviorString);
|
||||||
|
else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_int16") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_int16", behaviorString);
|
||||||
|
else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_int64") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_int64", behaviorString);
|
||||||
|
else if (strcmp(extension, "GL_EXT_shader_subgroup_extended_types_float16") == 0)
|
||||||
|
updateExtensionBehavior(line, "GL_EXT_shader_explicit_arithmetic_types_float16", behaviorString);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
|
void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBehavior behavior)
|
||||||
@@ -860,7 +911,6 @@ void TParseVersions::updateExtensionBehavior(const char* extension, TExtensionBe
|
|||||||
// Check if extension is used with correct shader stage.
|
// Check if extension is used with correct shader stage.
|
||||||
void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * const extension)
|
void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * const extension)
|
||||||
{
|
{
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
// GL_NV_mesh_shader extension is only allowed in task/mesh shaders
|
// GL_NV_mesh_shader extension is only allowed in task/mesh shaders
|
||||||
if (strcmp(extension, "GL_NV_mesh_shader") == 0) {
|
if (strcmp(extension, "GL_NV_mesh_shader") == 0) {
|
||||||
requireStage(loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask | EShLangFragmentMask),
|
requireStage(loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask | EShLangFragmentMask),
|
||||||
@@ -868,7 +918,6 @@ void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * con
|
|||||||
profileRequires(loc, ECoreProfile, 450, 0, "#extension GL_NV_mesh_shader");
|
profileRequires(loc, ECoreProfile, 450, 0, "#extension GL_NV_mesh_shader");
|
||||||
profileRequires(loc, EEsProfile, 320, 0, "#extension GL_NV_mesh_shader");
|
profileRequires(loc, EEsProfile, 320, 0, "#extension GL_NV_mesh_shader");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call for any operation needing full GLSL integer data-type support.
|
// Call for any operation needing full GLSL integer data-type support.
|
||||||
@@ -881,8 +930,8 @@ void TParseVersions::fullIntegerCheck(const TSourceLoc& loc, const char* op)
|
|||||||
// Call for any operation needing GLSL double data-type support.
|
// Call for any operation needing GLSL double data-type support.
|
||||||
void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
|
void TParseVersions::doubleCheck(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
//requireProfile(loc, ECoreProfile | ECompatibilityProfile, op);
|
||||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader_fp64, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call for any operation needing GLSL float16 data-type support.
|
// Call for any operation needing GLSL float16 data-type support.
|
||||||
@@ -890,9 +939,7 @@ void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool bu
|
|||||||
{
|
{
|
||||||
if (!builtIn) {
|
if (!builtIn) {
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_half_float,
|
E_GL_AMD_gpu_shader_half_float,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
||||||
@@ -902,9 +949,7 @@ void TParseVersions::float16Check(const TSourceLoc& loc, const char* op, bool bu
|
|||||||
bool TParseVersions::float16Arithmetic()
|
bool TParseVersions::float16Arithmetic()
|
||||||
{
|
{
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_half_float,
|
E_GL_AMD_gpu_shader_half_float,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
||||||
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
||||||
@@ -913,9 +958,7 @@ bool TParseVersions::float16Arithmetic()
|
|||||||
bool TParseVersions::int16Arithmetic()
|
bool TParseVersions::int16Arithmetic()
|
||||||
{
|
{
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
||||||
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
return extensionsTurnedOn(sizeof(extensions)/sizeof(extensions[0]), extensions);
|
||||||
@@ -937,9 +980,7 @@ void TParseVersions::requireFloat16Arithmetic(const TSourceLoc& loc, const char*
|
|||||||
combined += featureDesc;
|
combined += featureDesc;
|
||||||
|
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_half_float,
|
E_GL_AMD_gpu_shader_half_float,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
|
||||||
@@ -953,9 +994,7 @@ void TParseVersions::requireInt16Arithmetic(const TSourceLoc& loc, const char* o
|
|||||||
combined += featureDesc;
|
combined += featureDesc;
|
||||||
|
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, combined.c_str());
|
||||||
@@ -978,9 +1017,7 @@ void TParseVersions::float16ScalarVectorCheck(const TSourceLoc& loc, const char*
|
|||||||
{
|
{
|
||||||
if (!builtIn) {
|
if (!builtIn) {
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_half_float,
|
E_GL_AMD_gpu_shader_half_float,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_16bit_storage,
|
E_GL_EXT_shader_16bit_storage,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
E_GL_EXT_shader_explicit_arithmetic_types_float16};
|
||||||
@@ -1020,7 +1057,6 @@ void TParseVersions::explicitInt8Check(const TSourceLoc& loc, const char* op, bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
// Call for any operation needing GLSL float16 opaque-type support
|
// Call for any operation needing GLSL float16 opaque-type support
|
||||||
void TParseVersions::float16OpaqueCheck(const TSourceLoc& loc, const char* op, bool builtIn)
|
void TParseVersions::float16OpaqueCheck(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
{
|
{
|
||||||
@@ -1030,16 +1066,13 @@ void TParseVersions::float16OpaqueCheck(const TSourceLoc& loc, const char* op, b
|
|||||||
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
|
profileRequires(loc, ECoreProfile | ECompatibilityProfile, 400, nullptr, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Call for any operation needing GLSL explicit int16 data-type support.
|
// Call for any operation needing GLSL explicit int16 data-type support.
|
||||||
void TParseVersions::explicitInt16Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
void TParseVersions::explicitInt16Check(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
{
|
{
|
||||||
if (! builtIn) {
|
if (! builtIn) {
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
||||||
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
||||||
@@ -1050,9 +1083,7 @@ void TParseVersions::int16ScalarVectorCheck(const TSourceLoc& loc, const char* o
|
|||||||
{
|
{
|
||||||
if (! builtIn) {
|
if (! builtIn) {
|
||||||
const char* const extensions[] = {
|
const char* const extensions[] = {
|
||||||
#if AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_16bit_storage,
|
E_GL_EXT_shader_16bit_storage,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
E_GL_EXT_shader_explicit_arithmetic_types_int16};
|
||||||
@@ -1102,6 +1133,14 @@ void TParseVersions::fcoopmatCheck(const TSourceLoc& loc, const char* op, bool b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TParseVersions::intcoopmatCheck(const TSourceLoc& loc, const char* op, bool builtIn)
|
||||||
|
{
|
||||||
|
if (!builtIn) {
|
||||||
|
const char* const extensions[] = {E_GL_NV_integer_cooperative_matrix};
|
||||||
|
requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // GLSLANG_WEB
|
||||||
// Call for any operation removed because SPIR-V is in use.
|
// Call for any operation removed because SPIR-V is in use.
|
||||||
void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
|
void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
@@ -1119,15 +1158,19 @@ void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op)
|
|||||||
// Call for any operation that requires Vulkan.
|
// Call for any operation that requires Vulkan.
|
||||||
void TParseVersions::requireVulkan(const TSourceLoc& loc, const char* op)
|
void TParseVersions::requireVulkan(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (spvVersion.vulkan == 0)
|
if (spvVersion.vulkan == 0)
|
||||||
error(loc, "only allowed when using GLSL for Vulkan", op, "");
|
error(loc, "only allowed when using GLSL for Vulkan", op, "");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call for any operation that requires SPIR-V.
|
// Call for any operation that requires SPIR-V.
|
||||||
void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op)
|
void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op)
|
||||||
{
|
{
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (spvVersion.spv == 0)
|
if (spvVersion.spv == 0)
|
||||||
error(loc, "only allowed when generating SPIR-V", op, "");
|
error(loc, "only allowed when generating SPIR-V", op, "");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|||||||
@@ -125,8 +125,10 @@ const char* const E_GL_ARB_compute_shader = "GL_ARB_compute_shader
|
|||||||
const char* const E_GL_ARB_tessellation_shader = "GL_ARB_tessellation_shader";
|
const char* const E_GL_ARB_tessellation_shader = "GL_ARB_tessellation_shader";
|
||||||
const char* const E_GL_ARB_enhanced_layouts = "GL_ARB_enhanced_layouts";
|
const char* const E_GL_ARB_enhanced_layouts = "GL_ARB_enhanced_layouts";
|
||||||
const char* const E_GL_ARB_texture_cube_map_array = "GL_ARB_texture_cube_map_array";
|
const char* const E_GL_ARB_texture_cube_map_array = "GL_ARB_texture_cube_map_array";
|
||||||
|
const char* const E_GL_ARB_texture_multisample = "GL_ARB_texture_multisample";
|
||||||
const char* const E_GL_ARB_shader_texture_lod = "GL_ARB_shader_texture_lod";
|
const char* const E_GL_ARB_shader_texture_lod = "GL_ARB_shader_texture_lod";
|
||||||
const char* const E_GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attrib_location";
|
const char* const E_GL_ARB_explicit_attrib_location = "GL_ARB_explicit_attrib_location";
|
||||||
|
const char* const E_GL_ARB_explicit_uniform_location = "GL_ARB_explicit_uniform_location";
|
||||||
const char* const E_GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store";
|
const char* const E_GL_ARB_shader_image_load_store = "GL_ARB_shader_image_load_store";
|
||||||
const char* const E_GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters";
|
const char* const E_GL_ARB_shader_atomic_counters = "GL_ARB_shader_atomic_counters";
|
||||||
const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_parameters";
|
const char* const E_GL_ARB_shader_draw_parameters = "GL_ARB_shader_draw_parameters";
|
||||||
@@ -135,6 +137,7 @@ const char* const E_GL_ARB_derivative_control = "GL_ARB_derivative_con
|
|||||||
const char* const E_GL_ARB_shader_texture_image_samples = "GL_ARB_shader_texture_image_samples";
|
const char* const E_GL_ARB_shader_texture_image_samples = "GL_ARB_shader_texture_image_samples";
|
||||||
const char* const E_GL_ARB_viewport_array = "GL_ARB_viewport_array";
|
const char* const E_GL_ARB_viewport_array = "GL_ARB_viewport_array";
|
||||||
const char* const E_GL_ARB_gpu_shader_int64 = "GL_ARB_gpu_shader_int64";
|
const char* const E_GL_ARB_gpu_shader_int64 = "GL_ARB_gpu_shader_int64";
|
||||||
|
const char* const E_GL_ARB_gpu_shader_fp64 = "GL_ARB_gpu_shader_fp64";
|
||||||
const char* const E_GL_ARB_shader_ballot = "GL_ARB_shader_ballot";
|
const char* const E_GL_ARB_shader_ballot = "GL_ARB_shader_ballot";
|
||||||
const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture2";
|
const char* const E_GL_ARB_sparse_texture2 = "GL_ARB_sparse_texture2";
|
||||||
const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp";
|
const char* const E_GL_ARB_sparse_texture_clamp = "GL_ARB_sparse_texture_clamp";
|
||||||
@@ -142,6 +145,10 @@ const char* const E_GL_ARB_shader_stencil_export = "GL_ARB_shader_stencil
|
|||||||
// const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members
|
// const char* const E_GL_ARB_cull_distance = "GL_ARB_cull_distance"; // present for 4.5, but need extension control over block members
|
||||||
const char* const E_GL_ARB_post_depth_coverage = "GL_ARB_post_depth_coverage";
|
const char* const E_GL_ARB_post_depth_coverage = "GL_ARB_post_depth_coverage";
|
||||||
const char* const E_GL_ARB_shader_viewport_layer_array = "GL_ARB_shader_viewport_layer_array";
|
const char* const E_GL_ARB_shader_viewport_layer_array = "GL_ARB_shader_viewport_layer_array";
|
||||||
|
const char* const E_GL_ARB_fragment_shader_interlock = "GL_ARB_fragment_shader_interlock";
|
||||||
|
const char* const E_GL_ARB_shader_clock = "GL_ARB_shader_clock";
|
||||||
|
const char* const E_GL_ARB_uniform_buffer_object = "GL_ARB_uniform_buffer_object";
|
||||||
|
const char* const E_GL_ARB_sample_shading = "GL_ARB_sample_shading";
|
||||||
|
|
||||||
const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic";
|
const char* const E_GL_KHR_shader_subgroup_basic = "GL_KHR_shader_subgroup_basic";
|
||||||
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
|
const char* const E_GL_KHR_shader_subgroup_vote = "GL_KHR_shader_subgroup_vote";
|
||||||
@@ -173,6 +180,9 @@ const char* const E_GL_EXT_scalar_block_layout = "GL_EXT_scalar_blo
|
|||||||
const char* const E_GL_EXT_fragment_invocation_density = "GL_EXT_fragment_invocation_density";
|
const char* const E_GL_EXT_fragment_invocation_density = "GL_EXT_fragment_invocation_density";
|
||||||
const char* const E_GL_EXT_buffer_reference = "GL_EXT_buffer_reference";
|
const char* const E_GL_EXT_buffer_reference = "GL_EXT_buffer_reference";
|
||||||
const char* const E_GL_EXT_buffer_reference2 = "GL_EXT_buffer_reference2";
|
const char* const E_GL_EXT_buffer_reference2 = "GL_EXT_buffer_reference2";
|
||||||
|
const char* const E_GL_EXT_buffer_reference_uvec2 = "GL_EXT_buffer_reference_uvec2";
|
||||||
|
const char* const E_GL_EXT_demote_to_helper_invocation = "GL_EXT_demote_to_helper_invocation";
|
||||||
|
const char* const E_GL_EXT_shader_realtime_clock = "GL_EXT_shader_realtime_clock";
|
||||||
|
|
||||||
// Arrays of extensions for the above viewportEXTs duplications
|
// Arrays of extensions for the above viewportEXTs duplications
|
||||||
|
|
||||||
@@ -190,7 +200,6 @@ const int Num_OVR_multiview_EXTs = sizeof(OVR_multiview_EXTs) / sizeof(OVR_multi
|
|||||||
const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive";
|
const char* const E_GL_GOOGLE_cpp_style_line_directive = "GL_GOOGLE_cpp_style_line_directive";
|
||||||
const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive";
|
const char* const E_GL_GOOGLE_include_directive = "GL_GOOGLE_include_directive";
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
const char* const E_GL_AMD_shader_ballot = "GL_AMD_shader_ballot";
|
const char* const E_GL_AMD_shader_ballot = "GL_AMD_shader_ballot";
|
||||||
const char* const E_GL_AMD_shader_trinary_minmax = "GL_AMD_shader_trinary_minmax";
|
const char* const E_GL_AMD_shader_trinary_minmax = "GL_AMD_shader_trinary_minmax";
|
||||||
const char* const E_GL_AMD_shader_explicit_vertex_parameter = "GL_AMD_shader_explicit_vertex_parameter";
|
const char* const E_GL_AMD_shader_explicit_vertex_parameter = "GL_AMD_shader_explicit_vertex_parameter";
|
||||||
@@ -201,9 +210,8 @@ const char* const E_GL_AMD_gpu_shader_int16 = "GL_AMD_gpu_sh
|
|||||||
const char* const E_GL_AMD_shader_image_load_store_lod = "GL_AMD_shader_image_load_store_lod";
|
const char* const E_GL_AMD_shader_image_load_store_lod = "GL_AMD_shader_image_load_store_lod";
|
||||||
const char* const E_GL_AMD_shader_fragment_mask = "GL_AMD_shader_fragment_mask";
|
const char* const E_GL_AMD_shader_fragment_mask = "GL_AMD_shader_fragment_mask";
|
||||||
const char* const E_GL_AMD_gpu_shader_half_float_fetch = "GL_AMD_gpu_shader_half_float_fetch";
|
const char* const E_GL_AMD_gpu_shader_half_float_fetch = "GL_AMD_gpu_shader_half_float_fetch";
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
const char* const E_GL_INTEL_shader_integer_functions2 = "GL_INTEL_shader_integer_functions2";
|
||||||
|
|
||||||
const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage";
|
const char* const E_GL_NV_sample_mask_override_coverage = "GL_NV_sample_mask_override_coverage";
|
||||||
const char* const E_SPV_NV_geometry_shader_passthrough = "GL_NV_geometry_shader_passthrough";
|
const char* const E_SPV_NV_geometry_shader_passthrough = "GL_NV_geometry_shader_passthrough";
|
||||||
@@ -225,9 +233,10 @@ const char* const E_GL_NV_mesh_shader = "GL_NV_mesh_sh
|
|||||||
|
|
||||||
const char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_NV_viewport_array2 };
|
const char* const viewportEXTs[] = { E_GL_ARB_shader_viewport_layer_array, E_GL_NV_viewport_array2 };
|
||||||
const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]);
|
const int Num_viewportEXTs = sizeof(viewportEXTs) / sizeof(viewportEXTs[0]);
|
||||||
#endif
|
|
||||||
|
|
||||||
const char* const E_GL_NV_cooperative_matrix = "GL_NV_cooperative_matrix";
|
const char* const E_GL_NV_cooperative_matrix = "GL_NV_cooperative_matrix";
|
||||||
|
const char* const E_GL_NV_shader_sm_builtins = "GL_NV_shader_sm_builtins";
|
||||||
|
const char* const E_GL_NV_integer_cooperative_matrix = "GL_NV_integer_cooperative_matrix";
|
||||||
|
|
||||||
// AEP
|
// AEP
|
||||||
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";
|
const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a";
|
||||||
@@ -257,7 +266,7 @@ const char* const E_GL_OES_tessellation_point_size = "GL_OES_tessel
|
|||||||
const char* const E_GL_OES_texture_buffer = "GL_OES_texture_buffer";
|
const char* const E_GL_OES_texture_buffer = "GL_OES_texture_buffer";
|
||||||
const char* const E_GL_OES_texture_cube_map_array = "GL_OES_texture_cube_map_array";
|
const char* const E_GL_OES_texture_cube_map_array = "GL_OES_texture_cube_map_array";
|
||||||
|
|
||||||
// KHX
|
// EXT
|
||||||
const char* const E_GL_EXT_shader_explicit_arithmetic_types = "GL_EXT_shader_explicit_arithmetic_types";
|
const char* const E_GL_EXT_shader_explicit_arithmetic_types = "GL_EXT_shader_explicit_arithmetic_types";
|
||||||
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int8 = "GL_EXT_shader_explicit_arithmetic_types_int8";
|
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int8 = "GL_EXT_shader_explicit_arithmetic_types_int8";
|
||||||
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int16 = "GL_EXT_shader_explicit_arithmetic_types_int16";
|
const char* const E_GL_EXT_shader_explicit_arithmetic_types_int16 = "GL_EXT_shader_explicit_arithmetic_types_int16";
|
||||||
@@ -267,6 +276,11 @@ const char* const E_GL_EXT_shader_explicit_arithmetic_types_float16 = "GL_EXT_s
|
|||||||
const char* const E_GL_EXT_shader_explicit_arithmetic_types_float32 = "GL_EXT_shader_explicit_arithmetic_types_float32";
|
const char* const E_GL_EXT_shader_explicit_arithmetic_types_float32 = "GL_EXT_shader_explicit_arithmetic_types_float32";
|
||||||
const char* const E_GL_EXT_shader_explicit_arithmetic_types_float64 = "GL_EXT_shader_explicit_arithmetic_types_float64";
|
const char* const E_GL_EXT_shader_explicit_arithmetic_types_float64 = "GL_EXT_shader_explicit_arithmetic_types_float64";
|
||||||
|
|
||||||
|
const char* const E_GL_EXT_shader_subgroup_extended_types_int8 = "GL_EXT_shader_subgroup_extended_types_int8";
|
||||||
|
const char* const E_GL_EXT_shader_subgroup_extended_types_int16 = "GL_EXT_shader_subgroup_extended_types_int16";
|
||||||
|
const char* const E_GL_EXT_shader_subgroup_extended_types_int64 = "GL_EXT_shader_subgroup_extended_types_int64";
|
||||||
|
const char* const E_GL_EXT_shader_subgroup_extended_types_float16 = "GL_EXT_shader_subgroup_extended_types_float16";
|
||||||
|
|
||||||
// Arrays of extensions for the above AEP duplications
|
// Arrays of extensions for the above AEP duplications
|
||||||
|
|
||||||
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };
|
const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader };
|
||||||
|
|||||||
@@ -34,6 +34,8 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
#include "attribute.h"
|
#include "attribute.h"
|
||||||
#include "../Include/intermediate.h"
|
#include "../Include/intermediate.h"
|
||||||
#include "ParseHelper.h"
|
#include "ParseHelper.h"
|
||||||
@@ -339,5 +341,6 @@ void TParseContext::handleLoopAttributes(const TAttributes& attributes, TIntermN
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // GLSLANG_WEB
|
||||||
|
|||||||
@@ -76,7 +76,49 @@ namespace glslang {
|
|||||||
EatMaxIterations,
|
EatMaxIterations,
|
||||||
EatIterationMultiple,
|
EatIterationMultiple,
|
||||||
EatPeelCount,
|
EatPeelCount,
|
||||||
EatPartialCount
|
EatPartialCount,
|
||||||
|
EatFormatRgba32f,
|
||||||
|
EatFormatRgba16f,
|
||||||
|
EatFormatR32f,
|
||||||
|
EatFormatRgba8,
|
||||||
|
EatFormatRgba8Snorm,
|
||||||
|
EatFormatRg32f,
|
||||||
|
EatFormatRg16f,
|
||||||
|
EatFormatR11fG11fB10f,
|
||||||
|
EatFormatR16f,
|
||||||
|
EatFormatRgba16,
|
||||||
|
EatFormatRgb10A2,
|
||||||
|
EatFormatRg16,
|
||||||
|
EatFormatRg8,
|
||||||
|
EatFormatR16,
|
||||||
|
EatFormatR8,
|
||||||
|
EatFormatRgba16Snorm,
|
||||||
|
EatFormatRg16Snorm,
|
||||||
|
EatFormatRg8Snorm,
|
||||||
|
EatFormatR16Snorm,
|
||||||
|
EatFormatR8Snorm,
|
||||||
|
EatFormatRgba32i,
|
||||||
|
EatFormatRgba16i,
|
||||||
|
EatFormatRgba8i,
|
||||||
|
EatFormatR32i,
|
||||||
|
EatFormatRg32i,
|
||||||
|
EatFormatRg16i,
|
||||||
|
EatFormatRg8i,
|
||||||
|
EatFormatR16i,
|
||||||
|
EatFormatR8i,
|
||||||
|
EatFormatRgba32ui,
|
||||||
|
EatFormatRgba16ui,
|
||||||
|
EatFormatRgba8ui,
|
||||||
|
EatFormatR32ui,
|
||||||
|
EatFormatRgb10a2ui,
|
||||||
|
EatFormatRg32ui,
|
||||||
|
EatFormatRg16ui,
|
||||||
|
EatFormatRg8ui,
|
||||||
|
EatFormatR16ui,
|
||||||
|
EatFormatR8ui,
|
||||||
|
EatFormatUnknown,
|
||||||
|
EatNonWritable,
|
||||||
|
EatNonReadable
|
||||||
};
|
};
|
||||||
|
|
||||||
class TIntermAggregate;
|
class TIntermAggregate;
|
||||||
|
|||||||
@@ -78,7 +78,6 @@
|
|||||||
#define GL_DOUBLE_MAT4x2 0x8F4D
|
#define GL_DOUBLE_MAT4x2 0x8F4D
|
||||||
#define GL_DOUBLE_MAT4x3 0x8F4E
|
#define GL_DOUBLE_MAT4x3 0x8F4E
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
// Those constants are borrowed from extension NV_gpu_shader5
|
// Those constants are borrowed from extension NV_gpu_shader5
|
||||||
#define GL_FLOAT16_NV 0x8FF8
|
#define GL_FLOAT16_NV 0x8FF8
|
||||||
#define GL_FLOAT16_VEC2_NV 0x8FF9
|
#define GL_FLOAT16_VEC2_NV 0x8FF9
|
||||||
@@ -94,7 +93,6 @@
|
|||||||
#define GL_FLOAT16_MAT3x4_AMD 0x91CB
|
#define GL_FLOAT16_MAT3x4_AMD 0x91CB
|
||||||
#define GL_FLOAT16_MAT4x2_AMD 0x91CC
|
#define GL_FLOAT16_MAT4x2_AMD 0x91CC
|
||||||
#define GL_FLOAT16_MAT4x3_AMD 0x91CD
|
#define GL_FLOAT16_MAT4x3_AMD 0x91CD
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GL_SAMPLER_1D 0x8B5D
|
#define GL_SAMPLER_1D 0x8B5D
|
||||||
#define GL_SAMPLER_2D 0x8B5E
|
#define GL_SAMPLER_2D 0x8B5E
|
||||||
@@ -117,7 +115,6 @@
|
|||||||
#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
|
#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C
|
||||||
#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
|
#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
#define GL_FLOAT16_SAMPLER_1D_AMD 0x91CE
|
#define GL_FLOAT16_SAMPLER_1D_AMD 0x91CE
|
||||||
#define GL_FLOAT16_SAMPLER_2D_AMD 0x91CF
|
#define GL_FLOAT16_SAMPLER_2D_AMD 0x91CF
|
||||||
#define GL_FLOAT16_SAMPLER_3D_AMD 0x91D0
|
#define GL_FLOAT16_SAMPLER_3D_AMD 0x91D0
|
||||||
@@ -149,7 +146,6 @@
|
|||||||
#define GL_FLOAT16_IMAGE_BUFFER_AMD 0x91E8
|
#define GL_FLOAT16_IMAGE_BUFFER_AMD 0x91E8
|
||||||
#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD 0x91E9
|
#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_AMD 0x91E9
|
||||||
#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD 0x91EA
|
#define GL_FLOAT16_IMAGE_2D_MULTISAMPLE_ARRAY_AMD 0x91EA
|
||||||
#endif
|
|
||||||
|
|
||||||
#define GL_INT_SAMPLER_1D 0x8DC9
|
#define GL_INT_SAMPLER_1D 0x8DC9
|
||||||
#define GL_INT_SAMPLER_2D 0x8DCA
|
#define GL_INT_SAMPLER_2D 0x8DCA
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -45,271 +45,271 @@ extern int yydebug;
|
|||||||
# define YYTOKENTYPE
|
# define YYTOKENTYPE
|
||||||
enum yytokentype
|
enum yytokentype
|
||||||
{
|
{
|
||||||
ATTRIBUTE = 258,
|
CONST = 258,
|
||||||
VARYING = 259,
|
BOOL = 259,
|
||||||
FLOAT16_T = 260,
|
INT = 260,
|
||||||
FLOAT = 261,
|
UINT = 261,
|
||||||
FLOAT32_T = 262,
|
FLOAT = 262,
|
||||||
DOUBLE = 263,
|
BVEC2 = 263,
|
||||||
FLOAT64_T = 264,
|
BVEC3 = 264,
|
||||||
CONST = 265,
|
BVEC4 = 265,
|
||||||
BOOL = 266,
|
IVEC2 = 266,
|
||||||
INT = 267,
|
IVEC3 = 267,
|
||||||
UINT = 268,
|
IVEC4 = 268,
|
||||||
INT64_T = 269,
|
UVEC2 = 269,
|
||||||
UINT64_T = 270,
|
UVEC3 = 270,
|
||||||
INT32_T = 271,
|
UVEC4 = 271,
|
||||||
UINT32_T = 272,
|
VEC2 = 272,
|
||||||
INT16_T = 273,
|
VEC3 = 273,
|
||||||
UINT16_T = 274,
|
VEC4 = 274,
|
||||||
INT8_T = 275,
|
MAT2 = 275,
|
||||||
UINT8_T = 276,
|
MAT3 = 276,
|
||||||
BREAK = 277,
|
MAT4 = 277,
|
||||||
CONTINUE = 278,
|
MAT2X2 = 278,
|
||||||
DO = 279,
|
MAT2X3 = 279,
|
||||||
ELSE = 280,
|
MAT2X4 = 280,
|
||||||
FOR = 281,
|
MAT3X2 = 281,
|
||||||
IF = 282,
|
MAT3X3 = 282,
|
||||||
DISCARD = 283,
|
MAT3X4 = 283,
|
||||||
RETURN = 284,
|
MAT4X2 = 284,
|
||||||
SWITCH = 285,
|
MAT4X3 = 285,
|
||||||
CASE = 286,
|
MAT4X4 = 286,
|
||||||
DEFAULT = 287,
|
SAMPLER2D = 287,
|
||||||
SUBROUTINE = 288,
|
SAMPLER3D = 288,
|
||||||
BVEC2 = 289,
|
SAMPLERCUBE = 289,
|
||||||
BVEC3 = 290,
|
SAMPLER2DSHADOW = 290,
|
||||||
BVEC4 = 291,
|
SAMPLERCUBESHADOW = 291,
|
||||||
IVEC2 = 292,
|
SAMPLER2DARRAY = 292,
|
||||||
IVEC3 = 293,
|
SAMPLER2DARRAYSHADOW = 293,
|
||||||
IVEC4 = 294,
|
ISAMPLER2D = 294,
|
||||||
UVEC2 = 295,
|
ISAMPLER3D = 295,
|
||||||
UVEC3 = 296,
|
ISAMPLERCUBE = 296,
|
||||||
UVEC4 = 297,
|
ISAMPLER2DARRAY = 297,
|
||||||
I64VEC2 = 298,
|
USAMPLER2D = 298,
|
||||||
I64VEC3 = 299,
|
USAMPLER3D = 299,
|
||||||
I64VEC4 = 300,
|
USAMPLERCUBE = 300,
|
||||||
U64VEC2 = 301,
|
USAMPLER2DARRAY = 301,
|
||||||
U64VEC3 = 302,
|
SAMPLER = 302,
|
||||||
U64VEC4 = 303,
|
SAMPLERSHADOW = 303,
|
||||||
I32VEC2 = 304,
|
TEXTURE2D = 304,
|
||||||
I32VEC3 = 305,
|
TEXTURE3D = 305,
|
||||||
I32VEC4 = 306,
|
TEXTURECUBE = 306,
|
||||||
U32VEC2 = 307,
|
TEXTURE2DARRAY = 307,
|
||||||
U32VEC3 = 308,
|
ITEXTURE2D = 308,
|
||||||
U32VEC4 = 309,
|
ITEXTURE3D = 309,
|
||||||
I16VEC2 = 310,
|
ITEXTURECUBE = 310,
|
||||||
I16VEC3 = 311,
|
ITEXTURE2DARRAY = 311,
|
||||||
I16VEC4 = 312,
|
UTEXTURE2D = 312,
|
||||||
U16VEC2 = 313,
|
UTEXTURE3D = 313,
|
||||||
U16VEC3 = 314,
|
UTEXTURECUBE = 314,
|
||||||
U16VEC4 = 315,
|
UTEXTURE2DARRAY = 315,
|
||||||
I8VEC2 = 316,
|
ATTRIBUTE = 316,
|
||||||
I8VEC3 = 317,
|
VARYING = 317,
|
||||||
I8VEC4 = 318,
|
FLOAT16_T = 318,
|
||||||
U8VEC2 = 319,
|
FLOAT32_T = 319,
|
||||||
U8VEC3 = 320,
|
DOUBLE = 320,
|
||||||
U8VEC4 = 321,
|
FLOAT64_T = 321,
|
||||||
VEC2 = 322,
|
INT64_T = 322,
|
||||||
VEC3 = 323,
|
UINT64_T = 323,
|
||||||
VEC4 = 324,
|
INT32_T = 324,
|
||||||
MAT2 = 325,
|
UINT32_T = 325,
|
||||||
MAT3 = 326,
|
INT16_T = 326,
|
||||||
MAT4 = 327,
|
UINT16_T = 327,
|
||||||
CENTROID = 328,
|
INT8_T = 328,
|
||||||
IN = 329,
|
UINT8_T = 329,
|
||||||
OUT = 330,
|
I64VEC2 = 330,
|
||||||
INOUT = 331,
|
I64VEC3 = 331,
|
||||||
UNIFORM = 332,
|
I64VEC4 = 332,
|
||||||
PATCH = 333,
|
U64VEC2 = 333,
|
||||||
SAMPLE = 334,
|
U64VEC3 = 334,
|
||||||
BUFFER = 335,
|
U64VEC4 = 335,
|
||||||
SHARED = 336,
|
I32VEC2 = 336,
|
||||||
NONUNIFORM = 337,
|
I32VEC3 = 337,
|
||||||
PAYLOADNV = 338,
|
I32VEC4 = 338,
|
||||||
PAYLOADINNV = 339,
|
U32VEC2 = 339,
|
||||||
HITATTRNV = 340,
|
U32VEC3 = 340,
|
||||||
CALLDATANV = 341,
|
U32VEC4 = 341,
|
||||||
CALLDATAINNV = 342,
|
I16VEC2 = 342,
|
||||||
COHERENT = 343,
|
I16VEC3 = 343,
|
||||||
VOLATILE = 344,
|
I16VEC4 = 344,
|
||||||
RESTRICT = 345,
|
U16VEC2 = 345,
|
||||||
READONLY = 346,
|
U16VEC3 = 346,
|
||||||
WRITEONLY = 347,
|
U16VEC4 = 347,
|
||||||
DEVICECOHERENT = 348,
|
I8VEC2 = 348,
|
||||||
QUEUEFAMILYCOHERENT = 349,
|
I8VEC3 = 349,
|
||||||
WORKGROUPCOHERENT = 350,
|
I8VEC4 = 350,
|
||||||
SUBGROUPCOHERENT = 351,
|
U8VEC2 = 351,
|
||||||
NONPRIVATE = 352,
|
U8VEC3 = 352,
|
||||||
DVEC2 = 353,
|
U8VEC4 = 353,
|
||||||
DVEC3 = 354,
|
DVEC2 = 354,
|
||||||
DVEC4 = 355,
|
DVEC3 = 355,
|
||||||
DMAT2 = 356,
|
DVEC4 = 356,
|
||||||
DMAT3 = 357,
|
DMAT2 = 357,
|
||||||
DMAT4 = 358,
|
DMAT3 = 358,
|
||||||
F16VEC2 = 359,
|
DMAT4 = 359,
|
||||||
F16VEC3 = 360,
|
F16VEC2 = 360,
|
||||||
F16VEC4 = 361,
|
F16VEC3 = 361,
|
||||||
F16MAT2 = 362,
|
F16VEC4 = 362,
|
||||||
F16MAT3 = 363,
|
F16MAT2 = 363,
|
||||||
F16MAT4 = 364,
|
F16MAT3 = 364,
|
||||||
F32VEC2 = 365,
|
F16MAT4 = 365,
|
||||||
F32VEC3 = 366,
|
F32VEC2 = 366,
|
||||||
F32VEC4 = 367,
|
F32VEC3 = 367,
|
||||||
F32MAT2 = 368,
|
F32VEC4 = 368,
|
||||||
F32MAT3 = 369,
|
F32MAT2 = 369,
|
||||||
F32MAT4 = 370,
|
F32MAT3 = 370,
|
||||||
F64VEC2 = 371,
|
F32MAT4 = 371,
|
||||||
F64VEC3 = 372,
|
F64VEC2 = 372,
|
||||||
F64VEC4 = 373,
|
F64VEC3 = 373,
|
||||||
F64MAT2 = 374,
|
F64VEC4 = 374,
|
||||||
F64MAT3 = 375,
|
F64MAT2 = 375,
|
||||||
F64MAT4 = 376,
|
F64MAT3 = 376,
|
||||||
NOPERSPECTIVE = 377,
|
F64MAT4 = 377,
|
||||||
FLAT = 378,
|
DMAT2X2 = 378,
|
||||||
SMOOTH = 379,
|
DMAT2X3 = 379,
|
||||||
LAYOUT = 380,
|
DMAT2X4 = 380,
|
||||||
EXPLICITINTERPAMD = 381,
|
DMAT3X2 = 381,
|
||||||
PERVERTEXNV = 382,
|
DMAT3X3 = 382,
|
||||||
PERPRIMITIVENV = 383,
|
DMAT3X4 = 383,
|
||||||
PERVIEWNV = 384,
|
DMAT4X2 = 384,
|
||||||
PERTASKNV = 385,
|
DMAT4X3 = 385,
|
||||||
MAT2X2 = 386,
|
DMAT4X4 = 386,
|
||||||
MAT2X3 = 387,
|
F16MAT2X2 = 387,
|
||||||
MAT2X4 = 388,
|
F16MAT2X3 = 388,
|
||||||
MAT3X2 = 389,
|
F16MAT2X4 = 389,
|
||||||
MAT3X3 = 390,
|
F16MAT3X2 = 390,
|
||||||
MAT3X4 = 391,
|
F16MAT3X3 = 391,
|
||||||
MAT4X2 = 392,
|
F16MAT3X4 = 392,
|
||||||
MAT4X3 = 393,
|
F16MAT4X2 = 393,
|
||||||
MAT4X4 = 394,
|
F16MAT4X3 = 394,
|
||||||
DMAT2X2 = 395,
|
F16MAT4X4 = 395,
|
||||||
DMAT2X3 = 396,
|
F32MAT2X2 = 396,
|
||||||
DMAT2X4 = 397,
|
F32MAT2X3 = 397,
|
||||||
DMAT3X2 = 398,
|
F32MAT2X4 = 398,
|
||||||
DMAT3X3 = 399,
|
F32MAT3X2 = 399,
|
||||||
DMAT3X4 = 400,
|
F32MAT3X3 = 400,
|
||||||
DMAT4X2 = 401,
|
F32MAT3X4 = 401,
|
||||||
DMAT4X3 = 402,
|
F32MAT4X2 = 402,
|
||||||
DMAT4X4 = 403,
|
F32MAT4X3 = 403,
|
||||||
F16MAT2X2 = 404,
|
F32MAT4X4 = 404,
|
||||||
F16MAT2X3 = 405,
|
F64MAT2X2 = 405,
|
||||||
F16MAT2X4 = 406,
|
F64MAT2X3 = 406,
|
||||||
F16MAT3X2 = 407,
|
F64MAT2X4 = 407,
|
||||||
F16MAT3X3 = 408,
|
F64MAT3X2 = 408,
|
||||||
F16MAT3X4 = 409,
|
F64MAT3X3 = 409,
|
||||||
F16MAT4X2 = 410,
|
F64MAT3X4 = 410,
|
||||||
F16MAT4X3 = 411,
|
F64MAT4X2 = 411,
|
||||||
F16MAT4X4 = 412,
|
F64MAT4X3 = 412,
|
||||||
F32MAT2X2 = 413,
|
F64MAT4X4 = 413,
|
||||||
F32MAT2X3 = 414,
|
ATOMIC_UINT = 414,
|
||||||
F32MAT2X4 = 415,
|
ACCSTRUCTNV = 415,
|
||||||
F32MAT3X2 = 416,
|
FCOOPMATNV = 416,
|
||||||
F32MAT3X3 = 417,
|
ICOOPMATNV = 417,
|
||||||
F32MAT3X4 = 418,
|
UCOOPMATNV = 418,
|
||||||
F32MAT4X2 = 419,
|
SAMPLERCUBEARRAY = 419,
|
||||||
F32MAT4X3 = 420,
|
SAMPLERCUBEARRAYSHADOW = 420,
|
||||||
F32MAT4X4 = 421,
|
ISAMPLERCUBEARRAY = 421,
|
||||||
F64MAT2X2 = 422,
|
USAMPLERCUBEARRAY = 422,
|
||||||
F64MAT2X3 = 423,
|
SAMPLER1D = 423,
|
||||||
F64MAT2X4 = 424,
|
SAMPLER1DARRAY = 424,
|
||||||
F64MAT3X2 = 425,
|
SAMPLER1DARRAYSHADOW = 425,
|
||||||
F64MAT3X3 = 426,
|
ISAMPLER1D = 426,
|
||||||
F64MAT3X4 = 427,
|
SAMPLER1DSHADOW = 427,
|
||||||
F64MAT4X2 = 428,
|
SAMPLER2DRECT = 428,
|
||||||
F64MAT4X3 = 429,
|
SAMPLER2DRECTSHADOW = 429,
|
||||||
F64MAT4X4 = 430,
|
ISAMPLER2DRECT = 430,
|
||||||
ATOMIC_UINT = 431,
|
USAMPLER2DRECT = 431,
|
||||||
ACCSTRUCTNV = 432,
|
SAMPLERBUFFER = 432,
|
||||||
FCOOPMATNV = 433,
|
ISAMPLERBUFFER = 433,
|
||||||
SAMPLER1D = 434,
|
USAMPLERBUFFER = 434,
|
||||||
SAMPLER2D = 435,
|
SAMPLER2DMS = 435,
|
||||||
SAMPLER3D = 436,
|
ISAMPLER2DMS = 436,
|
||||||
SAMPLERCUBE = 437,
|
USAMPLER2DMS = 437,
|
||||||
SAMPLER1DSHADOW = 438,
|
SAMPLER2DMSARRAY = 438,
|
||||||
SAMPLER2DSHADOW = 439,
|
ISAMPLER2DMSARRAY = 439,
|
||||||
SAMPLERCUBESHADOW = 440,
|
USAMPLER2DMSARRAY = 440,
|
||||||
SAMPLER1DARRAY = 441,
|
SAMPLEREXTERNALOES = 441,
|
||||||
SAMPLER2DARRAY = 442,
|
SAMPLEREXTERNAL2DY2YEXT = 442,
|
||||||
SAMPLER1DARRAYSHADOW = 443,
|
ISAMPLER1DARRAY = 443,
|
||||||
SAMPLER2DARRAYSHADOW = 444,
|
USAMPLER1D = 444,
|
||||||
ISAMPLER1D = 445,
|
USAMPLER1DARRAY = 445,
|
||||||
ISAMPLER2D = 446,
|
F16SAMPLER1D = 446,
|
||||||
ISAMPLER3D = 447,
|
F16SAMPLER2D = 447,
|
||||||
ISAMPLERCUBE = 448,
|
F16SAMPLER3D = 448,
|
||||||
ISAMPLER1DARRAY = 449,
|
F16SAMPLER2DRECT = 449,
|
||||||
ISAMPLER2DARRAY = 450,
|
F16SAMPLERCUBE = 450,
|
||||||
USAMPLER1D = 451,
|
F16SAMPLER1DARRAY = 451,
|
||||||
USAMPLER2D = 452,
|
F16SAMPLER2DARRAY = 452,
|
||||||
USAMPLER3D = 453,
|
F16SAMPLERCUBEARRAY = 453,
|
||||||
USAMPLERCUBE = 454,
|
F16SAMPLERBUFFER = 454,
|
||||||
USAMPLER1DARRAY = 455,
|
F16SAMPLER2DMS = 455,
|
||||||
USAMPLER2DARRAY = 456,
|
F16SAMPLER2DMSARRAY = 456,
|
||||||
SAMPLER2DRECT = 457,
|
F16SAMPLER1DSHADOW = 457,
|
||||||
SAMPLER2DRECTSHADOW = 458,
|
F16SAMPLER2DSHADOW = 458,
|
||||||
ISAMPLER2DRECT = 459,
|
F16SAMPLER1DARRAYSHADOW = 459,
|
||||||
USAMPLER2DRECT = 460,
|
F16SAMPLER2DARRAYSHADOW = 460,
|
||||||
SAMPLERBUFFER = 461,
|
F16SAMPLER2DRECTSHADOW = 461,
|
||||||
ISAMPLERBUFFER = 462,
|
F16SAMPLERCUBESHADOW = 462,
|
||||||
USAMPLERBUFFER = 463,
|
F16SAMPLERCUBEARRAYSHADOW = 463,
|
||||||
SAMPLERCUBEARRAY = 464,
|
IMAGE1D = 464,
|
||||||
SAMPLERCUBEARRAYSHADOW = 465,
|
IIMAGE1D = 465,
|
||||||
ISAMPLERCUBEARRAY = 466,
|
UIMAGE1D = 466,
|
||||||
USAMPLERCUBEARRAY = 467,
|
IMAGE2D = 467,
|
||||||
SAMPLER2DMS = 468,
|
IIMAGE2D = 468,
|
||||||
ISAMPLER2DMS = 469,
|
UIMAGE2D = 469,
|
||||||
USAMPLER2DMS = 470,
|
IMAGE3D = 470,
|
||||||
SAMPLER2DMSARRAY = 471,
|
IIMAGE3D = 471,
|
||||||
ISAMPLER2DMSARRAY = 472,
|
UIMAGE3D = 472,
|
||||||
USAMPLER2DMSARRAY = 473,
|
IMAGE2DRECT = 473,
|
||||||
SAMPLEREXTERNALOES = 474,
|
IIMAGE2DRECT = 474,
|
||||||
SAMPLEREXTERNAL2DY2YEXT = 475,
|
UIMAGE2DRECT = 475,
|
||||||
F16SAMPLER1D = 476,
|
IMAGECUBE = 476,
|
||||||
F16SAMPLER2D = 477,
|
IIMAGECUBE = 477,
|
||||||
F16SAMPLER3D = 478,
|
UIMAGECUBE = 478,
|
||||||
F16SAMPLER2DRECT = 479,
|
IMAGEBUFFER = 479,
|
||||||
F16SAMPLERCUBE = 480,
|
IIMAGEBUFFER = 480,
|
||||||
F16SAMPLER1DARRAY = 481,
|
UIMAGEBUFFER = 481,
|
||||||
F16SAMPLER2DARRAY = 482,
|
IMAGE1DARRAY = 482,
|
||||||
F16SAMPLERCUBEARRAY = 483,
|
IIMAGE1DARRAY = 483,
|
||||||
F16SAMPLERBUFFER = 484,
|
UIMAGE1DARRAY = 484,
|
||||||
F16SAMPLER2DMS = 485,
|
IMAGE2DARRAY = 485,
|
||||||
F16SAMPLER2DMSARRAY = 486,
|
IIMAGE2DARRAY = 486,
|
||||||
F16SAMPLER1DSHADOW = 487,
|
UIMAGE2DARRAY = 487,
|
||||||
F16SAMPLER2DSHADOW = 488,
|
IMAGECUBEARRAY = 488,
|
||||||
F16SAMPLER1DARRAYSHADOW = 489,
|
IIMAGECUBEARRAY = 489,
|
||||||
F16SAMPLER2DARRAYSHADOW = 490,
|
UIMAGECUBEARRAY = 490,
|
||||||
F16SAMPLER2DRECTSHADOW = 491,
|
IMAGE2DMS = 491,
|
||||||
F16SAMPLERCUBESHADOW = 492,
|
IIMAGE2DMS = 492,
|
||||||
F16SAMPLERCUBEARRAYSHADOW = 493,
|
UIMAGE2DMS = 493,
|
||||||
SAMPLER = 494,
|
IMAGE2DMSARRAY = 494,
|
||||||
SAMPLERSHADOW = 495,
|
IIMAGE2DMSARRAY = 495,
|
||||||
TEXTURE1D = 496,
|
UIMAGE2DMSARRAY = 496,
|
||||||
TEXTURE2D = 497,
|
F16IMAGE1D = 497,
|
||||||
TEXTURE3D = 498,
|
F16IMAGE2D = 498,
|
||||||
TEXTURECUBE = 499,
|
F16IMAGE3D = 499,
|
||||||
TEXTURE1DARRAY = 500,
|
F16IMAGE2DRECT = 500,
|
||||||
TEXTURE2DARRAY = 501,
|
F16IMAGECUBE = 501,
|
||||||
ITEXTURE1D = 502,
|
F16IMAGE1DARRAY = 502,
|
||||||
ITEXTURE2D = 503,
|
F16IMAGE2DARRAY = 503,
|
||||||
ITEXTURE3D = 504,
|
F16IMAGECUBEARRAY = 504,
|
||||||
ITEXTURECUBE = 505,
|
F16IMAGEBUFFER = 505,
|
||||||
ITEXTURE1DARRAY = 506,
|
F16IMAGE2DMS = 506,
|
||||||
ITEXTURE2DARRAY = 507,
|
F16IMAGE2DMSARRAY = 507,
|
||||||
UTEXTURE1D = 508,
|
TEXTURECUBEARRAY = 508,
|
||||||
UTEXTURE2D = 509,
|
ITEXTURECUBEARRAY = 509,
|
||||||
UTEXTURE3D = 510,
|
UTEXTURECUBEARRAY = 510,
|
||||||
UTEXTURECUBE = 511,
|
TEXTURE1D = 511,
|
||||||
UTEXTURE1DARRAY = 512,
|
ITEXTURE1D = 512,
|
||||||
UTEXTURE2DARRAY = 513,
|
UTEXTURE1D = 513,
|
||||||
TEXTURE2DRECT = 514,
|
TEXTURE1DARRAY = 514,
|
||||||
ITEXTURE2DRECT = 515,
|
ITEXTURE1DARRAY = 515,
|
||||||
UTEXTURE2DRECT = 516,
|
UTEXTURE1DARRAY = 516,
|
||||||
TEXTUREBUFFER = 517,
|
TEXTURE2DRECT = 517,
|
||||||
ITEXTUREBUFFER = 518,
|
ITEXTURE2DRECT = 518,
|
||||||
UTEXTUREBUFFER = 519,
|
UTEXTURE2DRECT = 519,
|
||||||
TEXTURECUBEARRAY = 520,
|
TEXTUREBUFFER = 520,
|
||||||
ITEXTURECUBEARRAY = 521,
|
ITEXTUREBUFFER = 521,
|
||||||
UTEXTURECUBEARRAY = 522,
|
UTEXTUREBUFFER = 522,
|
||||||
TEXTURE2DMS = 523,
|
TEXTURE2DMS = 523,
|
||||||
ITEXTURE2DMS = 524,
|
ITEXTURE2DMS = 524,
|
||||||
UTEXTURE2DMS = 525,
|
UTEXTURE2DMS = 525,
|
||||||
@@ -335,121 +335,124 @@ extern int yydebug;
|
|||||||
USUBPASSINPUTMS = 545,
|
USUBPASSINPUTMS = 545,
|
||||||
F16SUBPASSINPUT = 546,
|
F16SUBPASSINPUT = 546,
|
||||||
F16SUBPASSINPUTMS = 547,
|
F16SUBPASSINPUTMS = 547,
|
||||||
IMAGE1D = 548,
|
LEFT_OP = 548,
|
||||||
IIMAGE1D = 549,
|
RIGHT_OP = 549,
|
||||||
UIMAGE1D = 550,
|
INC_OP = 550,
|
||||||
IMAGE2D = 551,
|
DEC_OP = 551,
|
||||||
IIMAGE2D = 552,
|
LE_OP = 552,
|
||||||
UIMAGE2D = 553,
|
GE_OP = 553,
|
||||||
IMAGE3D = 554,
|
EQ_OP = 554,
|
||||||
IIMAGE3D = 555,
|
NE_OP = 555,
|
||||||
UIMAGE3D = 556,
|
AND_OP = 556,
|
||||||
IMAGE2DRECT = 557,
|
OR_OP = 557,
|
||||||
IIMAGE2DRECT = 558,
|
XOR_OP = 558,
|
||||||
UIMAGE2DRECT = 559,
|
MUL_ASSIGN = 559,
|
||||||
IMAGECUBE = 560,
|
DIV_ASSIGN = 560,
|
||||||
IIMAGECUBE = 561,
|
ADD_ASSIGN = 561,
|
||||||
UIMAGECUBE = 562,
|
MOD_ASSIGN = 562,
|
||||||
IMAGEBUFFER = 563,
|
LEFT_ASSIGN = 563,
|
||||||
IIMAGEBUFFER = 564,
|
RIGHT_ASSIGN = 564,
|
||||||
UIMAGEBUFFER = 565,
|
AND_ASSIGN = 565,
|
||||||
IMAGE1DARRAY = 566,
|
XOR_ASSIGN = 566,
|
||||||
IIMAGE1DARRAY = 567,
|
OR_ASSIGN = 567,
|
||||||
UIMAGE1DARRAY = 568,
|
SUB_ASSIGN = 568,
|
||||||
IMAGE2DARRAY = 569,
|
LEFT_PAREN = 569,
|
||||||
IIMAGE2DARRAY = 570,
|
RIGHT_PAREN = 570,
|
||||||
UIMAGE2DARRAY = 571,
|
LEFT_BRACKET = 571,
|
||||||
IMAGECUBEARRAY = 572,
|
RIGHT_BRACKET = 572,
|
||||||
IIMAGECUBEARRAY = 573,
|
LEFT_BRACE = 573,
|
||||||
UIMAGECUBEARRAY = 574,
|
RIGHT_BRACE = 574,
|
||||||
IMAGE2DMS = 575,
|
DOT = 575,
|
||||||
IIMAGE2DMS = 576,
|
COMMA = 576,
|
||||||
UIMAGE2DMS = 577,
|
COLON = 577,
|
||||||
IMAGE2DMSARRAY = 578,
|
EQUAL = 578,
|
||||||
IIMAGE2DMSARRAY = 579,
|
SEMICOLON = 579,
|
||||||
UIMAGE2DMSARRAY = 580,
|
BANG = 580,
|
||||||
F16IMAGE1D = 581,
|
DASH = 581,
|
||||||
F16IMAGE2D = 582,
|
TILDE = 582,
|
||||||
F16IMAGE3D = 583,
|
PLUS = 583,
|
||||||
F16IMAGE2DRECT = 584,
|
STAR = 584,
|
||||||
F16IMAGECUBE = 585,
|
SLASH = 585,
|
||||||
F16IMAGE1DARRAY = 586,
|
PERCENT = 586,
|
||||||
F16IMAGE2DARRAY = 587,
|
LEFT_ANGLE = 587,
|
||||||
F16IMAGECUBEARRAY = 588,
|
RIGHT_ANGLE = 588,
|
||||||
F16IMAGEBUFFER = 589,
|
VERTICAL_BAR = 589,
|
||||||
F16IMAGE2DMS = 590,
|
CARET = 590,
|
||||||
F16IMAGE2DMSARRAY = 591,
|
AMPERSAND = 591,
|
||||||
STRUCT = 592,
|
QUESTION = 592,
|
||||||
VOID = 593,
|
INVARIANT = 593,
|
||||||
WHILE = 594,
|
HIGH_PRECISION = 594,
|
||||||
IDENTIFIER = 595,
|
MEDIUM_PRECISION = 595,
|
||||||
TYPE_NAME = 596,
|
LOW_PRECISION = 596,
|
||||||
FLOATCONSTANT = 597,
|
PRECISION = 597,
|
||||||
DOUBLECONSTANT = 598,
|
PACKED = 598,
|
||||||
INT16CONSTANT = 599,
|
RESOURCE = 599,
|
||||||
UINT16CONSTANT = 600,
|
SUPERP = 600,
|
||||||
INT32CONSTANT = 601,
|
FLOATCONSTANT = 601,
|
||||||
UINT32CONSTANT = 602,
|
INTCONSTANT = 602,
|
||||||
INTCONSTANT = 603,
|
UINTCONSTANT = 603,
|
||||||
UINTCONSTANT = 604,
|
BOOLCONSTANT = 604,
|
||||||
INT64CONSTANT = 605,
|
IDENTIFIER = 605,
|
||||||
UINT64CONSTANT = 606,
|
TYPE_NAME = 606,
|
||||||
BOOLCONSTANT = 607,
|
CENTROID = 607,
|
||||||
FLOAT16CONSTANT = 608,
|
IN = 608,
|
||||||
LEFT_OP = 609,
|
OUT = 609,
|
||||||
RIGHT_OP = 610,
|
INOUT = 610,
|
||||||
INC_OP = 611,
|
STRUCT = 611,
|
||||||
DEC_OP = 612,
|
VOID = 612,
|
||||||
LE_OP = 613,
|
WHILE = 613,
|
||||||
GE_OP = 614,
|
BREAK = 614,
|
||||||
EQ_OP = 615,
|
CONTINUE = 615,
|
||||||
NE_OP = 616,
|
DO = 616,
|
||||||
AND_OP = 617,
|
ELSE = 617,
|
||||||
OR_OP = 618,
|
FOR = 618,
|
||||||
XOR_OP = 619,
|
IF = 619,
|
||||||
MUL_ASSIGN = 620,
|
DISCARD = 620,
|
||||||
DIV_ASSIGN = 621,
|
RETURN = 621,
|
||||||
ADD_ASSIGN = 622,
|
SWITCH = 622,
|
||||||
MOD_ASSIGN = 623,
|
CASE = 623,
|
||||||
LEFT_ASSIGN = 624,
|
DEFAULT = 624,
|
||||||
RIGHT_ASSIGN = 625,
|
UNIFORM = 625,
|
||||||
AND_ASSIGN = 626,
|
SHARED = 626,
|
||||||
XOR_ASSIGN = 627,
|
BUFFER = 627,
|
||||||
OR_ASSIGN = 628,
|
FLAT = 628,
|
||||||
SUB_ASSIGN = 629,
|
SMOOTH = 629,
|
||||||
LEFT_PAREN = 630,
|
LAYOUT = 630,
|
||||||
RIGHT_PAREN = 631,
|
DOUBLECONSTANT = 631,
|
||||||
LEFT_BRACKET = 632,
|
INT16CONSTANT = 632,
|
||||||
RIGHT_BRACKET = 633,
|
UINT16CONSTANT = 633,
|
||||||
LEFT_BRACE = 634,
|
FLOAT16CONSTANT = 634,
|
||||||
RIGHT_BRACE = 635,
|
INT32CONSTANT = 635,
|
||||||
DOT = 636,
|
UINT32CONSTANT = 636,
|
||||||
COMMA = 637,
|
INT64CONSTANT = 637,
|
||||||
COLON = 638,
|
UINT64CONSTANT = 638,
|
||||||
EQUAL = 639,
|
SUBROUTINE = 639,
|
||||||
SEMICOLON = 640,
|
DEMOTE = 640,
|
||||||
BANG = 641,
|
PAYLOADNV = 641,
|
||||||
DASH = 642,
|
PAYLOADINNV = 642,
|
||||||
TILDE = 643,
|
HITATTRNV = 643,
|
||||||
PLUS = 644,
|
CALLDATANV = 644,
|
||||||
STAR = 645,
|
CALLDATAINNV = 645,
|
||||||
SLASH = 646,
|
PATCH = 646,
|
||||||
PERCENT = 647,
|
SAMPLE = 647,
|
||||||
LEFT_ANGLE = 648,
|
NONUNIFORM = 648,
|
||||||
RIGHT_ANGLE = 649,
|
COHERENT = 649,
|
||||||
VERTICAL_BAR = 650,
|
VOLATILE = 650,
|
||||||
CARET = 651,
|
RESTRICT = 651,
|
||||||
AMPERSAND = 652,
|
READONLY = 652,
|
||||||
QUESTION = 653,
|
WRITEONLY = 653,
|
||||||
INVARIANT = 654,
|
DEVICECOHERENT = 654,
|
||||||
PRECISE = 655,
|
QUEUEFAMILYCOHERENT = 655,
|
||||||
HIGH_PRECISION = 656,
|
WORKGROUPCOHERENT = 656,
|
||||||
MEDIUM_PRECISION = 657,
|
SUBGROUPCOHERENT = 657,
|
||||||
LOW_PRECISION = 658,
|
NONPRIVATE = 658,
|
||||||
PRECISION = 659,
|
NOPERSPECTIVE = 659,
|
||||||
PACKED = 660,
|
EXPLICITINTERPAMD = 660,
|
||||||
RESOURCE = 661,
|
PERVERTEXNV = 661,
|
||||||
SUPERP = 662
|
PERPRIMITIVENV = 662,
|
||||||
|
PERVIEWNV = 663,
|
||||||
|
PERTASKNV = 664,
|
||||||
|
PRECISE = 665
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -458,7 +461,7 @@ extern int yydebug;
|
|||||||
|
|
||||||
union YYSTYPE
|
union YYSTYPE
|
||||||
{
|
{
|
||||||
#line 71 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
#line 96 "MachineIndependent/glslang.y" /* yacc.c:1909 */
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
glslang::TSourceLoc loc;
|
glslang::TSourceLoc loc;
|
||||||
@@ -494,7 +497,7 @@ union YYSTYPE
|
|||||||
glslang::TArraySizes* typeParameters;
|
glslang::TArraySizes* typeParameters;
|
||||||
} interm;
|
} interm;
|
||||||
|
|
||||||
#line 498 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
#line 501 "MachineIndependent/glslang_tab.cpp.h" /* yacc.c:1909 */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef union YYSTYPE YYSTYPE;
|
typedef union YYSTYPE YYSTYPE;
|
||||||
|
|||||||
@@ -35,6 +35,8 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
#include "localintermediate.h"
|
#include "localintermediate.h"
|
||||||
#include "../Include/InfoSink.h"
|
#include "../Include/InfoSink.h"
|
||||||
|
|
||||||
@@ -174,7 +176,7 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
|
|||||||
case EOpIndexIndirect: out.debug << "indirect index"; break;
|
case EOpIndexIndirect: out.debug << "indirect index"; break;
|
||||||
case EOpIndexDirectStruct:
|
case EOpIndexDirectStruct:
|
||||||
{
|
{
|
||||||
bool reference = node->getLeft()->getType().getBasicType() == EbtReference;
|
bool reference = node->getLeft()->getType().isReference();
|
||||||
const TTypeList *members = reference ? node->getLeft()->getType().getReferentType()->getStruct() : node->getLeft()->getType().getStruct();
|
const TTypeList *members = reference ? node->getLeft()->getType().getReferentType()->getStruct() : node->getLeft()->getType().getStruct();
|
||||||
out.debug << (*members)[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName();
|
out.debug << (*members)[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName();
|
||||||
out.debug << ": direct index for structure"; break;
|
out.debug << ": direct index for structure"; break;
|
||||||
@@ -211,6 +213,13 @@ bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
|
|||||||
case EOpLogicalXor: out.debug << "logical-xor"; break;
|
case EOpLogicalXor: out.debug << "logical-xor"; break;
|
||||||
case EOpLogicalAnd: out.debug << "logical-and"; break;
|
case EOpLogicalAnd: out.debug << "logical-and"; break;
|
||||||
|
|
||||||
|
case EOpAbsDifference: out.debug << "absoluteDifference"; break;
|
||||||
|
case EOpAddSaturate: out.debug << "addSaturate"; break;
|
||||||
|
case EOpSubSaturate: out.debug << "subtractSaturate"; break;
|
||||||
|
case EOpAverage: out.debug << "average"; break;
|
||||||
|
case EOpAverageRounded: out.debug << "averageRounded"; break;
|
||||||
|
case EOpMul32x16: out.debug << "multiply32x16"; break;
|
||||||
|
|
||||||
default: out.debug << "<unknown op>";
|
default: out.debug << "<unknown op>";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -555,6 +564,9 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
|||||||
case EOpFindLSB: out.debug << "findLSB"; break;
|
case EOpFindLSB: out.debug << "findLSB"; break;
|
||||||
case EOpFindMSB: out.debug << "findMSB"; break;
|
case EOpFindMSB: out.debug << "findMSB"; break;
|
||||||
|
|
||||||
|
case EOpCountLeadingZeros: out.debug << "countLeadingZeros"; break;
|
||||||
|
case EOpCountTrailingZeros: out.debug << "countTrailingZeros"; break;
|
||||||
|
|
||||||
case EOpNoise: out.debug << "noise"; break;
|
case EOpNoise: out.debug << "noise"; break;
|
||||||
|
|
||||||
case EOpBallot: out.debug << "ballot"; break;
|
case EOpBallot: out.debug << "ballot"; break;
|
||||||
@@ -615,7 +627,6 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
|||||||
case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
|
case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
|
||||||
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
|
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break;
|
case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break;
|
||||||
case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break;
|
case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break;
|
||||||
case EOpSubgroupPartitionedMul: out.debug << "subgroupPartitionedMulNV"; break;
|
case EOpSubgroupPartitionedMul: out.debug << "subgroupPartitionedMulNV"; break;
|
||||||
@@ -638,7 +649,6 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
|||||||
case EOpSubgroupPartitionedExclusiveAnd: out.debug << "subgroupPartitionedExclusiveAndNV"; break;
|
case EOpSubgroupPartitionedExclusiveAnd: out.debug << "subgroupPartitionedExclusiveAndNV"; break;
|
||||||
case EOpSubgroupPartitionedExclusiveOr: out.debug << "subgroupPartitionedExclusiveOrNV"; break;
|
case EOpSubgroupPartitionedExclusiveOr: out.debug << "subgroupPartitionedExclusiveOrNV"; break;
|
||||||
case EOpSubgroupPartitionedExclusiveXor: out.debug << "subgroupPartitionedExclusiveXorNV"; break;
|
case EOpSubgroupPartitionedExclusiveXor: out.debug << "subgroupPartitionedExclusiveXorNV"; break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpClip: out.debug << "clip"; break;
|
case EOpClip: out.debug << "clip"; break;
|
||||||
case EOpIsFinite: out.debug << "isfinite"; break;
|
case EOpIsFinite: out.debug << "isfinite"; break;
|
||||||
@@ -648,7 +658,6 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
|||||||
|
|
||||||
case EOpSparseTexelsResident: out.debug << "sparseTexelsResident"; break;
|
case EOpSparseTexelsResident: out.debug << "sparseTexelsResident"; break;
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpMinInvocations: out.debug << "minInvocations"; break;
|
case EOpMinInvocations: out.debug << "minInvocations"; break;
|
||||||
case EOpMaxInvocations: out.debug << "maxInvocations"; break;
|
case EOpMaxInvocations: out.debug << "maxInvocations"; break;
|
||||||
case EOpAddInvocations: out.debug << "addInvocations"; break;
|
case EOpAddInvocations: out.debug << "addInvocations"; break;
|
||||||
@@ -677,7 +686,6 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
|||||||
|
|
||||||
case EOpCubeFaceIndex: out.debug << "cubeFaceIndex"; break;
|
case EOpCubeFaceIndex: out.debug << "cubeFaceIndex"; break;
|
||||||
case EOpCubeFaceCoord: out.debug << "cubeFaceCoord"; break;
|
case EOpCubeFaceCoord: out.debug << "cubeFaceCoord"; break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
||||||
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
||||||
@@ -863,7 +871,6 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
|
|
||||||
case EOpReadInvocation: out.debug << "readInvocation"; break;
|
case EOpReadInvocation: out.debug << "readInvocation"; break;
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpSwizzleInvocations: out.debug << "swizzleInvocations"; break;
|
case EOpSwizzleInvocations: out.debug << "swizzleInvocations"; break;
|
||||||
case EOpSwizzleInvocationsMasked: out.debug << "swizzleInvocationsMasked"; break;
|
case EOpSwizzleInvocationsMasked: out.debug << "swizzleInvocationsMasked"; break;
|
||||||
case EOpWriteInvocation: out.debug << "writeInvocation"; break;
|
case EOpWriteInvocation: out.debug << "writeInvocation"; break;
|
||||||
@@ -871,9 +878,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
case EOpMin3: out.debug << "min3"; break;
|
case EOpMin3: out.debug << "min3"; break;
|
||||||
case EOpMax3: out.debug << "max3"; break;
|
case EOpMax3: out.debug << "max3"; break;
|
||||||
case EOpMid3: out.debug << "mid3"; break;
|
case EOpMid3: out.debug << "mid3"; break;
|
||||||
|
|
||||||
case EOpTime: out.debug << "time"; break;
|
case EOpTime: out.debug << "time"; break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpAtomicAdd: out.debug << "AtomicAdd"; break;
|
case EOpAtomicAdd: out.debug << "AtomicAdd"; break;
|
||||||
case EOpAtomicMin: out.debug << "AtomicMin"; break;
|
case EOpAtomicMin: out.debug << "AtomicMin"; break;
|
||||||
@@ -910,10 +915,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
case EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break;
|
case EOpImageAtomicCompSwap: out.debug << "imageAtomicCompSwap"; break;
|
||||||
case EOpImageAtomicLoad: out.debug << "imageAtomicLoad"; break;
|
case EOpImageAtomicLoad: out.debug << "imageAtomicLoad"; break;
|
||||||
case EOpImageAtomicStore: out.debug << "imageAtomicStore"; break;
|
case EOpImageAtomicStore: out.debug << "imageAtomicStore"; break;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpImageLoadLod: out.debug << "imageLoadLod"; break;
|
case EOpImageLoadLod: out.debug << "imageLoadLod"; break;
|
||||||
case EOpImageStoreLod: out.debug << "imageStoreLod"; break;
|
case EOpImageStoreLod: out.debug << "imageStoreLod"; break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpTextureQuerySize: out.debug << "textureSize"; break;
|
case EOpTextureQuerySize: out.debug << "textureSize"; break;
|
||||||
case EOpTextureQueryLod: out.debug << "textureQueryLod"; break;
|
case EOpTextureQueryLod: out.debug << "textureQueryLod"; break;
|
||||||
@@ -940,11 +943,9 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
case EOpTextureOffsetClamp: out.debug << "textureOffsetClamp"; break;
|
case EOpTextureOffsetClamp: out.debug << "textureOffsetClamp"; break;
|
||||||
case EOpTextureGradClamp: out.debug << "textureGradClamp"; break;
|
case EOpTextureGradClamp: out.debug << "textureGradClamp"; break;
|
||||||
case EOpTextureGradOffsetClamp: out.debug << "textureGradOffsetClamp"; break;
|
case EOpTextureGradOffsetClamp: out.debug << "textureGradOffsetClamp"; break;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpTextureGatherLod: out.debug << "textureGatherLod"; break;
|
case EOpTextureGatherLod: out.debug << "textureGatherLod"; break;
|
||||||
case EOpTextureGatherLodOffset: out.debug << "textureGatherLodOffset"; break;
|
case EOpTextureGatherLodOffset: out.debug << "textureGatherLodOffset"; break;
|
||||||
case EOpTextureGatherLodOffsets: out.debug << "textureGatherLodOffsets"; break;
|
case EOpTextureGatherLodOffsets: out.debug << "textureGatherLodOffsets"; break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpSparseTexture: out.debug << "sparseTexture"; break;
|
case EOpSparseTexture: out.debug << "sparseTexture"; break;
|
||||||
case EOpSparseTextureOffset: out.debug << "sparseTextureOffset"; break;
|
case EOpSparseTextureOffset: out.debug << "sparseTextureOffset"; break;
|
||||||
@@ -962,19 +963,15 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
case EOpSparseTextureOffsetClamp: out.debug << "sparseTextureOffsetClamp"; break;
|
case EOpSparseTextureOffsetClamp: out.debug << "sparseTextureOffsetClamp"; break;
|
||||||
case EOpSparseTextureGradClamp: out.debug << "sparseTextureGradClamp"; break;
|
case EOpSparseTextureGradClamp: out.debug << "sparseTextureGradClamp"; break;
|
||||||
case EOpSparseTextureGradOffsetClamp: out.debug << "sparseTextureGradOffsetClam"; break;
|
case EOpSparseTextureGradOffsetClamp: out.debug << "sparseTextureGradOffsetClam"; break;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpSparseTextureGatherLod: out.debug << "sparseTextureGatherLod"; break;
|
case EOpSparseTextureGatherLod: out.debug << "sparseTextureGatherLod"; break;
|
||||||
case EOpSparseTextureGatherLodOffset: out.debug << "sparseTextureGatherLodOffset"; break;
|
case EOpSparseTextureGatherLodOffset: out.debug << "sparseTextureGatherLodOffset"; break;
|
||||||
case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break;
|
case EOpSparseTextureGatherLodOffsets: out.debug << "sparseTextureGatherLodOffsets"; break;
|
||||||
case EOpSparseImageLoadLod: out.debug << "sparseImageLoadLod"; break;
|
case EOpSparseImageLoadLod: out.debug << "sparseImageLoadLod"; break;
|
||||||
#endif
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EOpImageSampleFootprintNV: out.debug << "imageSampleFootprintNV"; break;
|
case EOpImageSampleFootprintNV: out.debug << "imageSampleFootprintNV"; break;
|
||||||
case EOpImageSampleFootprintClampNV: out.debug << "imageSampleFootprintClampNV"; break;
|
case EOpImageSampleFootprintClampNV: out.debug << "imageSampleFootprintClampNV"; break;
|
||||||
case EOpImageSampleFootprintLodNV: out.debug << "imageSampleFootprintLodNV"; break;
|
case EOpImageSampleFootprintLodNV: out.debug << "imageSampleFootprintLodNV"; break;
|
||||||
case EOpImageSampleFootprintGradNV: out.debug << "imageSampleFootprintGradNV"; break;
|
case EOpImageSampleFootprintGradNV: out.debug << "imageSampleFootprintGradNV"; break;
|
||||||
case EOpImageSampleFootprintGradClampNV: out.debug << "mageSampleFootprintGradClampNV"; break;
|
case EOpImageSampleFootprintGradClampNV: out.debug << "mageSampleFootprintGradClampNV"; break;
|
||||||
#endif
|
|
||||||
case EOpAddCarry: out.debug << "addCarry"; break;
|
case EOpAddCarry: out.debug << "addCarry"; break;
|
||||||
case EOpSubBorrow: out.debug << "subBorrow"; break;
|
case EOpSubBorrow: out.debug << "subBorrow"; break;
|
||||||
case EOpUMulExtended: out.debug << "uMulExtended"; break;
|
case EOpUMulExtended: out.debug << "uMulExtended"; break;
|
||||||
@@ -988,9 +985,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
|
|
||||||
case EOpInterpolateAtSample: out.debug << "interpolateAtSample"; break;
|
case EOpInterpolateAtSample: out.debug << "interpolateAtSample"; break;
|
||||||
case EOpInterpolateAtOffset: out.debug << "interpolateAtOffset"; break;
|
case EOpInterpolateAtOffset: out.debug << "interpolateAtOffset"; break;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EOpInterpolateAtVertex: out.debug << "interpolateAtVertex"; break;
|
case EOpInterpolateAtVertex: out.debug << "interpolateAtVertex"; break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpSinCos: out.debug << "sincos"; break;
|
case EOpSinCos: out.debug << "sincos"; break;
|
||||||
case EOpGenMul: out.debug << "mul"; break;
|
case EOpGenMul: out.debug << "mul"; break;
|
||||||
@@ -1057,22 +1052,45 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node
|
|||||||
case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
|
case EOpSubgroupQuadSwapVertical: out.debug << "subgroupQuadSwapVertical"; break;
|
||||||
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
|
case EOpSubgroupQuadSwapDiagonal: out.debug << "subgroupQuadSwapDiagonal"; break;
|
||||||
|
|
||||||
|
case EOpSubgroupPartition: out.debug << "subgroupPartitionNV"; break;
|
||||||
|
case EOpSubgroupPartitionedAdd: out.debug << "subgroupPartitionedAddNV"; break;
|
||||||
|
case EOpSubgroupPartitionedMul: out.debug << "subgroupPartitionedMulNV"; break;
|
||||||
|
case EOpSubgroupPartitionedMin: out.debug << "subgroupPartitionedMinNV"; break;
|
||||||
|
case EOpSubgroupPartitionedMax: out.debug << "subgroupPartitionedMaxNV"; break;
|
||||||
|
case EOpSubgroupPartitionedAnd: out.debug << "subgroupPartitionedAndNV"; break;
|
||||||
|
case EOpSubgroupPartitionedOr: out.debug << "subgroupPartitionedOrNV"; break;
|
||||||
|
case EOpSubgroupPartitionedXor: out.debug << "subgroupPartitionedXorNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveAdd: out.debug << "subgroupPartitionedInclusiveAddNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveMul: out.debug << "subgroupPartitionedInclusiveMulNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveMin: out.debug << "subgroupPartitionedInclusiveMinNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveMax: out.debug << "subgroupPartitionedInclusiveMaxNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveAnd: out.debug << "subgroupPartitionedInclusiveAndNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveOr: out.debug << "subgroupPartitionedInclusiveOrNV"; break;
|
||||||
|
case EOpSubgroupPartitionedInclusiveXor: out.debug << "subgroupPartitionedInclusiveXorNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveAdd: out.debug << "subgroupPartitionedExclusiveAddNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveMul: out.debug << "subgroupPartitionedExclusiveMulNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveMin: out.debug << "subgroupPartitionedExclusiveMinNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveMax: out.debug << "subgroupPartitionedExclusiveMaxNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveAnd: out.debug << "subgroupPartitionedExclusiveAndNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveOr: out.debug << "subgroupPartitionedExclusiveOrNV"; break;
|
||||||
|
case EOpSubgroupPartitionedExclusiveXor: out.debug << "subgroupPartitionedExclusiveXorNV"; break;
|
||||||
|
|
||||||
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
case EOpSubpassLoad: out.debug << "subpassLoad"; break;
|
||||||
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EOpTraceNV: out.debug << "traceNV"; break;
|
case EOpTraceNV: out.debug << "traceNV"; break;
|
||||||
case EOpReportIntersectionNV: out.debug << "reportIntersectionNV"; break;
|
case EOpReportIntersectionNV: out.debug << "reportIntersectionNV"; break;
|
||||||
case EOpIgnoreIntersectionNV: out.debug << "ignoreIntersectionNV"; break;
|
case EOpIgnoreIntersectionNV: out.debug << "ignoreIntersectionNV"; break;
|
||||||
case EOpTerminateRayNV: out.debug << "terminateRayNV"; break;
|
case EOpTerminateRayNV: out.debug << "terminateRayNV"; break;
|
||||||
case EOpExecuteCallableNV: out.debug << "executeCallableNV"; break;
|
case EOpExecuteCallableNV: out.debug << "executeCallableNV"; break;
|
||||||
case EOpWritePackedPrimitiveIndices4x8NV: out.debug << "writePackedPrimitiveIndices4x8NV"; break;
|
case EOpWritePackedPrimitiveIndices4x8NV: out.debug << "writePackedPrimitiveIndices4x8NV"; break;
|
||||||
#endif
|
|
||||||
|
|
||||||
case EOpCooperativeMatrixLoad: out.debug << "Load cooperative matrix"; break;
|
case EOpCooperativeMatrixLoad: out.debug << "Load cooperative matrix"; break;
|
||||||
case EOpCooperativeMatrixStore: out.debug << "Store cooperative matrix"; break;
|
case EOpCooperativeMatrixStore: out.debug << "Store cooperative matrix"; break;
|
||||||
case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices"; break;
|
case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices"; break;
|
||||||
|
|
||||||
|
case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break;
|
||||||
|
|
||||||
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
default: out.debug.message(EPrefixError, "Bad aggregation op");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1367,6 +1385,7 @@ bool TOutputTraverser::visitBranch(TVisit /* visit*/, TIntermBranch* node)
|
|||||||
case EOpContinue: out.debug << "Branch: Continue"; break;
|
case EOpContinue: out.debug << "Branch: Continue"; break;
|
||||||
case EOpReturn: out.debug << "Branch: Return"; break;
|
case EOpReturn: out.debug << "Branch: Return"; break;
|
||||||
case EOpCase: out.debug << "case: "; break;
|
case EOpCase: out.debug << "case: "; break;
|
||||||
|
case EOpDemote: out.debug << "Demote"; break;
|
||||||
case EOpDefault: out.debug << "default: "; break;
|
case EOpDefault: out.debug << "default: "; break;
|
||||||
default: out.debug << "Branch: Unknown Branch"; break;
|
default: out.debug << "Branch: Unknown Branch"; break;
|
||||||
}
|
}
|
||||||
@@ -1477,18 +1496,17 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
|||||||
}
|
}
|
||||||
infoSink.debug << "\n";
|
infoSink.debug << "\n";
|
||||||
}
|
}
|
||||||
|
if (interlockOrdering != EioNone)
|
||||||
|
infoSink.debug << "interlock ordering = " << TQualifier::getInterlockOrderingString(interlockOrdering) << "\n";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EShLangMeshNV:
|
case EShLangMeshNV:
|
||||||
infoSink.debug << "max_vertices = " << vertices << "\n";
|
infoSink.debug << "max_vertices = " << vertices << "\n";
|
||||||
infoSink.debug << "max_primitives = " << primitives << "\n";
|
infoSink.debug << "max_primitives = " << primitives << "\n";
|
||||||
infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
|
infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
|
||||||
// Fall through
|
// Fall through
|
||||||
|
|
||||||
case EShLangTaskNV:
|
case EShLangTaskNV:
|
||||||
// Fall through
|
// Fall through
|
||||||
#endif
|
|
||||||
case EShLangCompute:
|
case EShLangCompute:
|
||||||
infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n";
|
infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n";
|
||||||
{
|
{
|
||||||
@@ -1517,3 +1535,5 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // not GLSLANG_WEB
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -33,11 +33,15 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
#ifndef _IOMAPPER_INCLUDED
|
#ifndef _IOMAPPER_INCLUDED
|
||||||
#define _IOMAPPER_INCLUDED
|
#define _IOMAPPER_INCLUDED
|
||||||
|
|
||||||
#include "../Public/ShaderLang.h"
|
#include <cstdint>
|
||||||
|
#include "LiveTraverser.h"
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
//
|
//
|
||||||
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
|
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
|
||||||
//
|
//
|
||||||
@@ -47,17 +51,249 @@ class TInfoSink;
|
|||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
class TIntermediate;
|
class TIntermediate;
|
||||||
|
struct TVarEntryInfo {
|
||||||
|
int id;
|
||||||
|
TIntermSymbol* symbol;
|
||||||
|
bool live;
|
||||||
|
int newBinding;
|
||||||
|
int newSet;
|
||||||
|
int newLocation;
|
||||||
|
int newComponent;
|
||||||
|
int newIndex;
|
||||||
|
EShLanguage stage;
|
||||||
|
struct TOrderById {
|
||||||
|
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TOrderByPriority {
|
||||||
|
// ordering:
|
||||||
|
// 1) has both binding and set
|
||||||
|
// 2) has binding but no set
|
||||||
|
// 3) has no binding but set
|
||||||
|
// 4) has no binding and no set
|
||||||
|
inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) {
|
||||||
|
const TQualifier& lq = l.symbol->getQualifier();
|
||||||
|
const TQualifier& rq = r.symbol->getQualifier();
|
||||||
|
|
||||||
|
// simple rules:
|
||||||
|
// has binding gives 2 points
|
||||||
|
// has set gives 1 point
|
||||||
|
// who has the most points is more important.
|
||||||
|
int lPoints = (lq.hasBinding() ? 2 : 0) + (lq.hasSet() ? 1 : 0);
|
||||||
|
int rPoints = (rq.hasBinding() ? 2 : 0) + (rq.hasSet() ? 1 : 0);
|
||||||
|
|
||||||
|
if (lPoints == rPoints)
|
||||||
|
return l.id < r.id;
|
||||||
|
return lPoints > rPoints;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Base class for shared TIoMapResolver services, used by several derivations.
|
||||||
|
struct TDefaultIoResolverBase : public glslang::TIoMapResolver {
|
||||||
|
public:
|
||||||
|
TDefaultIoResolverBase(const TIntermediate& intermediate);
|
||||||
|
typedef std::vector<int> TSlotSet;
|
||||||
|
typedef std::unordered_map<int, TSlotSet> TSlotSetMap;
|
||||||
|
|
||||||
|
// grow the reflection stage by stage
|
||||||
|
void notifyBinding(EShLanguage, TVarEntryInfo& /*ent*/) override {}
|
||||||
|
void notifyInOut(EShLanguage, TVarEntryInfo& /*ent*/) override {}
|
||||||
|
void beginNotifications(EShLanguage) override {}
|
||||||
|
void endNotifications(EShLanguage) override {}
|
||||||
|
void beginResolve(EShLanguage) override {}
|
||||||
|
void endResolve(EShLanguage) override {}
|
||||||
|
void beginCollect(EShLanguage) override {}
|
||||||
|
void endCollect(EShLanguage) override {}
|
||||||
|
void reserverResourceSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {}
|
||||||
|
void reserverStorageSlot(TVarEntryInfo& /*ent*/, TInfoSink& /*infoSink*/) override {}
|
||||||
|
int getBaseBinding(TResourceType res, unsigned int set) const;
|
||||||
|
const std::vector<std::string>& getResourceSetBinding() const;
|
||||||
|
virtual TResourceType getResourceType(const glslang::TType& type) = 0;
|
||||||
|
bool doAutoBindingMapping() const;
|
||||||
|
bool doAutoLocationMapping() const;
|
||||||
|
TSlotSet::iterator findSlot(int set, int slot);
|
||||||
|
bool checkEmpty(int set, int slot);
|
||||||
|
bool validateInOut(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; }
|
||||||
|
int reserveSlot(int set, int slot, int size = 1);
|
||||||
|
int getFreeSlot(int set, int base, int size = 1);
|
||||||
|
int resolveSet(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
|
||||||
|
int resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
|
||||||
|
int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override;
|
||||||
|
int resolveInOutComponent(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
|
||||||
|
int resolveInOutIndex(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
|
||||||
|
void addStage(EShLanguage stage) override {
|
||||||
|
if (stage < EShLangCount)
|
||||||
|
stageMask[stage] = true;
|
||||||
|
}
|
||||||
|
uint32_t computeTypeLocationSize(const TType& type, EShLanguage stage);
|
||||||
|
|
||||||
|
TSlotSetMap slots;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
TDefaultIoResolverBase(TDefaultIoResolverBase&);
|
||||||
|
TDefaultIoResolverBase& operator=(TDefaultIoResolverBase&);
|
||||||
|
const TIntermediate& intermediate;
|
||||||
|
int nextUniformLocation;
|
||||||
|
int nextInputLocation;
|
||||||
|
int nextOutputLocation;
|
||||||
|
bool stageMask[EShLangCount + 1];
|
||||||
|
// Return descriptor set specific base if there is one, and the generic base otherwise.
|
||||||
|
int selectBaseBinding(int base, int descriptorSetBase) const {
|
||||||
|
return descriptorSetBase != -1 ? descriptorSetBase : base;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getLayoutSet(const glslang::TType& type) {
|
||||||
|
if (type.getQualifier().hasSet())
|
||||||
|
return type.getQualifier().layoutSet;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isSamplerType(const glslang::TType& type) {
|
||||||
|
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isPureSampler();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isTextureType(const glslang::TType& type) {
|
||||||
|
return (type.getBasicType() == glslang::EbtSampler &&
|
||||||
|
(type.getSampler().isTexture() || type.getSampler().isSubpass()));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isUboType(const glslang::TType& type) {
|
||||||
|
return type.getQualifier().storage == EvqUniform;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isImageType(const glslang::TType& type) {
|
||||||
|
return type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool isSsboType(const glslang::TType& type) {
|
||||||
|
return type.getQualifier().storage == EvqBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if this is a SRV (shader resource view) type:
|
||||||
|
static bool isSrvType(const glslang::TType& type) {
|
||||||
|
return isTextureType(type) || type.getQualifier().storage == EvqBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if this is a UAV (unordered access view) type:
|
||||||
|
static bool isUavType(const glslang::TType& type) {
|
||||||
|
if (type.getQualifier().isReadOnly())
|
||||||
|
return false;
|
||||||
|
return (type.getBasicType() == glslang::EbtSampler && type.getSampler().isImage()) ||
|
||||||
|
(type.getQualifier().storage == EvqBuffer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Defaulf I/O resolver for OpenGL
|
||||||
|
struct TDefaultGlslIoResolver : public TDefaultIoResolverBase {
|
||||||
|
public:
|
||||||
|
typedef std::map<TString, int> TVarSlotMap; // <resourceName, location/binding>
|
||||||
|
typedef std::map<int, TVarSlotMap> TSlotMap; // <resourceKey, TVarSlotMap>
|
||||||
|
TDefaultGlslIoResolver(const TIntermediate& intermediate);
|
||||||
|
bool validateBinding(EShLanguage /*stage*/, TVarEntryInfo& /*ent*/) override { return true; }
|
||||||
|
TResourceType getResourceType(const glslang::TType& type) override;
|
||||||
|
int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) override;
|
||||||
|
int resolveUniformLocation(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
|
||||||
|
int resolveBinding(EShLanguage /*stage*/, TVarEntryInfo& ent) override;
|
||||||
|
void beginResolve(EShLanguage /*stage*/) override;
|
||||||
|
void endResolve(EShLanguage stage) override;
|
||||||
|
void beginCollect(EShLanguage) override;
|
||||||
|
void endCollect(EShLanguage) override;
|
||||||
|
void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
|
||||||
|
void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) override;
|
||||||
|
// in/out symbol and uniform symbol are stored in the same resourceSlotMap, the storage key is used to identify each type of symbol.
|
||||||
|
// We use stage and storage qualifier to construct a storage key. it can help us identify the same storage resource used in different stage.
|
||||||
|
// if a resource is a program resource and we don't need know it usage stage, we can use same stage to build storage key.
|
||||||
|
// Note: both stage and type must less then 0xffff.
|
||||||
|
int buildStorageKey(EShLanguage stage, TStorageQualifier type) {
|
||||||
|
assert(static_cast<uint32_t>(stage) <= 0x0000ffff && static_cast<uint32_t>(type) <= 0x0000ffff);
|
||||||
|
return (stage << 16) | type;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Use for mark pre stage, to get more interface symbol information.
|
||||||
|
EShLanguage preStage;
|
||||||
|
// Use for mark current shader stage for resolver
|
||||||
|
EShLanguage currentStage;
|
||||||
|
// Slot map for storage resource(location of uniform and interface symbol) It's a program share slot
|
||||||
|
TSlotMap resourceSlotMap;
|
||||||
|
// Slot map for other resource(image, ubo, ssbo), It's a program share slot.
|
||||||
|
TSlotMap storageSlotMap;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<TString, TVarEntryInfo> TVarLiveMap;
|
||||||
|
|
||||||
|
// override function "operator=", if a vector<const _Kty, _Ty> being sort,
|
||||||
|
// when use vc++, the sort function will call :
|
||||||
|
// pair& operator=(const pair<_Other1, _Other2>& _Right)
|
||||||
|
// {
|
||||||
|
// first = _Right.first;
|
||||||
|
// second = _Right.second;
|
||||||
|
// return (*this);
|
||||||
|
// }
|
||||||
|
// that will make a const type handing on left.
|
||||||
|
// override this function can avoid a compiler error.
|
||||||
|
// In the future, if the vc++ compiler can handle such a situation,
|
||||||
|
// this part of the code will be removed.
|
||||||
|
struct TVarLivePair : std::pair<const TString, TVarEntryInfo> {
|
||||||
|
TVarLivePair(std::pair<const TString, TVarEntryInfo>& _Right) : pair(_Right.first, _Right.second) {}
|
||||||
|
TVarLivePair& operator=(const TVarLivePair& _Right) {
|
||||||
|
const_cast<TString&>(first) = _Right.first;
|
||||||
|
second = _Right.second;
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
typedef std::vector<TVarLivePair> TVarLiveVector;
|
||||||
|
|
||||||
// I/O mapper
|
// I/O mapper
|
||||||
class TIoMapper {
|
class TIoMapper {
|
||||||
public:
|
public:
|
||||||
TIoMapper() {}
|
TIoMapper() {}
|
||||||
virtual ~TIoMapper() {}
|
virtual ~TIoMapper() {}
|
||||||
|
|
||||||
// grow the reflection stage by stage
|
// grow the reflection stage by stage
|
||||||
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*);
|
bool virtual addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*);
|
||||||
|
bool virtual doMap(TIoMapResolver*, TInfoSink&) { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// I/O mapper for OpenGL
|
||||||
|
class TGlslIoMapper : public TIoMapper {
|
||||||
|
public:
|
||||||
|
TGlslIoMapper() {
|
||||||
|
memset(inVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
|
||||||
|
memset(outVarMaps, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
|
||||||
|
memset(uniformVarMap, 0, sizeof(TVarLiveMap*) * (EShLangCount + 1));
|
||||||
|
memset(intermediates, 0, sizeof(TIntermediate*) * (EShLangCount + 1));
|
||||||
|
}
|
||||||
|
virtual ~TGlslIoMapper() {
|
||||||
|
for (size_t stage = 0; stage < EShLangCount; stage++) {
|
||||||
|
if (inVarMaps[stage] != nullptr) {
|
||||||
|
delete inVarMaps[stage];
|
||||||
|
inVarMaps[stage] = nullptr;
|
||||||
|
}
|
||||||
|
if (outVarMaps[stage] != nullptr) {
|
||||||
|
delete outVarMaps[stage];
|
||||||
|
outVarMaps[stage] = nullptr;
|
||||||
|
}
|
||||||
|
if (uniformVarMap[stage] != nullptr) {
|
||||||
|
delete uniformVarMap[stage];
|
||||||
|
uniformVarMap[stage] = nullptr;
|
||||||
|
}
|
||||||
|
if (intermediates[stage] != nullptr)
|
||||||
|
intermediates[stage] = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// grow the reflection stage by stage
|
||||||
|
bool addStage(EShLanguage, TIntermediate&, TInfoSink&, TIoMapResolver*) override;
|
||||||
|
bool doMap(TIoMapResolver*, TInfoSink&) override;
|
||||||
|
TVarLiveMap *inVarMaps[EShLangCount], *outVarMaps[EShLangCount],
|
||||||
|
*uniformVarMap[EShLangCount];
|
||||||
|
TIntermediate* intermediates[EShLangCount];
|
||||||
|
bool hadError = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // _IOMAPPER_INCLUDED
|
#endif // _IOMAPPER_INCLUDED
|
||||||
|
|
||||||
|
#endif // GLSLANG_WEB
|
||||||
|
|||||||
@@ -187,12 +187,14 @@ bool TIndexTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
|
|||||||
//
|
//
|
||||||
void TParseContext::constantIndexExpressionCheck(TIntermNode* index)
|
void TParseContext::constantIndexExpressionCheck(TIntermNode* index)
|
||||||
{
|
{
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
TIndexTraverser it(inductiveLoopIds);
|
TIndexTraverser it(inductiveLoopIds);
|
||||||
|
|
||||||
index->traverse(&it);
|
index->traverse(&it);
|
||||||
|
|
||||||
if (it.bad)
|
if (it.bad)
|
||||||
error(it.badLoc, "Non-constant-index-expression", "limitations", "");
|
error(it.badLoc, "Non-constant-index-expression", "limitations", "");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|||||||
@@ -56,8 +56,10 @@ namespace glslang {
|
|||||||
//
|
//
|
||||||
void TIntermediate::error(TInfoSink& infoSink, const char* message)
|
void TIntermediate::error(TInfoSink& infoSink, const char* message)
|
||||||
{
|
{
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
infoSink.info.prefix(EPrefixError);
|
infoSink.info.prefix(EPrefixError);
|
||||||
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
|
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
|
||||||
|
#endif
|
||||||
|
|
||||||
++numErrors;
|
++numErrors;
|
||||||
}
|
}
|
||||||
@@ -65,8 +67,10 @@ void TIntermediate::error(TInfoSink& infoSink, const char* message)
|
|||||||
// Link-time warning.
|
// Link-time warning.
|
||||||
void TIntermediate::warn(TInfoSink& infoSink, const char* message)
|
void TIntermediate::warn(TInfoSink& infoSink, const char* message)
|
||||||
{
|
{
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
infoSink.info.prefix(EPrefixWarning);
|
infoSink.info.prefix(EPrefixWarning);
|
||||||
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
|
infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block
|
// TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block
|
||||||
@@ -78,9 +82,11 @@ void TIntermediate::warn(TInfoSink& infoSink, const char* message)
|
|||||||
//
|
//
|
||||||
void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
{
|
{
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
mergeCallGraphs(infoSink, unit);
|
mergeCallGraphs(infoSink, unit);
|
||||||
mergeModes(infoSink, unit);
|
mergeModes(infoSink, unit);
|
||||||
mergeTrees(infoSink, unit);
|
mergeTrees(infoSink, unit);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
|
void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
|
||||||
@@ -98,6 +104,8 @@ void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end());
|
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_MAX(member) member = std::max(member, unit.member)
|
||||||
#define MERGE_TRUE(member) if (unit.member) member = unit.member;
|
#define MERGE_TRUE(member) if (unit.member) member = unit.member;
|
||||||
|
|
||||||
@@ -106,9 +114,9 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
if (language != unit.language)
|
if (language != unit.language)
|
||||||
error(infoSink, "stages must match when linking into a single stage");
|
error(infoSink, "stages must match when linking into a single stage");
|
||||||
|
|
||||||
if (source == EShSourceNone)
|
if (getSource() == EShSourceNone)
|
||||||
source = unit.source;
|
setSource(unit.getSource());
|
||||||
if (source != unit.source)
|
if (getSource() != unit.getSource())
|
||||||
error(infoSink, "can't link compilation units from different source languages");
|
error(infoSink, "can't link compilation units from different source languages");
|
||||||
|
|
||||||
if (treeRoot == nullptr) {
|
if (treeRoot == nullptr) {
|
||||||
@@ -116,7 +124,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
version = unit.version;
|
version = unit.version;
|
||||||
requestedExtensions = unit.requestedExtensions;
|
requestedExtensions = unit.requestedExtensions;
|
||||||
} else {
|
} else {
|
||||||
if ((profile == EEsProfile) != (unit.profile == EEsProfile))
|
if ((isEsProfile()) != (unit.isEsProfile()))
|
||||||
error(infoSink, "Cannot cross link ES and desktop profiles");
|
error(infoSink, "Cannot cross link ES and desktop profiles");
|
||||||
else if (unit.profile == ECompatibilityProfile)
|
else if (unit.profile == ECompatibilityProfile)
|
||||||
profile = ECompatibilityProfile;
|
profile = ECompatibilityProfile;
|
||||||
@@ -142,18 +150,13 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
if (vertices == TQualifier::layoutNotSet)
|
if (vertices == TQualifier::layoutNotSet)
|
||||||
vertices = unit.vertices;
|
vertices = unit.vertices;
|
||||||
else if (vertices != unit.vertices) {
|
else if (vertices != unit.vertices) {
|
||||||
if (language == EShLangGeometry
|
if (language == EShLangGeometry || language == EShLangMeshNV)
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
|| language == EShLangMeshNV
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
error(infoSink, "Contradictory layout max_vertices values");
|
error(infoSink, "Contradictory layout max_vertices values");
|
||||||
else if (language == EShLangTessControl)
|
else if (language == EShLangTessControl)
|
||||||
error(infoSink, "Contradictory layout vertices values");
|
error(infoSink, "Contradictory layout vertices values");
|
||||||
else
|
else
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
if (primitives == TQualifier::layoutNotSet)
|
if (primitives == TQualifier::layoutNotSet)
|
||||||
primitives = unit.primitives;
|
primitives = unit.primitives;
|
||||||
else if (primitives != unit.primitives) {
|
else if (primitives != unit.primitives) {
|
||||||
@@ -162,7 +165,6 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
else
|
else
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (inputPrimitive == ElgNone)
|
if (inputPrimitive == ElgNone)
|
||||||
inputPrimitive = unit.inputPrimitive;
|
inputPrimitive = unit.inputPrimitive;
|
||||||
@@ -190,12 +192,14 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
MERGE_TRUE(pointMode);
|
MERGE_TRUE(pointMode);
|
||||||
|
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
if (localSize[i] > 1)
|
if (!localSizeNotDefault[i] && unit.localSizeNotDefault[i]) {
|
||||||
localSize[i] = unit.localSize[i];
|
localSize[i] = unit.localSize[i];
|
||||||
|
localSizeNotDefault[i] = true;
|
||||||
|
}
|
||||||
else if (localSize[i] != unit.localSize[i])
|
else if (localSize[i] != unit.localSize[i])
|
||||||
error(infoSink, "Contradictory local size");
|
error(infoSink, "Contradictory local size");
|
||||||
|
|
||||||
if (localSizeSpecId[i] != TQualifier::layoutNotSet)
|
if (localSizeSpecId[i] == TQualifier::layoutNotSet)
|
||||||
localSizeSpecId[i] = unit.localSizeSpecId[i];
|
localSizeSpecId[i] = unit.localSizeSpecId[i];
|
||||||
else if (localSizeSpecId[i] != unit.localSizeSpecId[i])
|
else if (localSizeSpecId[i] != unit.localSizeSpecId[i])
|
||||||
error(infoSink, "Contradictory local size specialization ids");
|
error(infoSink, "Contradictory local size specialization ids");
|
||||||
@@ -224,21 +228,16 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
xfbBuffers[b].implicitStride = std::max(xfbBuffers[b].implicitStride, unit.xfbBuffers[b].implicitStride);
|
xfbBuffers[b].implicitStride = std::max(xfbBuffers[b].implicitStride, unit.xfbBuffers[b].implicitStride);
|
||||||
if (unit.xfbBuffers[b].contains64BitType)
|
if (unit.xfbBuffers[b].contains64BitType)
|
||||||
xfbBuffers[b].contains64BitType = true;
|
xfbBuffers[b].contains64BitType = true;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
if (unit.xfbBuffers[b].contains32BitType)
|
if (unit.xfbBuffers[b].contains32BitType)
|
||||||
xfbBuffers[b].contains32BitType = true;
|
xfbBuffers[b].contains32BitType = true;
|
||||||
if (unit.xfbBuffers[b].contains16BitType)
|
if (unit.xfbBuffers[b].contains16BitType)
|
||||||
xfbBuffers[b].contains16BitType = true;
|
xfbBuffers[b].contains16BitType = true;
|
||||||
#endif
|
|
||||||
// TODO: 4.4 link: enhanced layouts: compare ranges
|
// TODO: 4.4 link: enhanced layouts: compare ranges
|
||||||
}
|
}
|
||||||
|
|
||||||
MERGE_TRUE(multiStream);
|
MERGE_TRUE(multiStream);
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
MERGE_TRUE(layoutOverrideCoverage);
|
MERGE_TRUE(layoutOverrideCoverage);
|
||||||
MERGE_TRUE(geoPassthroughEXT);
|
MERGE_TRUE(geoPassthroughEXT);
|
||||||
#endif
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < unit.shiftBinding.size(); ++i) {
|
for (unsigned int i = 0; i < unit.shiftBinding.size(); ++i) {
|
||||||
if (unit.shiftBinding[i] > 0)
|
if (unit.shiftBinding[i] > 0)
|
||||||
@@ -287,13 +286,8 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Getting this far means we have two existing trees to merge...
|
// Getting this far means we have two existing trees to merge...
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
numShaderRecordNVBlocks += unit.numShaderRecordNVBlocks;
|
numShaderRecordNVBlocks += unit.numShaderRecordNVBlocks;
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
numTaskNVBlocks += unit.numTaskNVBlocks;
|
numTaskNVBlocks += unit.numTaskNVBlocks;
|
||||||
#endif
|
|
||||||
|
|
||||||
// Get the top-level globals of each unit
|
// Get the top-level globals of each unit
|
||||||
TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();
|
TIntermSequence& globals = treeRoot->getAsAggregate()->getSequence();
|
||||||
@@ -315,6 +309,8 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit)
|
|||||||
ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end());
|
ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
// Traverser that seeds an ID map with all built-ins, and tracks the
|
// Traverser that seeds an ID map with all built-ins, and tracks the
|
||||||
// maximum ID used.
|
// maximum ID used.
|
||||||
// (It would be nice to put this in a function, but that causes warnings
|
// (It would be nice to put this in a function, but that causes warnings
|
||||||
@@ -502,6 +498,7 @@ void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType)
|
|||||||
//
|
//
|
||||||
void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage)
|
void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, bool crossStage)
|
||||||
{
|
{
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
bool writeTypeComparison = false;
|
bool writeTypeComparison = false;
|
||||||
|
|
||||||
// Types have to match
|
// Types have to match
|
||||||
@@ -536,7 +533,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Precise...
|
// Precise...
|
||||||
if (! crossStage && symbol.getQualifier().noContraction != unitSymbol.getQualifier().noContraction) {
|
if (! crossStage && symbol.getQualifier().isNoContraction() != unitSymbol.getQualifier().isNoContraction()) {
|
||||||
error(infoSink, "Presence of precise qualifier must match:");
|
error(infoSink, "Presence of precise qualifier must match:");
|
||||||
writeTypeComparison = true;
|
writeTypeComparison = true;
|
||||||
}
|
}
|
||||||
@@ -545,9 +542,9 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
|||||||
if (symbol.getQualifier().centroid != unitSymbol.getQualifier().centroid ||
|
if (symbol.getQualifier().centroid != unitSymbol.getQualifier().centroid ||
|
||||||
symbol.getQualifier().smooth != unitSymbol.getQualifier().smooth ||
|
symbol.getQualifier().smooth != unitSymbol.getQualifier().smooth ||
|
||||||
symbol.getQualifier().flat != unitSymbol.getQualifier().flat ||
|
symbol.getQualifier().flat != unitSymbol.getQualifier().flat ||
|
||||||
symbol.getQualifier().sample != unitSymbol.getQualifier().sample ||
|
symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() ||
|
||||||
symbol.getQualifier().patch != unitSymbol.getQualifier().patch ||
|
symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() ||
|
||||||
symbol.getQualifier().nopersp != unitSymbol.getQualifier().nopersp) {
|
symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective()) {
|
||||||
error(infoSink, "Interpolation and auxiliary storage qualifiers must match:");
|
error(infoSink, "Interpolation and auxiliary storage qualifiers must match:");
|
||||||
writeTypeComparison = true;
|
writeTypeComparison = true;
|
||||||
}
|
}
|
||||||
@@ -595,6 +592,7 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy
|
|||||||
if (writeTypeComparison)
|
if (writeTypeComparison)
|
||||||
infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus \"" <<
|
infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus \"" <<
|
||||||
unitSymbol.getType().getCompleteString() << "\"\n";
|
unitSymbol.getType().getCompleteString() << "\"\n";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -609,15 +607,12 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (numEntryPoints < 1) {
|
if (numEntryPoints < 1) {
|
||||||
if (source == EShSourceGlsl)
|
if (getSource() == EShSourceGlsl)
|
||||||
error(infoSink, "Missing entry point: Each stage requires one entry point");
|
error(infoSink, "Missing entry point: Each stage requires one entry point");
|
||||||
else
|
else
|
||||||
warn(infoSink, "Entry point not found");
|
warn(infoSink, "Entry point not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (numPushConstants > 1)
|
|
||||||
error(infoSink, "Only one push_constant block is allowed per stage");
|
|
||||||
|
|
||||||
// recursion and missing body checking
|
// recursion and missing body checking
|
||||||
checkCallGraphCycles(infoSink);
|
checkCallGraphCycles(infoSink);
|
||||||
checkCallGraphBodies(infoSink, keepUncalled);
|
checkCallGraphBodies(infoSink, keepUncalled);
|
||||||
@@ -625,6 +620,10 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
|||||||
// overlap/alias/missing I/O, etc.
|
// overlap/alias/missing I/O, etc.
|
||||||
inOutLocationCheck(infoSink);
|
inOutLocationCheck(infoSink);
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
if (getNumPushConstants() > 1)
|
||||||
|
error(infoSink, "Only one push_constant block is allowed per stage");
|
||||||
|
|
||||||
// invocations
|
// invocations
|
||||||
if (invocations == TQualifier::layoutNotSet)
|
if (invocations == TQualifier::layoutNotSet)
|
||||||
invocations = 1;
|
invocations = 1;
|
||||||
@@ -642,12 +641,10 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
|||||||
for (size_t b = 0; b < xfbBuffers.size(); ++b) {
|
for (size_t b = 0; b < xfbBuffers.size(); ++b) {
|
||||||
if (xfbBuffers[b].contains64BitType)
|
if (xfbBuffers[b].contains64BitType)
|
||||||
RoundToPow2(xfbBuffers[b].implicitStride, 8);
|
RoundToPow2(xfbBuffers[b].implicitStride, 8);
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
else if (xfbBuffers[b].contains32BitType)
|
else if (xfbBuffers[b].contains32BitType)
|
||||||
RoundToPow2(xfbBuffers[b].implicitStride, 4);
|
RoundToPow2(xfbBuffers[b].implicitStride, 4);
|
||||||
else if (xfbBuffers[b].contains16BitType)
|
else if (xfbBuffers[b].contains16BitType)
|
||||||
RoundToPow2(xfbBuffers[b].implicitStride, 2);
|
RoundToPow2(xfbBuffers[b].implicitStride, 2);
|
||||||
#endif
|
|
||||||
|
|
||||||
// "It is a compile-time or link-time error to have
|
// "It is a compile-time or link-time error to have
|
||||||
// any xfb_offset that overflows xfb_stride, whether stated on declarations before or after the xfb_stride, or
|
// any xfb_offset that overflows xfb_stride, whether stated on declarations before or after the xfb_stride, or
|
||||||
@@ -668,16 +665,11 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
|||||||
error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double or 64-bit integer:");
|
error(infoSink, "xfb_stride must be multiple of 8 for buffer holding a double or 64-bit integer:");
|
||||||
infoSink.info.prefix(EPrefixError);
|
infoSink.info.prefix(EPrefixError);
|
||||||
infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
|
infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
} else if (xfbBuffers[b].contains32BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) {
|
} else if (xfbBuffers[b].contains32BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) {
|
||||||
#else
|
|
||||||
} else if (! IsMultipleOfPow2(xfbBuffers[b].stride, 4)) {
|
|
||||||
#endif
|
|
||||||
error(infoSink, "xfb_stride must be multiple of 4:");
|
error(infoSink, "xfb_stride must be multiple of 4:");
|
||||||
infoSink.info.prefix(EPrefixError);
|
infoSink.info.prefix(EPrefixError);
|
||||||
infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
|
infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
|
||||||
}
|
}
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
// "If the buffer is capturing any
|
// "If the buffer is capturing any
|
||||||
// outputs with half-precision or 16-bit integer components, the stride must be a multiple of 2"
|
// outputs with half-precision or 16-bit integer components, the stride must be a multiple of 2"
|
||||||
else if (xfbBuffers[b].contains16BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 2)) {
|
else if (xfbBuffers[b].contains16BitType && ! IsMultipleOfPow2(xfbBuffers[b].stride, 2)) {
|
||||||
@@ -686,7 +678,6 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
|||||||
infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
|
infoSink.info << " xfb_buffer " << (unsigned int)b << ", xfb_stride " << xfbBuffers[b].stride << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
|
// "The resulting stride (implicit or explicit), when divided by 4, must be less than or equal to the
|
||||||
// implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
|
// implementation-dependent constant gl_MaxTransformFeedbackInterleavedComponents."
|
||||||
if (xfbBuffers[b].stride > (unsigned int)(4 * resources.maxTransformFeedbackInterleavedComponents)) {
|
if (xfbBuffers[b].stride > (unsigned int)(4 * resources.maxTransformFeedbackInterleavedComponents)) {
|
||||||
@@ -704,7 +695,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
|||||||
error(infoSink, "At least one shader must specify an output layout(vertices=...)");
|
error(infoSink, "At least one shader must specify an output layout(vertices=...)");
|
||||||
break;
|
break;
|
||||||
case EShLangTessEvaluation:
|
case EShLangTessEvaluation:
|
||||||
if (source == EShSourceGlsl) {
|
if (getSource() == EShSourceGlsl) {
|
||||||
if (inputPrimitive == ElgNone)
|
if (inputPrimitive == ElgNone)
|
||||||
error(infoSink, "At least one shader must specify an input layout primitive");
|
error(infoSink, "At least one shader must specify an input layout primitive");
|
||||||
if (vertexSpacing == EvsNone)
|
if (vertexSpacing == EvsNone)
|
||||||
@@ -730,8 +721,6 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
|||||||
break;
|
break;
|
||||||
case EShLangCompute:
|
case EShLangCompute:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
case EShLangRayGenNV:
|
case EShLangRayGenNV:
|
||||||
case EShLangIntersectNV:
|
case EShLangIntersectNV:
|
||||||
case EShLangAnyHitNV:
|
case EShLangAnyHitNV:
|
||||||
@@ -764,8 +753,6 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
|||||||
if (numTaskNVBlocks > 1)
|
if (numTaskNVBlocks > 1)
|
||||||
error(infoSink, "Only one taskNV interface block is allowed per shader");
|
error(infoSink, "Only one taskNV interface block is allowed per shader");
|
||||||
break;
|
break;
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error(infoSink, "Unknown Stage.");
|
error(infoSink, "Unknown Stage.");
|
||||||
break;
|
break;
|
||||||
@@ -787,6 +774,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled)
|
|||||||
} finalLinkTraverser;
|
} finalLinkTraverser;
|
||||||
|
|
||||||
treeRoot->traverse(&finalLinkTraverser);
|
treeRoot->traverse(&finalLinkTraverser);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -973,7 +961,7 @@ void TIntermediate::inOutLocationCheck(TInfoSink& infoSink)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile == EEsProfile) {
|
if (isEsProfile()) {
|
||||||
if (numFragOut > 1 && fragOutWithNoLocation)
|
if (numFragOut > 1 && fragOutWithNoLocation)
|
||||||
error(infoSink, "when more than one fragment shader output, all must have location qualifiers");
|
error(infoSink, "when more than one fragment shader output, all must have location qualifiers");
|
||||||
}
|
}
|
||||||
@@ -1066,6 +1054,7 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
|
|||||||
// So, for the case of dvec3, we need two independent ioRanges.
|
// So, for the case of dvec3, we need two independent ioRanges.
|
||||||
|
|
||||||
int collision = -1; // no collision
|
int collision = -1; // no collision
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 &&
|
if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 &&
|
||||||
(qualifier.isPipeInput() || qualifier.isPipeOutput())) {
|
(qualifier.isPipeInput() || qualifier.isPipeOutput())) {
|
||||||
// Dealing with dvec3 in/out split across two locations.
|
// Dealing with dvec3 in/out split across two locations.
|
||||||
@@ -1092,7 +1081,9 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
|
|||||||
if (collision < 0)
|
if (collision < 0)
|
||||||
usedIo[set].push_back(range2);
|
usedIo[set].push_back(range2);
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
// Not a dvec3 in/out split across two locations, generic path.
|
// Not a dvec3 in/out split across two locations, generic path.
|
||||||
// Need a single IO-range block.
|
// Need a single IO-range block.
|
||||||
|
|
||||||
@@ -1106,10 +1097,10 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ
|
|||||||
}
|
}
|
||||||
|
|
||||||
// combine location and component ranges
|
// combine location and component ranges
|
||||||
TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.layoutIndex : 0);
|
TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.getIndex() : 0);
|
||||||
|
|
||||||
// check for collisions, except for vertex inputs on desktop targeting OpenGL
|
// check for collisions, except for vertex inputs on desktop targeting OpenGL
|
||||||
if (! (profile != EEsProfile && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0)
|
if (! (!isEsProfile() && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0)
|
||||||
collision = checkLocationRange(set, range, type, typeCollision);
|
collision = checkLocationRange(set, range, type, typeCollision);
|
||||||
|
|
||||||
if (collision < 0)
|
if (collision < 0)
|
||||||
@@ -1187,14 +1178,10 @@ int TIntermediate::computeTypeLocationSize(const TType& type, EShLanguage stage)
|
|||||||
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||||
// TODO: are there valid cases of having an unsized array with a location? If so, running this code too early.
|
// TODO: are there valid cases of having an unsized array with a location? If so, running this code too early.
|
||||||
TType elementType(type, 0);
|
TType elementType(type, 0);
|
||||||
if (type.isSizedArray()
|
if (type.isSizedArray() && !type.getQualifier().isPerView())
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
&& !type.getQualifier().isPerView()
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
return type.getOuterArraySize() * computeTypeLocationSize(elementType, stage);
|
return type.getOuterArraySize() * computeTypeLocationSize(elementType, stage);
|
||||||
else {
|
else {
|
||||||
#ifdef NV_EXTENSIONS
|
#ifndef GLSLANG_WEB
|
||||||
// unset perViewNV attributes for arrayed per-view outputs: "perviewNV vec4 v[MAX_VIEWS][3];"
|
// unset perViewNV attributes for arrayed per-view outputs: "perviewNV vec4 v[MAX_VIEWS][3];"
|
||||||
elementType.getQualifier().perViewNV = false;
|
elementType.getQualifier().perViewNV = false;
|
||||||
#endif
|
#endif
|
||||||
@@ -1273,6 +1260,8 @@ int TIntermediate::computeTypeUniformLocationSize(const TType& type)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
// Accumulate xfb buffer ranges and check for collisions as the accumulation is done.
|
// 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.
|
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
|
||||||
@@ -1285,11 +1274,7 @@ int TIntermediate::addXfbBufferOffset(const TType& type)
|
|||||||
TXfbBuffer& buffer = xfbBuffers[qualifier.layoutXfbBuffer];
|
TXfbBuffer& buffer = xfbBuffers[qualifier.layoutXfbBuffer];
|
||||||
|
|
||||||
// compute the range
|
// compute the range
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
unsigned int size = computeTypeXfbSize(type, buffer.contains64BitType, buffer.contains32BitType, buffer.contains16BitType);
|
unsigned int size = computeTypeXfbSize(type, buffer.contains64BitType, buffer.contains32BitType, buffer.contains16BitType);
|
||||||
#else
|
|
||||||
unsigned int size = computeTypeXfbSize(type, buffer.contains64BitType);
|
|
||||||
#endif
|
|
||||||
buffer.implicitStride = std::max(buffer.implicitStride, qualifier.layoutXfbOffset + size);
|
buffer.implicitStride = std::max(buffer.implicitStride, qualifier.layoutXfbOffset + size);
|
||||||
TRange range(qualifier.layoutXfbOffset, qualifier.layoutXfbOffset + size - 1);
|
TRange range(qualifier.layoutXfbOffset, qualifier.layoutXfbOffset + size - 1);
|
||||||
|
|
||||||
@@ -1309,15 +1294,10 @@ int TIntermediate::addXfbBufferOffset(const TType& type)
|
|||||||
// Recursively figure out how many bytes of xfb buffer are used by the given type.
|
// Recursively figure out how many bytes of xfb buffer are used by the given type.
|
||||||
// Return the size of type, in bytes.
|
// Return the size of type, in bytes.
|
||||||
// Sets contains64BitType to true if the type contains a 64-bit data type.
|
// Sets contains64BitType to true if the type contains a 64-bit data type.
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
// Sets contains32BitType to true if the type contains a 32-bit data type.
|
// Sets contains32BitType to true if the type contains a 32-bit data type.
|
||||||
// Sets contains16BitType to true if the type contains a 16-bit data type.
|
// Sets contains16BitType to true if the type contains a 16-bit data type.
|
||||||
// N.B. Caller must set contains64BitType, contains32BitType, and contains16BitType to false before calling.
|
// N.B. Caller must set contains64BitType, contains32BitType, and contains16BitType to false before calling.
|
||||||
unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const
|
unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const
|
||||||
#else
|
|
||||||
// N.B. Caller must set contains64BitType to false before calling.
|
|
||||||
unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains64BitType) const
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
// "...if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8,
|
// "...if applied to an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8,
|
||||||
// and the space taken in the buffer will be a multiple of 8.
|
// and the space taken in the buffer will be a multiple of 8.
|
||||||
@@ -1330,44 +1310,32 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
|
|||||||
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
// TODO: perf: this can be flattened by using getCumulativeArraySize(), and a deref that discards all arrayness
|
||||||
assert(type.isSizedArray());
|
assert(type.isSizedArray());
|
||||||
TType elementType(type, 0);
|
TType elementType(type, 0);
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType, contains16BitType, contains16BitType);
|
return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType, contains16BitType, contains16BitType);
|
||||||
#else
|
|
||||||
return type.getOuterArraySize() * computeTypeXfbSize(elementType, contains64BitType);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.isStruct()) {
|
if (type.isStruct()) {
|
||||||
unsigned int size = 0;
|
unsigned int size = 0;
|
||||||
bool structContains64BitType = false;
|
bool structContains64BitType = false;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
bool structContains32BitType = false;
|
bool structContains32BitType = false;
|
||||||
bool structContains16BitType = false;
|
bool structContains16BitType = false;
|
||||||
#endif
|
|
||||||
for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
|
for (int member = 0; member < (int)type.getStruct()->size(); ++member) {
|
||||||
TType memberType(type, member);
|
TType memberType(type, member);
|
||||||
// "... if applied to
|
// "... if applied to
|
||||||
// an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8,
|
// an aggregate containing a double or 64-bit integer, the offset must also be a multiple of 8,
|
||||||
// and the space taken in the buffer will be a multiple of 8."
|
// and the space taken in the buffer will be a multiple of 8."
|
||||||
bool memberContains64BitType = false;
|
bool memberContains64BitType = false;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
bool memberContains32BitType = false;
|
bool memberContains32BitType = false;
|
||||||
bool memberContains16BitType = false;
|
bool memberContains16BitType = false;
|
||||||
int memberSize = computeTypeXfbSize(memberType, memberContains64BitType, memberContains32BitType, memberContains16BitType);
|
int memberSize = computeTypeXfbSize(memberType, memberContains64BitType, memberContains32BitType, memberContains16BitType);
|
||||||
#else
|
|
||||||
int memberSize = computeTypeXfbSize(memberType, memberContains64BitType);
|
|
||||||
#endif
|
|
||||||
if (memberContains64BitType) {
|
if (memberContains64BitType) {
|
||||||
structContains64BitType = true;
|
structContains64BitType = true;
|
||||||
RoundToPow2(size, 8);
|
RoundToPow2(size, 8);
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
} else if (memberContains32BitType) {
|
} else if (memberContains32BitType) {
|
||||||
structContains32BitType = true;
|
structContains32BitType = true;
|
||||||
RoundToPow2(size, 4);
|
RoundToPow2(size, 4);
|
||||||
} else if (memberContains16BitType) {
|
} else if (memberContains16BitType) {
|
||||||
structContains16BitType = true;
|
structContains16BitType = true;
|
||||||
RoundToPow2(size, 2);
|
RoundToPow2(size, 2);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
size += memberSize;
|
size += memberSize;
|
||||||
}
|
}
|
||||||
@@ -1375,14 +1343,12 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
|
|||||||
if (structContains64BitType) {
|
if (structContains64BitType) {
|
||||||
contains64BitType = true;
|
contains64BitType = true;
|
||||||
RoundToPow2(size, 8);
|
RoundToPow2(size, 8);
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
} else if (structContains32BitType) {
|
} else if (structContains32BitType) {
|
||||||
contains32BitType = true;
|
contains32BitType = true;
|
||||||
RoundToPow2(size, 4);
|
RoundToPow2(size, 4);
|
||||||
} else if (structContains16BitType) {
|
} else if (structContains16BitType) {
|
||||||
contains16BitType = true;
|
contains16BitType = true;
|
||||||
RoundToPow2(size, 2);
|
RoundToPow2(size, 2);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@@ -1402,7 +1368,6 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
|
|||||||
if (type.getBasicType() == EbtDouble || type.getBasicType() == EbtInt64 || type.getBasicType() == EbtUint64) {
|
if (type.getBasicType() == EbtDouble || type.getBasicType() == EbtInt64 || type.getBasicType() == EbtUint64) {
|
||||||
contains64BitType = true;
|
contains64BitType = true;
|
||||||
return 8 * numComponents;
|
return 8 * numComponents;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
} else if (type.getBasicType() == EbtFloat16 || type.getBasicType() == EbtInt16 || type.getBasicType() == EbtUint16) {
|
} else if (type.getBasicType() == EbtFloat16 || type.getBasicType() == EbtInt16 || type.getBasicType() == EbtUint16) {
|
||||||
contains16BitType = true;
|
contains16BitType = true;
|
||||||
return 2 * numComponents;
|
return 2 * numComponents;
|
||||||
@@ -1412,12 +1377,10 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains
|
|||||||
contains32BitType = true;
|
contains32BitType = true;
|
||||||
return 4 * numComponents;
|
return 4 * numComponents;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
} else
|
|
||||||
return 4 * numComponents;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
const int baseAlignmentVec4Std140 = 16;
|
const int baseAlignmentVec4Std140 = 16;
|
||||||
|
|
||||||
// Return the size and alignment of a component of the given type.
|
// Return the size and alignment of a component of the given type.
|
||||||
@@ -1425,6 +1388,10 @@ const int baseAlignmentVec4Std140 = 16;
|
|||||||
// Return value is the alignment..
|
// Return value is the alignment..
|
||||||
int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size)
|
||||||
{
|
{
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
size = 4; return 4;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (type.getBasicType()) {
|
switch (type.getBasicType()) {
|
||||||
case EbtInt64:
|
case EbtInt64:
|
||||||
case EbtUint64:
|
case EbtUint64:
|
||||||
@@ -1741,7 +1708,7 @@ int TIntermediate::getBlockSize(const TType& blockType)
|
|||||||
|
|
||||||
int TIntermediate::computeBufferReferenceTypeSize(const TType& type)
|
int TIntermediate::computeBufferReferenceTypeSize(const TType& type)
|
||||||
{
|
{
|
||||||
assert(type.getBasicType() == EbtReference);
|
assert(type.isReference());
|
||||||
int size = getBlockSize(*type.getReferentType());
|
int size = getBlockSize(*type.getReferentType());
|
||||||
|
|
||||||
int align = type.getBufferReferenceAlignment();
|
int align = type.getBufferReferenceAlignment();
|
||||||
|
|||||||
@@ -147,23 +147,19 @@ struct TOffsetRange {
|
|||||||
TRange offset;
|
TRange offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
// Things that need to be tracked per xfb buffer.
|
// Things that need to be tracked per xfb buffer.
|
||||||
struct TXfbBuffer {
|
struct TXfbBuffer {
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false),
|
TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false),
|
||||||
contains32BitType(false), contains16BitType(false) { }
|
contains32BitType(false), contains16BitType(false) { }
|
||||||
#else
|
|
||||||
TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false) { }
|
|
||||||
#endif
|
|
||||||
std::vector<TRange> ranges; // byte offsets that have already been assigned
|
std::vector<TRange> ranges; // byte offsets that have already been assigned
|
||||||
unsigned int stride;
|
unsigned int stride;
|
||||||
unsigned int implicitStride;
|
unsigned int implicitStride;
|
||||||
bool contains64BitType;
|
bool contains64BitType;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
bool contains32BitType;
|
bool contains32BitType;
|
||||||
bool contains16BitType;
|
bool contains16BitType;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
// Track a set of strings describing how the module was processed.
|
// Track a set of strings describing how the module was processed.
|
||||||
// Using the form:
|
// Using the form:
|
||||||
@@ -217,7 +213,6 @@ class TSymbolTable;
|
|||||||
class TSymbol;
|
class TSymbol;
|
||||||
class TVariable;
|
class TVariable;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
//
|
//
|
||||||
// Texture and Sampler transformation mode.
|
// Texture and Sampler transformation mode.
|
||||||
//
|
//
|
||||||
@@ -226,7 +221,6 @@ enum ComputeDerivativeMode {
|
|||||||
LayoutDerivativeGroupQuads, // derivative_group_quadsNV
|
LayoutDerivativeGroupQuads, // derivative_group_quadsNV
|
||||||
LayoutDerivativeGroupLinear, // derivative_group_linearNV
|
LayoutDerivativeGroupLinear, // derivative_group_linearNV
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Set of helper functions to help parse and build the tree.
|
// Set of helper functions to help parse and build the tree.
|
||||||
@@ -234,32 +228,36 @@ enum ComputeDerivativeMode {
|
|||||||
class TIntermediate {
|
class TIntermediate {
|
||||||
public:
|
public:
|
||||||
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
|
explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) :
|
||||||
implicitThisName("@this"), implicitCounterName("@count"),
|
language(l),
|
||||||
language(l), source(EShSourceNone), profile(p), version(v), treeRoot(0),
|
profile(p), version(v), treeRoot(0),
|
||||||
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
|
numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false),
|
||||||
|
invertY(false),
|
||||||
|
useStorageBuffer(false),
|
||||||
|
nanMinMaxClamp(false),
|
||||||
|
depthReplacing(false)
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
,
|
||||||
|
implicitThisName("@this"), implicitCounterName("@count"),
|
||||||
|
source(EShSourceNone),
|
||||||
|
useVulkanMemoryModel(false),
|
||||||
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
|
invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet),
|
||||||
inputPrimitive(ElgNone), outputPrimitive(ElgNone),
|
inputPrimitive(ElgNone), outputPrimitive(ElgNone),
|
||||||
pixelCenterInteger(false), originUpperLeft(false),
|
pixelCenterInteger(false), originUpperLeft(false),
|
||||||
vertexSpacing(EvsNone), vertexOrder(EvoNone), pointMode(false), earlyFragmentTests(false),
|
vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false),
|
||||||
postDepthCoverage(false), depthLayout(EldNone), depthReplacing(false),
|
postDepthCoverage(false), depthLayout(EldNone),
|
||||||
hlslFunctionality1(false),
|
hlslFunctionality1(false),
|
||||||
blendEquations(0), xfbMode(false), multiStream(false),
|
blendEquations(0), xfbMode(false), multiStream(false),
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
layoutOverrideCoverage(false),
|
layoutOverrideCoverage(false),
|
||||||
geoPassthroughEXT(false),
|
geoPassthroughEXT(false),
|
||||||
numShaderRecordNVBlocks(0),
|
numShaderRecordNVBlocks(0),
|
||||||
computeDerivativeMode(LayoutDerivativeNone),
|
computeDerivativeMode(LayoutDerivativeNone),
|
||||||
primitives(TQualifier::layoutNotSet),
|
primitives(TQualifier::layoutNotSet),
|
||||||
numTaskNVBlocks(0),
|
numTaskNVBlocks(0),
|
||||||
#endif
|
|
||||||
autoMapBindings(false),
|
autoMapBindings(false),
|
||||||
autoMapLocations(false),
|
autoMapLocations(false),
|
||||||
invertY(false),
|
|
||||||
flattenUniformArrays(false),
|
flattenUniformArrays(false),
|
||||||
useUnknownFormat(false),
|
useUnknownFormat(false),
|
||||||
hlslOffsets(false),
|
hlslOffsets(false),
|
||||||
useStorageBuffer(false),
|
|
||||||
useVulkanMemoryModel(false),
|
|
||||||
hlslIoMapping(false),
|
hlslIoMapping(false),
|
||||||
useVariablePointers(false),
|
useVariablePointers(false),
|
||||||
textureSamplerTransformMode(EShTexSampTransKeep),
|
textureSamplerTransformMode(EShTexSampTransKeep),
|
||||||
@@ -267,160 +265,22 @@ public:
|
|||||||
binaryDoubleOutput(false),
|
binaryDoubleOutput(false),
|
||||||
usePhysicalStorageBuffer(false),
|
usePhysicalStorageBuffer(false),
|
||||||
uniformLocationBase(0)
|
uniformLocationBase(0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
localSize[0] = 1;
|
localSize[0] = 1;
|
||||||
localSize[1] = 1;
|
localSize[1] = 1;
|
||||||
localSize[2] = 1;
|
localSize[2] = 1;
|
||||||
|
localSizeNotDefault[0] = false;
|
||||||
|
localSizeNotDefault[1] = false;
|
||||||
|
localSizeNotDefault[2] = false;
|
||||||
localSizeSpecId[0] = TQualifier::layoutNotSet;
|
localSizeSpecId[0] = TQualifier::layoutNotSet;
|
||||||
localSizeSpecId[1] = TQualifier::layoutNotSet;
|
localSizeSpecId[1] = TQualifier::layoutNotSet;
|
||||||
localSizeSpecId[2] = TQualifier::layoutNotSet;
|
localSizeSpecId[2] = TQualifier::layoutNotSet;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
|
xfbBuffers.resize(TQualifier::layoutXfbBufferEnd);
|
||||||
|
|
||||||
shiftBinding.fill(0);
|
shiftBinding.fill(0);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
void setLimits(const TBuiltInResource& r) { resources = r; }
|
|
||||||
|
|
||||||
bool postProcess(TIntermNode*, EShLanguage);
|
|
||||||
void output(TInfoSink&, bool tree);
|
|
||||||
void removeTree();
|
|
||||||
|
|
||||||
void setSource(EShSource s) { source = s; }
|
|
||||||
EShSource getSource() const { return source; }
|
|
||||||
void setEntryPointName(const char* ep)
|
|
||||||
{
|
|
||||||
entryPointName = ep;
|
|
||||||
processes.addProcess("entry-point");
|
|
||||||
processes.addArgument(entryPointName);
|
|
||||||
}
|
|
||||||
void setEntryPointMangledName(const char* ep) { entryPointMangledName = ep; }
|
|
||||||
const std::string& getEntryPointName() const { return entryPointName; }
|
|
||||||
const std::string& getEntryPointMangledName() const { return entryPointMangledName; }
|
|
||||||
|
|
||||||
void setShiftBinding(TResourceType res, unsigned int shift)
|
|
||||||
{
|
|
||||||
shiftBinding[res] = shift;
|
|
||||||
|
|
||||||
const char* name = getResourceName(res);
|
|
||||||
if (name != nullptr)
|
|
||||||
processes.addIfNonZero(name, shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; }
|
|
||||||
|
|
||||||
void setShiftBindingForSet(TResourceType res, unsigned int shift, unsigned int set)
|
|
||||||
{
|
|
||||||
if (shift == 0) // ignore if there's no shift: it's a no-op.
|
|
||||||
return;
|
|
||||||
|
|
||||||
shiftBindingForSet[res][set] = shift;
|
|
||||||
|
|
||||||
const char* name = getResourceName(res);
|
|
||||||
if (name != nullptr) {
|
|
||||||
processes.addProcess(name);
|
|
||||||
processes.addArgument(shift);
|
|
||||||
processes.addArgument(set);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int getShiftBindingForSet(TResourceType res, unsigned int set) const
|
|
||||||
{
|
|
||||||
const auto shift = shiftBindingForSet[res].find(set);
|
|
||||||
return shift == shiftBindingForSet[res].end() ? -1 : shift->second;
|
|
||||||
}
|
|
||||||
bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); }
|
|
||||||
|
|
||||||
void setResourceSetBinding(const std::vector<std::string>& shift)
|
|
||||||
{
|
|
||||||
resourceSetBinding = shift;
|
|
||||||
if (shift.size() > 0) {
|
|
||||||
processes.addProcess("resource-set-binding");
|
|
||||||
for (int s = 0; s < (int)shift.size(); ++s)
|
|
||||||
processes.addArgument(shift[s]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
|
|
||||||
void setAutoMapBindings(bool map)
|
|
||||||
{
|
|
||||||
autoMapBindings = map;
|
|
||||||
if (autoMapBindings)
|
|
||||||
processes.addProcess("auto-map-bindings");
|
|
||||||
}
|
|
||||||
bool getAutoMapBindings() const { return autoMapBindings; }
|
|
||||||
void setAutoMapLocations(bool map)
|
|
||||||
{
|
|
||||||
autoMapLocations = map;
|
|
||||||
if (autoMapLocations)
|
|
||||||
processes.addProcess("auto-map-locations");
|
|
||||||
}
|
|
||||||
bool getAutoMapLocations() const { return autoMapLocations; }
|
|
||||||
void setInvertY(bool invert)
|
|
||||||
{
|
|
||||||
invertY = invert;
|
|
||||||
if (invertY)
|
|
||||||
processes.addProcess("invert-y");
|
|
||||||
}
|
|
||||||
bool getInvertY() const { return invertY; }
|
|
||||||
|
|
||||||
void setFlattenUniformArrays(bool flatten)
|
|
||||||
{
|
|
||||||
flattenUniformArrays = flatten;
|
|
||||||
if (flattenUniformArrays)
|
|
||||||
processes.addProcess("flatten-uniform-arrays");
|
|
||||||
}
|
|
||||||
bool getFlattenUniformArrays() const { return flattenUniformArrays; }
|
|
||||||
void setNoStorageFormat(bool b)
|
|
||||||
{
|
|
||||||
useUnknownFormat = b;
|
|
||||||
if (useUnknownFormat)
|
|
||||||
processes.addProcess("no-storage-format");
|
|
||||||
}
|
|
||||||
bool getNoStorageFormat() const { return useUnknownFormat; }
|
|
||||||
void setHlslOffsets()
|
|
||||||
{
|
|
||||||
hlslOffsets = true;
|
|
||||||
if (hlslOffsets)
|
|
||||||
processes.addProcess("hlsl-offsets");
|
|
||||||
}
|
|
||||||
bool usingHlslOffsets() const { return hlslOffsets; }
|
|
||||||
void setUseStorageBuffer()
|
|
||||||
{
|
|
||||||
useStorageBuffer = true;
|
|
||||||
processes.addProcess("use-storage-buffer");
|
|
||||||
}
|
|
||||||
bool usingStorageBuffer() const { return useStorageBuffer; }
|
|
||||||
void setHlslIoMapping(bool b)
|
|
||||||
{
|
|
||||||
hlslIoMapping = b;
|
|
||||||
if (hlslIoMapping)
|
|
||||||
processes.addProcess("hlsl-iomap");
|
|
||||||
}
|
|
||||||
bool usingHlslIoMapping() { return hlslIoMapping; }
|
|
||||||
void setUseVulkanMemoryModel()
|
|
||||||
{
|
|
||||||
useVulkanMemoryModel = true;
|
|
||||||
processes.addProcess("use-vulkan-memory-model");
|
|
||||||
}
|
|
||||||
bool usingVulkanMemoryModel() const { return useVulkanMemoryModel; }
|
|
||||||
void setUsePhysicalStorageBuffer()
|
|
||||||
{
|
|
||||||
usePhysicalStorageBuffer = true;
|
|
||||||
}
|
|
||||||
bool usingPhysicalStorageBuffer() const { return usePhysicalStorageBuffer; }
|
|
||||||
void setUseVariablePointers()
|
|
||||||
{
|
|
||||||
useVariablePointers = true;
|
|
||||||
processes.addProcess("use-variable-pointers");
|
|
||||||
}
|
|
||||||
bool usingVariablePointers() const { return useVariablePointers; }
|
|
||||||
|
|
||||||
template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
|
|
||||||
bool hasCounterBufferName(const TString& name) const {
|
|
||||||
size_t len = strlen(implicitCounterName);
|
|
||||||
return name.size() > len &&
|
|
||||||
name.compare(name.size() - len, len, implicitCounterName) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
|
|
||||||
|
|
||||||
void setVersion(int v) { version = v; }
|
void setVersion(int v) { version = v; }
|
||||||
int getVersion() const { return version; }
|
int getVersion() const { return version; }
|
||||||
@@ -451,6 +311,12 @@ public:
|
|||||||
case EShTargetSpv_1_3:
|
case EShTargetSpv_1_3:
|
||||||
processes.addProcess("target-env spirv1.3");
|
processes.addProcess("target-env spirv1.3");
|
||||||
break;
|
break;
|
||||||
|
case EShTargetSpv_1_4:
|
||||||
|
processes.addProcess("target-env spirv1.4");
|
||||||
|
break;
|
||||||
|
case EShTargetSpv_1_5:
|
||||||
|
processes.addProcess("target-env spirv1.5");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
processes.addProcess("target-env spirvUnknown");
|
processes.addProcess("target-env spirvUnknown");
|
||||||
break;
|
break;
|
||||||
@@ -484,9 +350,35 @@ public:
|
|||||||
int getNumEntryPoints() const { return numEntryPoints; }
|
int getNumEntryPoints() const { return numEntryPoints; }
|
||||||
int getNumErrors() const { return numErrors; }
|
int getNumErrors() const { return numErrors; }
|
||||||
void addPushConstantCount() { ++numPushConstants; }
|
void addPushConstantCount() { ++numPushConstants; }
|
||||||
#ifdef NV_EXTENSIONS
|
void setLimits(const TBuiltInResource& r) { resources = r; }
|
||||||
void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; }
|
|
||||||
void addTaskNVCount() { ++numTaskNVBlocks; }
|
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
|
||||||
|
void setSource(EShSource s) { assert(s == EShSourceGlsl); }
|
||||||
|
EShSource getSource() const { return EShSourceGlsl; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool isRecursive() const { return recursive; }
|
bool isRecursive() const { return recursive; }
|
||||||
@@ -565,6 +457,169 @@ public:
|
|||||||
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
|
void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&);
|
||||||
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
|
void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&);
|
||||||
|
|
||||||
|
void setUseStorageBuffer()
|
||||||
|
{
|
||||||
|
useStorageBuffer = true;
|
||||||
|
processes.addProcess("use-storage-buffer");
|
||||||
|
}
|
||||||
|
bool usingStorageBuffer() const { return useStorageBuffer; }
|
||||||
|
void setDepthReplacing() { depthReplacing = true; }
|
||||||
|
bool isDepthReplacing() const { return depthReplacing; }
|
||||||
|
bool setLocalSize(int dim, int size)
|
||||||
|
{
|
||||||
|
if (localSizeNotDefault[dim])
|
||||||
|
return size == localSize[dim];
|
||||||
|
localSizeNotDefault[dim] = true;
|
||||||
|
localSize[dim] = size;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
unsigned int getLocalSize(int dim) const { return localSize[dim]; }
|
||||||
|
bool setLocalSizeSpecId(int dim, int id)
|
||||||
|
{
|
||||||
|
if (localSizeSpecId[dim] != TQualifier::layoutNotSet)
|
||||||
|
return id == localSizeSpecId[dim];
|
||||||
|
localSizeSpecId[dim] = id;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; }
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
void output(TInfoSink&, bool tree) { }
|
||||||
|
|
||||||
|
bool isEsProfile() const { return false; }
|
||||||
|
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; }
|
||||||
|
unsigned getXfbStride(int buffer) const { return 0; }
|
||||||
|
bool hasLayoutDerivativeModeNone() const { return false; }
|
||||||
|
ComputeDerivativeMode getLayoutDerivativeModeNone() const { return LayoutDerivativeNone; }
|
||||||
|
#else
|
||||||
|
void output(TInfoSink&, bool tree);
|
||||||
|
|
||||||
|
bool isEsProfile() const { return profile == EEsProfile; }
|
||||||
|
|
||||||
|
void setShiftBinding(TResourceType res, unsigned int shift)
|
||||||
|
{
|
||||||
|
shiftBinding[res] = shift;
|
||||||
|
|
||||||
|
const char* name = getResourceName(res);
|
||||||
|
if (name != nullptr)
|
||||||
|
processes.addIfNonZero(name, shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int getShiftBinding(TResourceType res) const { return shiftBinding[res]; }
|
||||||
|
|
||||||
|
void setShiftBindingForSet(TResourceType res, unsigned int shift, unsigned int set)
|
||||||
|
{
|
||||||
|
if (shift == 0) // ignore if there's no shift: it's a no-op.
|
||||||
|
return;
|
||||||
|
|
||||||
|
shiftBindingForSet[res][set] = shift;
|
||||||
|
|
||||||
|
const char* name = getResourceName(res);
|
||||||
|
if (name != nullptr) {
|
||||||
|
processes.addProcess(name);
|
||||||
|
processes.addArgument(shift);
|
||||||
|
processes.addArgument(set);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int getShiftBindingForSet(TResourceType res, unsigned int set) const
|
||||||
|
{
|
||||||
|
const auto shift = shiftBindingForSet[res].find(set);
|
||||||
|
return shift == shiftBindingForSet[res].end() ? -1 : shift->second;
|
||||||
|
}
|
||||||
|
bool hasShiftBindingForSet(TResourceType res) const { return !shiftBindingForSet[res].empty(); }
|
||||||
|
|
||||||
|
void setResourceSetBinding(const std::vector<std::string>& shift)
|
||||||
|
{
|
||||||
|
resourceSetBinding = shift;
|
||||||
|
if (shift.size() > 0) {
|
||||||
|
processes.addProcess("resource-set-binding");
|
||||||
|
for (int s = 0; s < (int)shift.size(); ++s)
|
||||||
|
processes.addArgument(shift[s]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const std::vector<std::string>& getResourceSetBinding() const { return resourceSetBinding; }
|
||||||
|
void setAutoMapBindings(bool map)
|
||||||
|
{
|
||||||
|
autoMapBindings = map;
|
||||||
|
if (autoMapBindings)
|
||||||
|
processes.addProcess("auto-map-bindings");
|
||||||
|
}
|
||||||
|
bool getAutoMapBindings() const { return autoMapBindings; }
|
||||||
|
void setAutoMapLocations(bool map)
|
||||||
|
{
|
||||||
|
autoMapLocations = map;
|
||||||
|
if (autoMapLocations)
|
||||||
|
processes.addProcess("auto-map-locations");
|
||||||
|
}
|
||||||
|
bool getAutoMapLocations() const { return autoMapLocations; }
|
||||||
|
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
|
void setFlattenUniformArrays(bool flatten)
|
||||||
|
{
|
||||||
|
flattenUniformArrays = flatten;
|
||||||
|
if (flattenUniformArrays)
|
||||||
|
processes.addProcess("flatten-uniform-arrays");
|
||||||
|
}
|
||||||
|
bool getFlattenUniformArrays() const { return flattenUniformArrays; }
|
||||||
|
#endif
|
||||||
|
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; }
|
||||||
|
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
|
template<class T> T addCounterBufferName(const T& name) const { return name + implicitCounterName; }
|
||||||
|
bool hasCounterBufferName(const TString& name) const {
|
||||||
|
size_t len = strlen(implicitCounterName);
|
||||||
|
return name.size() > len &&
|
||||||
|
name.compare(name.size() - len, len, implicitCounterName) == 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { textureSamplerTransformMode = mode; }
|
||||||
|
int getNumPushConstants() const { return numPushConstants; }
|
||||||
|
void addShaderRecordNVCount() { ++numShaderRecordNVBlocks; }
|
||||||
|
void addTaskNVCount() { ++numTaskNVBlocks; }
|
||||||
|
|
||||||
bool setInvocations(int i)
|
bool setInvocations(int i)
|
||||||
{
|
{
|
||||||
if (invocations != TQualifier::layoutNotSet)
|
if (invocations != TQualifier::layoutNotSet)
|
||||||
@@ -608,23 +663,14 @@ public:
|
|||||||
void setPointMode() { pointMode = true; }
|
void setPointMode() { pointMode = true; }
|
||||||
bool getPointMode() const { return pointMode; }
|
bool getPointMode() const { return pointMode; }
|
||||||
|
|
||||||
bool setLocalSize(int dim, int size)
|
bool setInterlockOrdering(TInterlockOrdering o)
|
||||||
{
|
{
|
||||||
if (localSize[dim] > 1)
|
if (interlockOrdering != EioNone)
|
||||||
return size == localSize[dim];
|
return interlockOrdering == o;
|
||||||
localSize[dim] = size;
|
interlockOrdering = o;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
unsigned int getLocalSize(int dim) const { return localSize[dim]; }
|
TInterlockOrdering getInterlockOrdering() const { return interlockOrdering; }
|
||||||
|
|
||||||
bool setLocalSizeSpecId(int dim, int id)
|
|
||||||
{
|
|
||||||
if (localSizeSpecId[dim] != TQualifier::layoutNotSet)
|
|
||||||
return id == localSizeSpecId[dim];
|
|
||||||
localSizeSpecId[dim] = id;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
int getLocalSizeSpecId(int dim) const { return localSizeSpecId[dim]; }
|
|
||||||
|
|
||||||
void setXfbMode() { xfbMode = true; }
|
void setXfbMode() { xfbMode = true; }
|
||||||
bool getXfbMode() const { return xfbMode; }
|
bool getXfbMode() const { return xfbMode; }
|
||||||
@@ -638,14 +684,10 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
TLayoutGeometry getOutputPrimitive() const { return outputPrimitive; }
|
TLayoutGeometry getOutputPrimitive() const { return outputPrimitive; }
|
||||||
void setOriginUpperLeft() { originUpperLeft = true; }
|
|
||||||
bool getOriginUpperLeft() const { return originUpperLeft; }
|
|
||||||
void setPixelCenterInteger() { pixelCenterInteger = true; }
|
|
||||||
bool getPixelCenterInteger() const { return pixelCenterInteger; }
|
|
||||||
void setEarlyFragmentTests() { earlyFragmentTests = true; }
|
|
||||||
bool getEarlyFragmentTests() const { return earlyFragmentTests; }
|
|
||||||
void setPostDepthCoverage() { postDepthCoverage = true; }
|
void setPostDepthCoverage() { postDepthCoverage = true; }
|
||||||
bool getPostDepthCoverage() const { return postDepthCoverage; }
|
bool getPostDepthCoverage() const { return postDepthCoverage; }
|
||||||
|
void setEarlyFragmentTests() { earlyFragmentTests = true; }
|
||||||
|
bool getEarlyFragmentTests() const { return earlyFragmentTests; }
|
||||||
bool setDepth(TLayoutDepth d)
|
bool setDepth(TLayoutDepth d)
|
||||||
{
|
{
|
||||||
if (depthLayout != EldNone)
|
if (depthLayout != EldNone)
|
||||||
@@ -654,29 +696,12 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
TLayoutDepth getDepth() const { return depthLayout; }
|
TLayoutDepth getDepth() const { return depthLayout; }
|
||||||
void setDepthReplacing() { depthReplacing = true; }
|
void setOriginUpperLeft() { originUpperLeft = true; }
|
||||||
bool isDepthReplacing() const { return depthReplacing; }
|
bool getOriginUpperLeft() const { return originUpperLeft; }
|
||||||
|
void setPixelCenterInteger() { pixelCenterInteger = true; }
|
||||||
void setHlslFunctionality1() { hlslFunctionality1 = true; }
|
bool getPixelCenterInteger() const { return pixelCenterInteger; }
|
||||||
bool getHlslFunctionality1() const { return hlslFunctionality1; }
|
|
||||||
|
|
||||||
void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
|
void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); }
|
||||||
unsigned int getBlendEquations() const { return blendEquations; }
|
unsigned int getBlendEquations() const { return blendEquations; }
|
||||||
|
|
||||||
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
|
|
||||||
void merge(TInfoSink&, TIntermediate&);
|
|
||||||
void finalCheck(TInfoSink&, bool keepUncalled);
|
|
||||||
|
|
||||||
void addIoAccessed(const TString& name) { ioAccessed.insert(name); }
|
|
||||||
bool inIoAccessed(const TString& name) const { return ioAccessed.find(name) != ioAccessed.end(); }
|
|
||||||
|
|
||||||
int addUsedLocation(const TQualifier&, const TType&, bool& typeCollision);
|
|
||||||
int checkLocationRange(int set, const TIoRange& range, const TType&, bool& typeCollision);
|
|
||||||
int addUsedOffsets(int binding, int offset, int numOffsets);
|
|
||||||
bool addUsedConstantId(int id);
|
|
||||||
static int computeTypeLocationSize(const TType&, EShLanguage);
|
|
||||||
static int computeTypeUniformLocationSize(const TType&);
|
|
||||||
|
|
||||||
bool setXfbBufferStride(int buffer, unsigned stride)
|
bool setXfbBufferStride(int buffer, unsigned stride)
|
||||||
{
|
{
|
||||||
if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd)
|
if (xfbBuffers[buffer].stride != TQualifier::layoutXfbStrideEnd)
|
||||||
@@ -686,28 +711,14 @@ public:
|
|||||||
}
|
}
|
||||||
unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
|
unsigned getXfbStride(int buffer) const { return xfbBuffers[buffer].stride; }
|
||||||
int addXfbBufferOffset(const TType&);
|
int addXfbBufferOffset(const TType&);
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const;
|
unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType, bool& contains32BitType, bool& contains16BitType) const;
|
||||||
#else
|
|
||||||
unsigned int computeTypeXfbSize(const TType&, bool& contains64BitType) 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);
|
|
||||||
static int getMemberAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
|
|
||||||
static bool improperStraddle(const TType& type, int size, int offset);
|
|
||||||
static void updateOffset(const TType& parentType, const TType& memberType, int& offset, int& memberSize);
|
|
||||||
static int getOffset(const TType& type, int index);
|
|
||||||
static int getBlockSize(const TType& blockType);
|
|
||||||
static int computeBufferReferenceTypeSize(const TType&);
|
|
||||||
bool promote(TIntermOperator*);
|
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
|
void setLayoutOverrideCoverage() { layoutOverrideCoverage = true; }
|
||||||
bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
|
bool getLayoutOverrideCoverage() const { return layoutOverrideCoverage; }
|
||||||
void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
|
void setGeoPassthroughEXT() { geoPassthroughEXT = true; }
|
||||||
bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
|
bool getGeoPassthroughEXT() const { return geoPassthroughEXT; }
|
||||||
void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
|
void setLayoutDerivativeMode(ComputeDerivativeMode mode) { computeDerivativeMode = mode; }
|
||||||
|
bool hasLayoutDerivativeModeNone() const { return computeDerivativeMode != LayoutDerivativeNone; }
|
||||||
ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
|
ComputeDerivativeMode getLayoutDerivativeModeNone() const { return computeDerivativeMode; }
|
||||||
bool setPrimitives(int m)
|
bool setPrimitives(int m)
|
||||||
{
|
{
|
||||||
@@ -717,28 +728,10 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
int getPrimitives() const { return primitives; }
|
int getPrimitives() const { return primitives; }
|
||||||
#endif
|
|
||||||
|
|
||||||
const char* addSemanticName(const TString& name)
|
const char* addSemanticName(const TString& name)
|
||||||
{
|
{
|
||||||
return semanticNameSet.insert(name).first->c_str();
|
return semanticNameSet.insert(name).first->c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSourceFile(const char* file) { if (file != nullptr) sourceFile = file; }
|
|
||||||
const std::string& getSourceFile() const { return sourceFile; }
|
|
||||||
void addSourceText(const char* text, size_t len) { sourceText.append(text, len); }
|
|
||||||
const std::string& getSourceText() const { return sourceText; }
|
|
||||||
const std::map<std::string, std::string>& getIncludeText() const { return includeText; }
|
|
||||||
void addIncludeText(const char* name, const char* text, size_t len) { includeText[name].assign(text,len); }
|
|
||||||
void addProcesses(const std::vector<std::string>& p)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < (int)p.size(); ++i)
|
|
||||||
processes.addProcess(p[i]);
|
|
||||||
}
|
|
||||||
void addProcess(const std::string& process) { processes.addProcess(process); }
|
|
||||||
void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
|
|
||||||
const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); }
|
|
||||||
|
|
||||||
void addUniformLocationOverride(const char* nameStr, int location)
|
void addUniformLocationOverride(const char* nameStr, int location)
|
||||||
{
|
{
|
||||||
std::string name = nameStr;
|
std::string name = nameStr;
|
||||||
@@ -763,9 +756,98 @@ public:
|
|||||||
|
|
||||||
void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
|
void setBinaryDoubleOutput() { binaryDoubleOutput = true; }
|
||||||
bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
|
bool getBinaryDoubleOutput() { return binaryDoubleOutput; }
|
||||||
|
#endif // GLSLANG_WEB
|
||||||
|
|
||||||
const char* const implicitThisName;
|
#ifdef ENABLE_HLSL
|
||||||
const char* const implicitCounterName;
|
void setHlslFunctionality1() { hlslFunctionality1 = true; }
|
||||||
|
bool getHlslFunctionality1() const { return hlslFunctionality1; }
|
||||||
|
void setHlslOffsets()
|
||||||
|
{
|
||||||
|
hlslOffsets = true;
|
||||||
|
if (hlslOffsets)
|
||||||
|
processes.addProcess("hlsl-offsets");
|
||||||
|
}
|
||||||
|
bool usingHlslOffsets() const { return hlslOffsets; }
|
||||||
|
void setHlslIoMapping(bool b)
|
||||||
|
{
|
||||||
|
hlslIoMapping = b;
|
||||||
|
if (hlslIoMapping)
|
||||||
|
processes.addProcess("hlsl-iomap");
|
||||||
|
}
|
||||||
|
bool usingHlslIoMapping() { return hlslIoMapping; }
|
||||||
|
#else
|
||||||
|
bool getHlslFunctionality1() const { return false; }
|
||||||
|
bool usingHlslOffsets() const { return false; }
|
||||||
|
bool usingHlslIoMapping() { return false; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void addToCallGraph(TInfoSink&, const TString& caller, const TString& callee);
|
||||||
|
void merge(TInfoSink&, TIntermediate&);
|
||||||
|
void finalCheck(TInfoSink&, bool keepUncalled);
|
||||||
|
|
||||||
|
bool buildConvertOp(TBasicType dst, TBasicType src, TOperator& convertOp) const;
|
||||||
|
TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const;
|
||||||
|
|
||||||
|
void addIoAccessed(const TString& name) { ioAccessed.insert(name); }
|
||||||
|
bool inIoAccessed(const TString& name) const { return ioAccessed.find(name) != ioAccessed.end(); }
|
||||||
|
|
||||||
|
int addUsedLocation(const TQualifier&, const TType&, bool& typeCollision);
|
||||||
|
int checkLocationRange(int set, const TIoRange& range, const TType&, bool& typeCollision);
|
||||||
|
int addUsedOffsets(int binding, int offset, int numOffsets);
|
||||||
|
bool addUsedConstantId(int id);
|
||||||
|
static int computeTypeLocationSize(const TType&, EShLanguage);
|
||||||
|
static int computeTypeUniformLocationSize(const TType&);
|
||||||
|
|
||||||
|
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);
|
||||||
|
static int getMemberAlignment(const TType&, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor);
|
||||||
|
static bool improperStraddle(const TType& type, int size, int offset);
|
||||||
|
static void updateOffset(const TType& parentType, const TType& memberType, int& offset, int& memberSize);
|
||||||
|
static int getOffset(const TType& type, int index);
|
||||||
|
static int getBlockSize(const TType& blockType);
|
||||||
|
static int computeBufferReferenceTypeSize(const TType&);
|
||||||
|
bool promote(TIntermOperator*);
|
||||||
|
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; }
|
||||||
|
void addSourceText(const char* text, size_t len) { sourceText.append(text, len); }
|
||||||
|
const std::string& getSourceText() const { return sourceText; }
|
||||||
|
const std::map<std::string, std::string>& getIncludeText() const { return includeText; }
|
||||||
|
void addIncludeText(const char* name, const char* text, size_t len) { includeText[name].assign(text,len); }
|
||||||
|
void addProcesses(const std::vector<std::string>& p)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (int)p.size(); ++i)
|
||||||
|
processes.addProcess(p[i]);
|
||||||
|
}
|
||||||
|
void addProcess(const std::string& process) { processes.addProcess(process); }
|
||||||
|
void addProcessArgument(const std::string& arg) { processes.addArgument(arg); }
|
||||||
|
const std::vector<std::string>& getProcesses() const { return processes.getProcesses(); }
|
||||||
|
|
||||||
|
// Certain explicit conversions are allowed conditionally
|
||||||
|
#ifdef GLSLANG_WEB
|
||||||
|
bool getArithemeticInt8Enabled() const { return false; }
|
||||||
|
bool getArithemeticInt16Enabled() const { return false; }
|
||||||
|
bool getArithemeticFloat16Enabled() const { return false; }
|
||||||
|
#else
|
||||||
|
bool getArithemeticInt8Enabled() const {
|
||||||
|
return extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int8);
|
||||||
|
}
|
||||||
|
bool getArithemeticInt16Enabled() const {
|
||||||
|
return extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
|
extensionRequested(E_GL_AMD_gpu_shader_int16) ||
|
||||||
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_int16);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getArithemeticFloat16Enabled() const {
|
||||||
|
return extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types) ||
|
||||||
|
extensionRequested(E_GL_AMD_gpu_shader_half_float) ||
|
||||||
|
extensionRequested(E_GL_EXT_shader_explicit_arithmetic_types_float16);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
TIntermSymbol* addSymbol(int Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&);
|
||||||
@@ -796,13 +878,21 @@ protected:
|
|||||||
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
bool specConstantPropagates(const TIntermTyped&, const TIntermTyped&);
|
||||||
void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
|
void performTextureUpgradeAndSamplerRemovalTransformation(TIntermNode* root);
|
||||||
bool isConversionAllowed(TOperator op, TIntermTyped* node) const;
|
bool isConversionAllowed(TOperator op, TIntermTyped* node) const;
|
||||||
TIntermTyped* createConversion(TBasicType convertTo, TIntermTyped* node) const;
|
|
||||||
std::tuple<TBasicType, TBasicType> getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const;
|
std::tuple<TBasicType, TBasicType> getConversionDestinatonType(TBasicType type0, TBasicType type1, TOperator op) const;
|
||||||
|
|
||||||
|
// 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();}
|
bool extensionRequested(const char *extension) const {return requestedExtensions.find(extension) != requestedExtensions.end();}
|
||||||
|
#endif
|
||||||
|
|
||||||
static const char* getResourceName(TResourceType);
|
static const char* getResourceName(TResourceType);
|
||||||
|
|
||||||
const EShLanguage language; // stage, known at construction time
|
const EShLanguage language; // stage, known at construction time
|
||||||
EShSource source; // source language, known a bit later
|
|
||||||
std::string entryPointName;
|
std::string entryPointName;
|
||||||
std::string entryPointMangledName;
|
std::string entryPointMangledName;
|
||||||
typedef std::list<TCall> TGraph;
|
typedef std::list<TCall> TGraph;
|
||||||
@@ -818,6 +908,20 @@ protected:
|
|||||||
int numErrors;
|
int numErrors;
|
||||||
int numPushConstants;
|
int numPushConstants;
|
||||||
bool recursive;
|
bool recursive;
|
||||||
|
bool invertY;
|
||||||
|
bool useStorageBuffer;
|
||||||
|
bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN
|
||||||
|
bool depthReplacing;
|
||||||
|
int localSize[3];
|
||||||
|
bool localSizeNotDefault[3];
|
||||||
|
int localSizeSpecId[3];
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
public:
|
||||||
|
const char* const implicitThisName;
|
||||||
|
const char* const implicitCounterName;
|
||||||
|
protected:
|
||||||
|
EShSource source; // source language, known a bit later
|
||||||
|
bool useVulkanMemoryModel;
|
||||||
int invocations;
|
int invocations;
|
||||||
int vertices;
|
int vertices;
|
||||||
TLayoutGeometry inputPrimitive;
|
TLayoutGeometry inputPrimitive;
|
||||||
@@ -826,27 +930,22 @@ protected:
|
|||||||
bool originUpperLeft;
|
bool originUpperLeft;
|
||||||
TVertexSpacing vertexSpacing;
|
TVertexSpacing vertexSpacing;
|
||||||
TVertexOrder vertexOrder;
|
TVertexOrder vertexOrder;
|
||||||
|
TInterlockOrdering interlockOrdering;
|
||||||
bool pointMode;
|
bool pointMode;
|
||||||
int localSize[3];
|
|
||||||
int localSizeSpecId[3];
|
|
||||||
bool earlyFragmentTests;
|
bool earlyFragmentTests;
|
||||||
bool postDepthCoverage;
|
bool postDepthCoverage;
|
||||||
TLayoutDepth depthLayout;
|
TLayoutDepth depthLayout;
|
||||||
bool depthReplacing;
|
|
||||||
bool hlslFunctionality1;
|
bool hlslFunctionality1;
|
||||||
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
|
int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift
|
||||||
bool xfbMode;
|
bool xfbMode;
|
||||||
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
|
std::vector<TXfbBuffer> xfbBuffers; // all the data we need to track per xfb buffer
|
||||||
bool multiStream;
|
bool multiStream;
|
||||||
|
|
||||||
#ifdef NV_EXTENSIONS
|
|
||||||
bool layoutOverrideCoverage;
|
bool layoutOverrideCoverage;
|
||||||
bool geoPassthroughEXT;
|
bool geoPassthroughEXT;
|
||||||
int numShaderRecordNVBlocks;
|
int numShaderRecordNVBlocks;
|
||||||
ComputeDerivativeMode computeDerivativeMode;
|
ComputeDerivativeMode computeDerivativeMode;
|
||||||
int primitives;
|
int primitives;
|
||||||
int numTaskNVBlocks;
|
int numTaskNVBlocks;
|
||||||
#endif
|
|
||||||
|
|
||||||
// Base shift values
|
// Base shift values
|
||||||
std::array<unsigned int, EResCount> shiftBinding;
|
std::array<unsigned int, EResCount> shiftBinding;
|
||||||
@@ -857,23 +956,29 @@ protected:
|
|||||||
std::vector<std::string> resourceSetBinding;
|
std::vector<std::string> resourceSetBinding;
|
||||||
bool autoMapBindings;
|
bool autoMapBindings;
|
||||||
bool autoMapLocations;
|
bool autoMapLocations;
|
||||||
bool invertY;
|
|
||||||
bool flattenUniformArrays;
|
bool flattenUniformArrays;
|
||||||
bool useUnknownFormat;
|
bool useUnknownFormat;
|
||||||
bool hlslOffsets;
|
bool hlslOffsets;
|
||||||
bool useStorageBuffer;
|
|
||||||
bool useVulkanMemoryModel;
|
|
||||||
bool hlslIoMapping;
|
bool hlslIoMapping;
|
||||||
bool useVariablePointers;
|
bool useVariablePointers;
|
||||||
|
|
||||||
std::set<TString> ioAccessed; // set of names of statically read/written I/O that might need extra checking
|
|
||||||
std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers
|
|
||||||
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
|
|
||||||
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
|
||||||
std::set<TString> semanticNameSet;
|
std::set<TString> semanticNameSet;
|
||||||
|
|
||||||
EShTextureSamplerTransformMode textureSamplerTransformMode;
|
EShTextureSamplerTransformMode textureSamplerTransformMode;
|
||||||
|
|
||||||
|
bool needToLegalize;
|
||||||
|
bool binaryDoubleOutput;
|
||||||
|
bool usePhysicalStorageBuffer;
|
||||||
|
|
||||||
|
std::unordered_map<std::string, int> uniformLocationOverrides;
|
||||||
|
int uniformLocationBase;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::unordered_set<int> usedConstantId; // specialization constant ids used
|
||||||
|
std::vector<TOffsetRange> usedAtomics; // sets of bindings used by atomic counters
|
||||||
|
std::vector<TIoRange> usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers
|
||||||
|
// set of names of statically read/written I/O that might need extra checking
|
||||||
|
std::set<TString> ioAccessed;
|
||||||
// source code of shader, useful as part of debug information
|
// source code of shader, useful as part of debug information
|
||||||
std::string sourceFile;
|
std::string sourceFile;
|
||||||
std::string sourceText;
|
std::string sourceText;
|
||||||
@@ -884,13 +989,6 @@ protected:
|
|||||||
// for OpModuleProcessed, or equivalent
|
// for OpModuleProcessed, or equivalent
|
||||||
TProcesses processes;
|
TProcesses processes;
|
||||||
|
|
||||||
bool needToLegalize;
|
|
||||||
bool binaryDoubleOutput;
|
|
||||||
bool usePhysicalStorageBuffer;
|
|
||||||
|
|
||||||
std::unordered_map<std::string, int> uniformLocationOverrides;
|
|
||||||
int uniformLocationBase;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void operator=(TIntermediate&); // prevent assignments
|
void operator=(TIntermediate&); // prevent assignments
|
||||||
};
|
};
|
||||||
|
|||||||
Executable → Regular
+97
-20
@@ -57,26 +57,91 @@ public:
|
|||||||
TParseVersions(TIntermediate& interm, int version, EProfile profile,
|
TParseVersions(TIntermediate& interm, int version, EProfile profile,
|
||||||
const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink,
|
const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink,
|
||||||
bool forwardCompatible, EShMessages messages)
|
bool forwardCompatible, EShMessages messages)
|
||||||
: infoSink(infoSink), version(version), profile(profile), language(language),
|
:
|
||||||
spvVersion(spvVersion), forwardCompatible(forwardCompatible),
|
#ifndef GLSLANG_WEB
|
||||||
|
forwardCompatible(forwardCompatible),
|
||||||
|
profile(profile),
|
||||||
|
#endif
|
||||||
|
infoSink(infoSink), version(version),
|
||||||
|
language(language),
|
||||||
|
spvVersion(spvVersion),
|
||||||
intermediate(interm), messages(messages), numErrors(0), currentScanner(0) { }
|
intermediate(interm), messages(messages), numErrors(0), currentScanner(0) { }
|
||||||
virtual ~TParseVersions() { }
|
virtual ~TParseVersions() { }
|
||||||
|
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) { }
|
||||||
|
void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
|
||||||
|
const char* featureDesc) { }
|
||||||
|
void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
|
||||||
|
const char* featureDesc) { }
|
||||||
|
TExtensionBehavior getExtensionBehavior(const char*) { return EBhMissing; }
|
||||||
|
bool extensionTurnedOn(const char* const extension) { return false; }
|
||||||
|
bool extensionsTurnedOn(int numExtensions, const char* const extensions[]) { return false; }
|
||||||
|
void updateExtensionBehavior(int line, const char* const extension, const char* behavior) { }
|
||||||
|
void updateExtensionBehavior(const char* const extension, TExtensionBehavior) { }
|
||||||
|
void checkExtensionStage(const TSourceLoc&, const char* const extension) { }
|
||||||
|
void fullIntegerCheck(const TSourceLoc&, const char* op) { }
|
||||||
|
void doubleCheck(const TSourceLoc&, const char* op) { }
|
||||||
|
bool float16Arithmetic() { return false; }
|
||||||
|
void requireFloat16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
|
||||||
|
bool int16Arithmetic() { return false; }
|
||||||
|
void requireInt16Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
|
||||||
|
bool int8Arithmetic() { return false; }
|
||||||
|
void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc) { }
|
||||||
|
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 initializeExtensionBehavior();
|
||||||
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);
|
|
||||||
virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
|
virtual void checkDeprecated(const TSourceLoc&, int queryProfiles, int depVersion, const char* featureDesc);
|
||||||
virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc);
|
virtual void requireNotRemoved(const TSourceLoc&, int queryProfiles, int removedVersion, const char* featureDesc);
|
||||||
virtual void unimplemented(const TSourceLoc&, const char* featureDesc);
|
virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
|
||||||
virtual void requireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
const char* featureDesc);
|
||||||
virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
virtual void ppRequireExtensions(const TSourceLoc&, int numExtensions, const char* const extensions[],
|
||||||
|
const char* featureDesc);
|
||||||
virtual TExtensionBehavior getExtensionBehavior(const char*);
|
virtual TExtensionBehavior getExtensionBehavior(const char*);
|
||||||
virtual bool extensionTurnedOn(const char* const extension);
|
virtual bool extensionTurnedOn(const char* const extension);
|
||||||
virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);
|
virtual bool extensionsTurnedOn(int numExtensions, const char* const extensions[]);
|
||||||
virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior);
|
virtual void updateExtensionBehavior(int line, const char* const extension, const char* behavior);
|
||||||
|
virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior);
|
||||||
|
virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[],
|
||||||
|
const char* featureDesc);
|
||||||
|
virtual void checkExtensionStage(const TSourceLoc&, const char* const extension);
|
||||||
virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
|
virtual void fullIntegerCheck(const TSourceLoc&, const char* op);
|
||||||
|
|
||||||
|
virtual void unimplemented(const TSourceLoc&, const char* featureDesc);
|
||||||
virtual void doubleCheck(const TSourceLoc&, const char* op);
|
virtual void doubleCheck(const TSourceLoc&, const char* op);
|
||||||
virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
virtual void float16Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
virtual void float16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
|
virtual void float16ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
@@ -88,24 +153,35 @@ public:
|
|||||||
virtual void int8ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
|
virtual void int8ScalarVectorCheck(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
virtual bool int8Arithmetic();
|
virtual bool int8Arithmetic();
|
||||||
virtual void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc);
|
virtual void requireInt8Arithmetic(const TSourceLoc& loc, const char* op, const char* featureDesc);
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
virtual void float16OpaqueCheck(const TSourceLoc&, const char* op, bool builtIn = false);
|
virtual void float16OpaqueCheck(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
#endif
|
|
||||||
virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
virtual void int64Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
virtual void explicitInt8Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
virtual void explicitInt8Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
virtual void explicitInt16Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
virtual void explicitInt16Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
virtual void explicitInt32Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
virtual void explicitInt32Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
virtual void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
virtual void explicitFloat32Check(const TSourceLoc&, const char* op, bool builtIn = false);
|
||||||
virtual void explicitFloat64Check(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);
|
||||||
|
virtual void intcoopmatCheck(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 spvRemoved(const TSourceLoc&, const char* op);
|
||||||
virtual void vulkanRemoved(const TSourceLoc&, const char* op);
|
virtual void vulkanRemoved(const TSourceLoc&, const char* op);
|
||||||
virtual void requireVulkan(const TSourceLoc&, const char* op);
|
virtual void requireVulkan(const TSourceLoc&, const char* op);
|
||||||
virtual void requireSpv(const TSourceLoc&, const char* op);
|
virtual void requireSpv(const TSourceLoc&, const char* op);
|
||||||
virtual bool checkExtensionsRequested(const TSourceLoc&, int numExtensions, const char* const extensions[], const char* featureDesc);
|
|
||||||
virtual void updateExtensionBehavior(const char* const extension, TExtensionBehavior);
|
|
||||||
virtual void checkExtensionStage(const TSourceLoc&, const char* const extension);
|
|
||||||
virtual void fcoopmatCheck(const TSourceLoc&, const char* op, bool builtIn = false);
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(GLSLANG_WEB) && !defined(GLSLANG_WEB_DEVEL)
|
||||||
|
void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...) { addError(); }
|
||||||
|
void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...) { }
|
||||||
|
void C_DECL ppError(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...) { addError(); }
|
||||||
|
void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
|
const char* szExtraInfoFormat, ...) { }
|
||||||
|
#else
|
||||||
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, ...) = 0;
|
const char* szExtraInfoFormat, ...) = 0;
|
||||||
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
|
virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
@@ -114,6 +190,7 @@ public:
|
|||||||
const char* szExtraInfoFormat, ...) = 0;
|
const char* szExtraInfoFormat, ...) = 0;
|
||||||
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken,
|
||||||
const char* szExtraInfoFormat, ...) = 0;
|
const char* szExtraInfoFormat, ...) = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
void addError() { ++numErrors; }
|
void addError() { ++numErrors; }
|
||||||
int getNumErrors() const { return numErrors; }
|
int getNumErrors() const { return numErrors; }
|
||||||
@@ -127,20 +204,20 @@ public:
|
|||||||
void setCurrentString(int string) { currentScanner->setString(string); }
|
void setCurrentString(int string) { currentScanner->setString(string); }
|
||||||
|
|
||||||
void getPreamble(std::string&);
|
void getPreamble(std::string&);
|
||||||
bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; }
|
#ifdef ENABLE_HLSL
|
||||||
bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; }
|
|
||||||
bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; }
|
bool isReadingHLSL() const { return (messages & EShMsgReadHlsl) == EShMsgReadHlsl; }
|
||||||
bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; }
|
bool hlslEnable16BitTypes() const { return (messages & EShMsgHlslEnable16BitTypes) != 0; }
|
||||||
bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; }
|
bool hlslDX9Compatible() const { return (messages & EShMsgHlslDX9Compatible) != 0; }
|
||||||
|
#else
|
||||||
|
bool isReadingHLSL() const { return false; }
|
||||||
|
#endif
|
||||||
|
|
||||||
TInfoSink& infoSink;
|
TInfoSink& infoSink;
|
||||||
|
|
||||||
// compilation mode
|
// compilation mode
|
||||||
int version; // version, updated by #version in the shader
|
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
|
EShLanguage language; // really the stage
|
||||||
SpvVersion spvVersion;
|
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
|
TIntermediate& intermediate; // helper for making and hooking up pieces of the parse tree
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -545,7 +545,7 @@ int TPpContext::evalToToken(int token, bool shortCircuit, int& res, bool& err, T
|
|||||||
case MacroExpandStarted:
|
case MacroExpandStarted:
|
||||||
break;
|
break;
|
||||||
case MacroExpandUndef:
|
case MacroExpandUndef:
|
||||||
if (! shortCircuit && parseContext.profile == EEsProfile) {
|
if (! shortCircuit && parseContext.isEsProfile()) {
|
||||||
const char* message = "undefined macro in expression not allowed in es profile";
|
const char* message = "undefined macro in expression not allowed in es profile";
|
||||||
if (parseContext.relaxedErrors())
|
if (parseContext.relaxedErrors())
|
||||||
parseContext.ppWarn(ppToken->loc, message, "preprocessor evaluation", ppToken->name);
|
parseContext.ppWarn(ppToken->loc, message, "preprocessor evaluation", ppToken->name);
|
||||||
@@ -722,6 +722,7 @@ int TPpContext::CPPline(TPpToken* ppToken)
|
|||||||
parseContext.setCurrentLine(lineRes);
|
parseContext.setCurrentLine(lineRes);
|
||||||
|
|
||||||
if (token != '\n') {
|
if (token != '\n') {
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (token == PpAtomConstString) {
|
if (token == PpAtomConstString) {
|
||||||
parseContext.ppRequireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line");
|
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
|
// We need to save a copy of the string instead of pointing
|
||||||
@@ -731,7 +732,9 @@ int TPpContext::CPPline(TPpToken* ppToken)
|
|||||||
parseContext.setCurrentSourceName(sourceName);
|
parseContext.setCurrentSourceName(sourceName);
|
||||||
hasFile = true;
|
hasFile = true;
|
||||||
token = scanToken(ppToken);
|
token = scanToken(ppToken);
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken);
|
token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken);
|
||||||
if (! fileErr) {
|
if (! fileErr) {
|
||||||
parseContext.setCurrentString(fileRes);
|
parseContext.setCurrentString(fileRes);
|
||||||
@@ -792,10 +795,8 @@ int TPpContext::CPPpragma(TPpToken* ppToken)
|
|||||||
case PpAtomConstUint:
|
case PpAtomConstUint:
|
||||||
case PpAtomConstInt64:
|
case PpAtomConstInt64:
|
||||||
case PpAtomConstUint64:
|
case PpAtomConstUint64:
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case PpAtomConstInt16:
|
case PpAtomConstInt16:
|
||||||
case PpAtomConstUint16:
|
case PpAtomConstUint16:
|
||||||
#endif
|
|
||||||
case PpAtomConstFloat:
|
case PpAtomConstFloat:
|
||||||
case PpAtomConstDouble:
|
case PpAtomConstDouble:
|
||||||
case PpAtomConstFloat16:
|
case PpAtomConstFloat16:
|
||||||
@@ -954,18 +955,20 @@ int TPpContext::readCPPline(TPpToken* ppToken)
|
|||||||
case PpAtomIfndef:
|
case PpAtomIfndef:
|
||||||
token = CPPifdef(0, ppToken);
|
token = CPPifdef(0, ppToken);
|
||||||
break;
|
break;
|
||||||
|
case PpAtomLine:
|
||||||
|
token = CPPline(ppToken);
|
||||||
|
break;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
case PpAtomInclude:
|
case PpAtomInclude:
|
||||||
if(!parseContext.isReadingHLSL()) {
|
if(!parseContext.isReadingHLSL()) {
|
||||||
parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include");
|
parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include");
|
||||||
}
|
}
|
||||||
token = CPPinclude(ppToken);
|
token = CPPinclude(ppToken);
|
||||||
break;
|
break;
|
||||||
case PpAtomLine:
|
|
||||||
token = CPPline(ppToken);
|
|
||||||
break;
|
|
||||||
case PpAtomPragma:
|
case PpAtomPragma:
|
||||||
token = CPPpragma(ppToken);
|
token = CPPpragma(ppToken);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
case PpAtomUndef:
|
case PpAtomUndef:
|
||||||
token = CPPundef(ppToken);
|
token = CPPundef(ppToken);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
|||||||
ch = getChar();
|
ch = getChar();
|
||||||
int firstDecimal = len;
|
int firstDecimal = len;
|
||||||
|
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
// 1.#INF or -1.#INF
|
// 1.#INF or -1.#INF
|
||||||
if (ch == '#' && (ifdepth > 0 || parseContext.intermediate.getSource() == EShSourceHlsl)) {
|
if (ch == '#' && (ifdepth > 0 || parseContext.intermediate.getSource() == EShSourceHlsl)) {
|
||||||
if ((len < 2) ||
|
if ((len < 2) ||
|
||||||
@@ -169,6 +170,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Consume leading-zero digits after the decimal point
|
// Consume leading-zero digits after the decimal point
|
||||||
while (ch == '0') {
|
while (ch == '0') {
|
||||||
@@ -257,6 +259,7 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
|||||||
// Suffix:
|
// Suffix:
|
||||||
bool isDouble = false;
|
bool isDouble = false;
|
||||||
bool isFloat16 = false;
|
bool isFloat16 = false;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (ch == 'l' || ch == 'L') {
|
if (ch == 'l' || ch == 'L') {
|
||||||
if (ifdepth == 0 && parseContext.intermediate.getSource() == EShSourceGlsl)
|
if (ifdepth == 0 && parseContext.intermediate.getSource() == EShSourceGlsl)
|
||||||
parseContext.doubleCheck(ppToken->loc, "double floating-point suffix");
|
parseContext.doubleCheck(ppToken->loc, "double floating-point suffix");
|
||||||
@@ -295,11 +298,15 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken)
|
|||||||
saveName(ch);
|
saveName(ch);
|
||||||
isFloat16 = true;
|
isFloat16 = true;
|
||||||
}
|
}
|
||||||
} else if (ch == 'f' || ch == 'F') {
|
} else
|
||||||
|
#endif
|
||||||
|
if (ch == 'f' || ch == 'F') {
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
if (ifdepth == 0)
|
if (ifdepth == 0)
|
||||||
parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix");
|
parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix");
|
||||||
if (ifdepth == 0 && !parseContext.relaxedErrors())
|
if (ifdepth == 0 && !parseContext.relaxedErrors())
|
||||||
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix");
|
parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix");
|
||||||
|
#endif
|
||||||
if (ifdepth == 0 && !hasDecimalOrExponent)
|
if (ifdepth == 0 && !hasDecimalOrExponent)
|
||||||
parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
|
parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", "");
|
||||||
saveName(ch);
|
saveName(ch);
|
||||||
@@ -468,9 +475,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
static const int Num_Int64_Extensions = sizeof(Int64_Extensions) / sizeof(Int64_Extensions[0]);
|
static const int Num_Int64_Extensions = sizeof(Int64_Extensions) / sizeof(Int64_Extensions[0]);
|
||||||
|
|
||||||
static const char* const Int16_Extensions[] = {
|
static const char* const Int16_Extensions[] = {
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
E_GL_AMD_gpu_shader_int16,
|
E_GL_AMD_gpu_shader_int16,
|
||||||
#endif
|
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types,
|
E_GL_EXT_shader_explicit_arithmetic_types,
|
||||||
E_GL_EXT_shader_explicit_arithmetic_types_int16 };
|
E_GL_EXT_shader_explicit_arithmetic_types_int16 };
|
||||||
static const int Num_Int16_Extensions = sizeof(Int16_Extensions) / sizeof(Int16_Extensions[0]);
|
static const int Num_Int16_Extensions = sizeof(Int16_Extensions) / sizeof(Int16_Extensions[0]);
|
||||||
@@ -579,6 +584,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isUnsigned = true;
|
isUnsigned = true;
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
int nextCh = getch();
|
int nextCh = getch();
|
||||||
if (nextCh == 'l' || nextCh == 'L') {
|
if (nextCh == 'l' || nextCh == 'L') {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
@@ -587,7 +593,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
nextCh = getch();
|
nextCh = getch();
|
||||||
if ((nextCh == 's' || nextCh == 'S') &&
|
if ((nextCh == 's' || nextCh == 'S') &&
|
||||||
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
||||||
@@ -596,12 +601,10 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
isInt16 = true;
|
isInt16 = true;
|
||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
#endif
|
|
||||||
} else if (ch == 'l' || ch == 'L') {
|
} else if (ch == 'l' || ch == 'L') {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isInt64 = true;
|
isInt64 = true;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
} else if ((ch == 's' || ch == 'S') &&
|
} else if ((ch == 's' || ch == 'S') &&
|
||||||
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
@@ -689,6 +692,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isUnsigned = true;
|
isUnsigned = true;
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
int nextCh = getch();
|
int nextCh = getch();
|
||||||
if (nextCh == 'l' || nextCh == 'L') {
|
if (nextCh == 'l' || nextCh == 'L') {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
@@ -697,7 +701,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
nextCh = getch();
|
nextCh = getch();
|
||||||
if ((nextCh == 's' || nextCh == 'S') &&
|
if ((nextCh == 's' || nextCh == 'S') &&
|
||||||
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
||||||
@@ -706,12 +709,10 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
isInt16 = true;
|
isInt16 = true;
|
||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
#endif
|
|
||||||
} else if (ch == 'l' || ch == 'L') {
|
} else if (ch == 'l' || ch == 'L') {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isInt64 = true;
|
isInt64 = true;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
} else if ((ch == 's' || ch == 'S') &&
|
} else if ((ch == 's' || ch == 'S') &&
|
||||||
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
@@ -780,6 +781,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isUnsigned = true;
|
isUnsigned = true;
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
int nextCh = getch();
|
int nextCh = getch();
|
||||||
if (nextCh == 'l' || nextCh == 'L') {
|
if (nextCh == 'l' || nextCh == 'L') {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
@@ -788,7 +790,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
|
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
nextCh = getch();
|
nextCh = getch();
|
||||||
if ((nextCh == 's' || nextCh == 'S') &&
|
if ((nextCh == 's' || nextCh == 'S') &&
|
||||||
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
||||||
@@ -797,12 +798,10 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
isInt16 = true;
|
isInt16 = true;
|
||||||
} else
|
} else
|
||||||
ungetch();
|
ungetch();
|
||||||
#endif
|
|
||||||
} else if (ch == 'l' || ch == 'L') {
|
} else if (ch == 'l' || ch == 'L') {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isInt64 = true;
|
isInt64 = true;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
} else if ((ch == 's' || ch == 'S') &&
|
} else if ((ch == 's' || ch == 'S') &&
|
||||||
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
pp->parseContext.intermediate.getSource() == EShSourceGlsl) {
|
||||||
if (len < MaxTokenLength)
|
if (len < MaxTokenLength)
|
||||||
|
|||||||
@@ -116,6 +116,7 @@ int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken
|
|||||||
int atom = stream[currentPos++].get(*ppToken);
|
int atom = stream[currentPos++].get(*ppToken);
|
||||||
ppToken->loc = parseContext.getCurrentLoc();
|
ppToken->loc = parseContext.getCurrentLoc();
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
// Check for ##, unless the current # is the last character
|
// Check for ##, unless the current # is the last character
|
||||||
if (atom == '#') {
|
if (atom == '#') {
|
||||||
if (peekToken('#')) {
|
if (peekToken('#')) {
|
||||||
@@ -125,6 +126,7 @@ int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken
|
|||||||
atom = PpAtomPaste;
|
atom = PpAtomPaste;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return atom;
|
return atom;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,8 @@
|
|||||||
// propagate the 'noContraction' qualifier.
|
// propagate the 'noContraction' qualifier.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
#include "propagateNoContraction.h"
|
#include "propagateNoContraction.h"
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
@@ -79,7 +81,7 @@ typedef std::unordered_set<glslang::TIntermBranch*> ReturnBranchNodeSet;
|
|||||||
// the node has 'noContraction' qualifier, otherwise false.
|
// the node has 'noContraction' qualifier, otherwise false.
|
||||||
bool isPreciseObjectNode(glslang::TIntermTyped* node)
|
bool isPreciseObjectNode(glslang::TIntermTyped* node)
|
||||||
{
|
{
|
||||||
return node->getType().getQualifier().noContraction;
|
return node->getType().getQualifier().isNoContraction();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the opcode is a dereferencing one.
|
// Returns true if the opcode is a dereferencing one.
|
||||||
@@ -864,3 +866,5 @@ void PropagateNoContraction(const glslang::TIntermediate& intermediate)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // GLSLANG_WEB
|
||||||
@@ -33,6 +33,8 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
#include "../Include/Common.h"
|
#include "../Include/Common.h"
|
||||||
#include "reflection.h"
|
#include "reflection.h"
|
||||||
#include "LiveTraverser.h"
|
#include "LiveTraverser.h"
|
||||||
@@ -110,6 +112,10 @@ public:
|
|||||||
TReflection::TMapIndexToReflection &ioItems =
|
TReflection::TMapIndexToReflection &ioItems =
|
||||||
input ? reflection.indexToPipeInput : reflection.indexToPipeOutput;
|
input ? reflection.indexToPipeInput : reflection.indexToPipeOutput;
|
||||||
|
|
||||||
|
|
||||||
|
TReflection::TNameToIndex &ioMapper =
|
||||||
|
input ? reflection.pipeInNameToIndex : reflection.pipeOutNameToIndex;
|
||||||
|
|
||||||
if (reflection.options & EShReflectionUnwrapIOBlocks) {
|
if (reflection.options & EShReflectionUnwrapIOBlocks) {
|
||||||
bool anonymous = IsAnonymous(name);
|
bool anonymous = IsAnonymous(name);
|
||||||
|
|
||||||
@@ -127,12 +133,13 @@ public:
|
|||||||
blowUpIOAggregate(input, baseName, type);
|
blowUpIOAggregate(input, baseName, type);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TReflection::TNameToIndex::const_iterator it = reflection.nameToIndex.find(name.c_str());
|
TReflection::TNameToIndex::const_iterator it = ioMapper.find(name.c_str());
|
||||||
if (it == reflection.nameToIndex.end()) {
|
if (it == ioMapper.end()) {
|
||||||
reflection.nameToIndex[name.c_str()] = (int)ioItems.size();
|
// seperate pipe i/o params from uniforms and blocks
|
||||||
|
// in is only for input in first stage as out is only for last stage. check traverse in call stack.
|
||||||
|
ioMapper[name.c_str()] = static_cast<int>(ioItems.size());
|
||||||
ioItems.push_back(
|
ioItems.push_back(
|
||||||
TObjectReflection(name.c_str(), type, 0, mapToGlType(type), mapToGlArraySize(type), 0));
|
TObjectReflection(name.c_str(), type, 0, mapToGlType(type), mapToGlArraySize(type), 0));
|
||||||
|
|
||||||
EShLanguageMask& stages = ioItems.back().stages;
|
EShLanguageMask& stages = ioItems.back().stages;
|
||||||
stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
|
stages = static_cast<EShLanguageMask>(stages | 1 << intermediate.getStage());
|
||||||
} else {
|
} else {
|
||||||
@@ -396,7 +403,7 @@ public:
|
|||||||
topLevelArrayStride = variables.back().arrayStride;
|
topLevelArrayStride = variables.back().arrayStride;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((reflection.options & EShReflectionSeparateBuffers) && terminalType->getBasicType() == EbtAtomicUint)
|
if ((reflection.options & EShReflectionSeparateBuffers) && terminalType->isAtomic())
|
||||||
reflection.atomicCounterUniformIndices.push_back(uniformIndex);
|
reflection.atomicCounterUniformIndices.push_back(uniformIndex);
|
||||||
|
|
||||||
variables.back().topLevelArrayStride = topLevelArrayStride;
|
variables.back().topLevelArrayStride = topLevelArrayStride;
|
||||||
@@ -554,15 +561,18 @@ public:
|
|||||||
bool blockParent = (base->getType().getBasicType() == EbtBlock && base->getQualifier().storage == EvqBuffer);
|
bool blockParent = (base->getType().getBasicType() == EbtBlock && base->getQualifier().storage == EvqBuffer);
|
||||||
|
|
||||||
if (strictArraySuffix && blockParent) {
|
if (strictArraySuffix && blockParent) {
|
||||||
const TTypeList& typeList = *base->getType().getStruct();
|
TType structDerefType(base->getType(), 0);
|
||||||
|
|
||||||
|
const TType &structType = base->getType().isArray() ? structDerefType : base->getType();
|
||||||
|
const TTypeList& typeList = *structType.getStruct();
|
||||||
|
|
||||||
TVector<int> memberOffsets;
|
TVector<int> memberOffsets;
|
||||||
|
|
||||||
memberOffsets.resize(typeList.size());
|
memberOffsets.resize(typeList.size());
|
||||||
getOffsets(base->getType(), memberOffsets);
|
getOffsets(structType, memberOffsets);
|
||||||
|
|
||||||
for (int i = 0; i < (int)typeList.size(); ++i) {
|
for (int i = 0; i < (int)typeList.size(); ++i) {
|
||||||
TType derefType(base->getType(), i);
|
TType derefType(structType, i);
|
||||||
TString name = baseName;
|
TString name = baseName;
|
||||||
if (name.size() > 0)
|
if (name.size() > 0)
|
||||||
name.append(".");
|
name.append(".");
|
||||||
@@ -573,7 +583,7 @@ public:
|
|||||||
if (derefType.isArray() && derefType.isStruct()) {
|
if (derefType.isArray() && derefType.isStruct()) {
|
||||||
name.append("[0]");
|
name.append("[0]");
|
||||||
blowUpActiveAggregate(TType(derefType, 0), name, derefs, derefs.end(), memberOffsets[i],
|
blowUpActiveAggregate(TType(derefType, 0), name, derefs, derefs.end(), memberOffsets[i],
|
||||||
blockIndex, 0, getArrayStride(base->getType(), derefType),
|
blockIndex, 0, getArrayStride(structType, derefType),
|
||||||
base->getQualifier().storage, false);
|
base->getQualifier().storage, false);
|
||||||
} else {
|
} else {
|
||||||
blowUpActiveAggregate(derefType, name, derefs, derefs.end(), memberOffsets[i], blockIndex,
|
blowUpActiveAggregate(derefType, name, derefs, derefs.end(), memberOffsets[i], blockIndex,
|
||||||
@@ -701,7 +711,6 @@ public:
|
|||||||
case EsdBuffer:
|
case EsdBuffer:
|
||||||
return GL_SAMPLER_BUFFER;
|
return GL_SAMPLER_BUFFER;
|
||||||
}
|
}
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
switch ((int)sampler.dim) {
|
switch ((int)sampler.dim) {
|
||||||
case Esd1D:
|
case Esd1D:
|
||||||
@@ -730,7 +739,6 @@ public:
|
|||||||
case EsdBuffer:
|
case EsdBuffer:
|
||||||
return GL_FLOAT16_SAMPLER_BUFFER_AMD;
|
return GL_FLOAT16_SAMPLER_BUFFER_AMD;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
switch ((int)sampler.dim) {
|
switch ((int)sampler.dim) {
|
||||||
case Esd1D:
|
case Esd1D:
|
||||||
@@ -793,7 +801,6 @@ public:
|
|||||||
case EsdBuffer:
|
case EsdBuffer:
|
||||||
return GL_IMAGE_BUFFER;
|
return GL_IMAGE_BUFFER;
|
||||||
}
|
}
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
switch ((int)sampler.dim) {
|
switch ((int)sampler.dim) {
|
||||||
case Esd1D:
|
case Esd1D:
|
||||||
@@ -812,7 +819,6 @@ public:
|
|||||||
case EsdBuffer:
|
case EsdBuffer:
|
||||||
return GL_FLOAT16_IMAGE_BUFFER_AMD;
|
return GL_FLOAT16_IMAGE_BUFFER_AMD;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
case EbtInt:
|
case EbtInt:
|
||||||
switch ((int)sampler.dim) {
|
switch ((int)sampler.dim) {
|
||||||
case Esd1D:
|
case Esd1D:
|
||||||
@@ -878,9 +884,7 @@ public:
|
|||||||
switch (type.getBasicType()) {
|
switch (type.getBasicType()) {
|
||||||
case EbtFloat: return GL_FLOAT_VEC2 + offset;
|
case EbtFloat: return GL_FLOAT_VEC2 + offset;
|
||||||
case EbtDouble: return GL_DOUBLE_VEC2 + offset;
|
case EbtDouble: return GL_DOUBLE_VEC2 + offset;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbtFloat16: return GL_FLOAT16_VEC2_NV + offset;
|
case EbtFloat16: return GL_FLOAT16_VEC2_NV + offset;
|
||||||
#endif
|
|
||||||
case EbtInt: return GL_INT_VEC2 + offset;
|
case EbtInt: return GL_INT_VEC2 + offset;
|
||||||
case EbtUint: return GL_UNSIGNED_INT_VEC2 + offset;
|
case EbtUint: return GL_UNSIGNED_INT_VEC2 + offset;
|
||||||
case EbtInt64: return GL_INT64_ARB + offset;
|
case EbtInt64: return GL_INT64_ARB + offset;
|
||||||
@@ -940,7 +944,6 @@ public:
|
|||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbtFloat16:
|
case EbtFloat16:
|
||||||
switch (type.getMatrixCols()) {
|
switch (type.getMatrixCols()) {
|
||||||
case 2:
|
case 2:
|
||||||
@@ -965,7 +968,6 @@ public:
|
|||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -974,9 +976,7 @@ public:
|
|||||||
switch (type.getBasicType()) {
|
switch (type.getBasicType()) {
|
||||||
case EbtFloat: return GL_FLOAT;
|
case EbtFloat: return GL_FLOAT;
|
||||||
case EbtDouble: return GL_DOUBLE;
|
case EbtDouble: return GL_DOUBLE;
|
||||||
#ifdef AMD_EXTENSIONS
|
|
||||||
case EbtFloat16: return GL_FLOAT16_NV;
|
case EbtFloat16: return GL_FLOAT16_NV;
|
||||||
#endif
|
|
||||||
case EbtInt: return GL_INT;
|
case EbtInt: return GL_INT;
|
||||||
case EbtUint: return GL_UNSIGNED_INT;
|
case EbtUint: return GL_UNSIGNED_INT;
|
||||||
case EbtInt64: return GL_INT64_ARB;
|
case EbtInt64: return GL_INT64_ARB;
|
||||||
@@ -1093,6 +1093,7 @@ void TReflection::buildAttributeReflection(EShLanguage stage, const TIntermediat
|
|||||||
// build counter block index associations for buffers
|
// build counter block index associations for buffers
|
||||||
void TReflection::buildCounterIndices(const TIntermediate& intermediate)
|
void TReflection::buildCounterIndices(const TIntermediate& intermediate)
|
||||||
{
|
{
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
// search for ones that have counters
|
// search for ones that have counters
|
||||||
for (int i = 0; i < int(indexToUniformBlock.size()); ++i) {
|
for (int i = 0; i < int(indexToUniformBlock.size()); ++i) {
|
||||||
const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name).c_str());
|
const TString counterName(intermediate.addCounterBufferName(indexToUniformBlock[i].name).c_str());
|
||||||
@@ -1101,6 +1102,7 @@ void TReflection::buildCounterIndices(const TIntermediate& intermediate)
|
|||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
indexToUniformBlock[i].counterIndex = index;
|
indexToUniformBlock[i].counterIndex = index;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// build Shader Stages mask for all uniforms
|
// build Shader Stages mask for all uniforms
|
||||||
@@ -1198,3 +1200,5 @@ void TReflection::dump()
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // GLSLANG_WEB
|
||||||
|
|||||||
@@ -33,6 +33,8 @@
|
|||||||
// POSSIBILITY OF SUCH DAMAGE.
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
#ifndef _REFLECTION_INCLUDED
|
#ifndef _REFLECTION_INCLUDED
|
||||||
#define _REFLECTION_INCLUDED
|
#define _REFLECTION_INCLUDED
|
||||||
|
|
||||||
@@ -150,6 +152,20 @@ public:
|
|||||||
// see getIndex(const char*)
|
// see getIndex(const char*)
|
||||||
int getIndex(const TString& name) const { return getIndex(name.c_str()); }
|
int getIndex(const TString& name) const { return getIndex(name.c_str()); }
|
||||||
|
|
||||||
|
|
||||||
|
// for mapping any name to its index (only pipe input/output names)
|
||||||
|
int getPipeIOIndex(const char* name, const bool inOrOut) const
|
||||||
|
{
|
||||||
|
TNameToIndex::const_iterator it = inOrOut ? pipeInNameToIndex.find(name) : pipeOutNameToIndex.find(name);
|
||||||
|
if (it == (inOrOut ? pipeInNameToIndex.end() : pipeOutNameToIndex.end()))
|
||||||
|
return -1;
|
||||||
|
else
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// see gePipeIOIndex(const char*, const bool)
|
||||||
|
int getPipeIOIndex(const TString& name, const bool inOrOut) const { return getPipeIOIndex(name.c_str(), inOrOut); }
|
||||||
|
|
||||||
// Thread local size
|
// Thread local size
|
||||||
unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; }
|
unsigned getLocalSize(int dim) const { return dim <= 2 ? localSize[dim] : 0; }
|
||||||
|
|
||||||
@@ -187,6 +203,8 @@ protected:
|
|||||||
|
|
||||||
TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this
|
TObjectReflection badReflection; // return for queries of -1 or generally out of range; has expected descriptions with in it for this
|
||||||
TNameToIndex nameToIndex; // maps names to indexes; can hold all types of data: uniform/buffer and which function names have been processed
|
TNameToIndex nameToIndex; // maps names to indexes; can hold all types of data: uniform/buffer and which function names have been processed
|
||||||
|
TNameToIndex pipeInNameToIndex; // maps pipe in names to indexes, this is a fix to seperate pipe I/O from uniforms and buffers.
|
||||||
|
TNameToIndex pipeOutNameToIndex; // maps pipe out names to indexes, this is a fix to seperate pipe I/O from uniforms and buffers.
|
||||||
TMapIndexToReflection indexToUniform;
|
TMapIndexToReflection indexToUniform;
|
||||||
TMapIndexToReflection indexToUniformBlock;
|
TMapIndexToReflection indexToUniformBlock;
|
||||||
TMapIndexToReflection indexToBufferVariable;
|
TMapIndexToReflection indexToBufferVariable;
|
||||||
@@ -201,3 +219,5 @@ protected:
|
|||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
|
||||||
#endif // _REFLECTION_INCLUDED
|
#endif // _REFLECTION_INCLUDED
|
||||||
|
|
||||||
|
#endif // GLSLANG_WEB
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
export default (() => {
|
||||||
|
const initialize = () => {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
Module({
|
||||||
|
locateFile() {
|
||||||
|
const i = import.meta.url.lastIndexOf('/')
|
||||||
|
return import.meta.url.substring(0, i) + '/glslang.wasm';
|
||||||
|
},
|
||||||
|
onRuntimeInitialized() {
|
||||||
|
resolve({
|
||||||
|
compileGLSLZeroCopy: this.compileGLSLZeroCopy,
|
||||||
|
compileGLSL: this.compileGLSL,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
let instance;
|
||||||
|
return () => {
|
||||||
|
if (!instance) {
|
||||||
|
instance = initialize();
|
||||||
|
}
|
||||||
|
return instance;
|
||||||
|
};
|
||||||
|
})();
|
||||||
@@ -0,0 +1,269 @@
|
|||||||
|
//
|
||||||
|
// Copyright (C) 2019 Google, Inc.
|
||||||
|
//
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions
|
||||||
|
// are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#ifdef __EMSCRIPTEN__
|
||||||
|
#include <emscripten.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "../../../SPIRV/GlslangToSpv.h"
|
||||||
|
#include "../../../glslang/Public/ShaderLang.h"
|
||||||
|
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
|
#define EMSCRIPTEN_KEEPALIVE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const TBuiltInResource DefaultTBuiltInResource = {
|
||||||
|
/* .MaxLights = */ 32,
|
||||||
|
/* .MaxClipPlanes = */ 6,
|
||||||
|
/* .MaxTextureUnits = */ 32,
|
||||||
|
/* .MaxTextureCoords = */ 32,
|
||||||
|
/* .MaxVertexAttribs = */ 64,
|
||||||
|
/* .MaxVertexUniformComponents = */ 4096,
|
||||||
|
/* .MaxVaryingFloats = */ 64,
|
||||||
|
/* .MaxVertexTextureImageUnits = */ 32,
|
||||||
|
/* .MaxCombinedTextureImageUnits = */ 80,
|
||||||
|
/* .MaxTextureImageUnits = */ 32,
|
||||||
|
/* .MaxFragmentUniformComponents = */ 4096,
|
||||||
|
/* .MaxDrawBuffers = */ 32,
|
||||||
|
/* .MaxVertexUniformVectors = */ 128,
|
||||||
|
/* .MaxVaryingVectors = */ 8,
|
||||||
|
/* .MaxFragmentUniformVectors = */ 16,
|
||||||
|
/* .MaxVertexOutputVectors = */ 16,
|
||||||
|
/* .MaxFragmentInputVectors = */ 15,
|
||||||
|
/* .MinProgramTexelOffset = */ -8,
|
||||||
|
/* .MaxProgramTexelOffset = */ 7,
|
||||||
|
/* .MaxClipDistances = */ 8,
|
||||||
|
/* .MaxComputeWorkGroupCountX = */ 65535,
|
||||||
|
/* .MaxComputeWorkGroupCountY = */ 65535,
|
||||||
|
/* .MaxComputeWorkGroupCountZ = */ 65535,
|
||||||
|
/* .MaxComputeWorkGroupSizeX = */ 1024,
|
||||||
|
/* .MaxComputeWorkGroupSizeY = */ 1024,
|
||||||
|
/* .MaxComputeWorkGroupSizeZ = */ 64,
|
||||||
|
/* .MaxComputeUniformComponents = */ 1024,
|
||||||
|
/* .MaxComputeTextureImageUnits = */ 16,
|
||||||
|
/* .MaxComputeImageUniforms = */ 8,
|
||||||
|
/* .MaxComputeAtomicCounters = */ 8,
|
||||||
|
/* .MaxComputeAtomicCounterBuffers = */ 1,
|
||||||
|
/* .MaxVaryingComponents = */ 60,
|
||||||
|
/* .MaxVertexOutputComponents = */ 64,
|
||||||
|
/* .MaxGeometryInputComponents = */ 64,
|
||||||
|
/* .MaxGeometryOutputComponents = */ 128,
|
||||||
|
/* .MaxFragmentInputComponents = */ 128,
|
||||||
|
/* .MaxImageUnits = */ 8,
|
||||||
|
/* .MaxCombinedImageUnitsAndFragmentOutputs = */ 8,
|
||||||
|
/* .MaxCombinedShaderOutputResources = */ 8,
|
||||||
|
/* .MaxImageSamples = */ 0,
|
||||||
|
/* .MaxVertexImageUniforms = */ 0,
|
||||||
|
/* .MaxTessControlImageUniforms = */ 0,
|
||||||
|
/* .MaxTessEvaluationImageUniforms = */ 0,
|
||||||
|
/* .MaxGeometryImageUniforms = */ 0,
|
||||||
|
/* .MaxFragmentImageUniforms = */ 8,
|
||||||
|
/* .MaxCombinedImageUniforms = */ 8,
|
||||||
|
/* .MaxGeometryTextureImageUnits = */ 16,
|
||||||
|
/* .MaxGeometryOutputVertices = */ 256,
|
||||||
|
/* .MaxGeometryTotalOutputComponents = */ 1024,
|
||||||
|
/* .MaxGeometryUniformComponents = */ 1024,
|
||||||
|
/* .MaxGeometryVaryingComponents = */ 64,
|
||||||
|
/* .MaxTessControlInputComponents = */ 128,
|
||||||
|
/* .MaxTessControlOutputComponents = */ 128,
|
||||||
|
/* .MaxTessControlTextureImageUnits = */ 16,
|
||||||
|
/* .MaxTessControlUniformComponents = */ 1024,
|
||||||
|
/* .MaxTessControlTotalOutputComponents = */ 4096,
|
||||||
|
/* .MaxTessEvaluationInputComponents = */ 128,
|
||||||
|
/* .MaxTessEvaluationOutputComponents = */ 128,
|
||||||
|
/* .MaxTessEvaluationTextureImageUnits = */ 16,
|
||||||
|
/* .MaxTessEvaluationUniformComponents = */ 1024,
|
||||||
|
/* .MaxTessPatchComponents = */ 120,
|
||||||
|
/* .MaxPatchVertices = */ 32,
|
||||||
|
/* .MaxTessGenLevel = */ 64,
|
||||||
|
/* .MaxViewports = */ 16,
|
||||||
|
/* .MaxVertexAtomicCounters = */ 0,
|
||||||
|
/* .MaxTessControlAtomicCounters = */ 0,
|
||||||
|
/* .MaxTessEvaluationAtomicCounters = */ 0,
|
||||||
|
/* .MaxGeometryAtomicCounters = */ 0,
|
||||||
|
/* .MaxFragmentAtomicCounters = */ 8,
|
||||||
|
/* .MaxCombinedAtomicCounters = */ 8,
|
||||||
|
/* .MaxAtomicCounterBindings = */ 1,
|
||||||
|
/* .MaxVertexAtomicCounterBuffers = */ 0,
|
||||||
|
/* .MaxTessControlAtomicCounterBuffers = */ 0,
|
||||||
|
/* .MaxTessEvaluationAtomicCounterBuffers = */ 0,
|
||||||
|
/* .MaxGeometryAtomicCounterBuffers = */ 0,
|
||||||
|
/* .MaxFragmentAtomicCounterBuffers = */ 1,
|
||||||
|
/* .MaxCombinedAtomicCounterBuffers = */ 1,
|
||||||
|
/* .MaxAtomicCounterBufferSize = */ 16384,
|
||||||
|
/* .MaxTransformFeedbackBuffers = */ 4,
|
||||||
|
/* .MaxTransformFeedbackInterleavedComponents = */ 64,
|
||||||
|
/* .MaxCullDistances = */ 8,
|
||||||
|
/* .MaxCombinedClipAndCullDistances = */ 8,
|
||||||
|
/* .MaxSamples = */ 4,
|
||||||
|
/* .maxMeshOutputVerticesNV = */ 256,
|
||||||
|
/* .maxMeshOutputPrimitivesNV = */ 512,
|
||||||
|
/* .maxMeshWorkGroupSizeX_NV = */ 32,
|
||||||
|
/* .maxMeshWorkGroupSizeY_NV = */ 1,
|
||||||
|
/* .maxMeshWorkGroupSizeZ_NV = */ 1,
|
||||||
|
/* .maxTaskWorkGroupSizeX_NV = */ 32,
|
||||||
|
/* .maxTaskWorkGroupSizeY_NV = */ 1,
|
||||||
|
/* .maxTaskWorkGroupSizeZ_NV = */ 1,
|
||||||
|
/* .maxMeshViewCountNV = */ 4,
|
||||||
|
|
||||||
|
/* .limits = */ {
|
||||||
|
/* .nonInductiveForLoops = */ 1,
|
||||||
|
/* .whileLoops = */ 1,
|
||||||
|
/* .doWhileLoops = */ 1,
|
||||||
|
/* .generalUniformIndexing = */ 1,
|
||||||
|
/* .generalAttributeMatrixVectorIndexing = */ 1,
|
||||||
|
/* .generalVaryingIndexing = */ 1,
|
||||||
|
/* .generalSamplerIndexing = */ 1,
|
||||||
|
/* .generalVariableIndexing = */ 1,
|
||||||
|
/* .generalConstantMatrixVectorIndexing = */ 1,
|
||||||
|
}};
|
||||||
|
|
||||||
|
static bool initialized = false;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Takes in a GLSL shader as a string and converts it to SPIR-V in binary form.
|
||||||
|
*
|
||||||
|
* |glsl| Null-terminated string containing the shader to be converted.
|
||||||
|
* |stage_int| Magic number indicating the type of shader being processed.
|
||||||
|
* Legal values are as follows:
|
||||||
|
* Vertex = 0
|
||||||
|
* Fragment = 4
|
||||||
|
* Compute = 5
|
||||||
|
* |gen_debug| Flag to indicate if debug information should be generated.
|
||||||
|
* |spirv| Output parameter for a pointer to the resulting SPIR-V data.
|
||||||
|
* |spirv_len| Output parameter for the length of the output binary buffer.
|
||||||
|
*
|
||||||
|
* Returns a void* pointer which, if not null, must be destroyed by
|
||||||
|
* destroy_output_buffer.o. (This is not the same pointer returned in |spirv|.)
|
||||||
|
* If null, the compilation failed.
|
||||||
|
*/
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
void* convert_glsl_to_spirv(const char* glsl, int stage_int, bool gen_debug, uint32_t** spirv, size_t* spirv_len)
|
||||||
|
{
|
||||||
|
if (glsl == nullptr) {
|
||||||
|
fprintf(stderr, "Input pointer null\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (spirv == nullptr || spirv_len == nullptr) {
|
||||||
|
fprintf(stderr, "Output pointer null\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
*spirv = nullptr;
|
||||||
|
*spirv_len = 0;
|
||||||
|
|
||||||
|
if (stage_int != 0 && stage_int != 4 && stage_int != 5) {
|
||||||
|
fprintf(stderr, "Invalid shader stage\n");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
EShLanguage stage = static_cast<EShLanguage>(stage_int);
|
||||||
|
|
||||||
|
if (!initialized) {
|
||||||
|
glslang::InitializeProcess();
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
glslang::TShader shader(stage);
|
||||||
|
shader.setStrings(&glsl, 1);
|
||||||
|
shader.setEnvInput(glslang::EShSourceGlsl, stage, glslang::EShClientVulkan, 100);
|
||||||
|
shader.setEnvClient(glslang::EShClientVulkan, glslang::EShTargetVulkan_1_1);
|
||||||
|
shader.setEnvTarget(glslang::EShTargetSpv, glslang::EShTargetSpv_1_3);
|
||||||
|
if (!shader.parse(&DefaultTBuiltInResource, 100, true, EShMsgDefault)) {
|
||||||
|
fprintf(stderr, "Parse failed\n");
|
||||||
|
fprintf(stderr, "%s\n", shader.getInfoLog());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
glslang::TProgram program;
|
||||||
|
program.addShader(&shader);
|
||||||
|
if (!program.link(EShMsgDefault)) {
|
||||||
|
fprintf(stderr, "Link failed\n");
|
||||||
|
fprintf(stderr, "%s\n", program.getInfoLog());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
glslang::SpvOptions spvOptions;
|
||||||
|
spvOptions.generateDebugInfo = gen_debug;
|
||||||
|
spvOptions.optimizeSize = false;
|
||||||
|
spvOptions.disassemble = false;
|
||||||
|
spvOptions.validate = false;
|
||||||
|
|
||||||
|
std::vector<uint32_t>* output = new std::vector<uint32_t>;
|
||||||
|
glslang::GlslangToSpv(*program.getIntermediate(stage), *output, nullptr, &spvOptions);
|
||||||
|
|
||||||
|
*spirv_len = output->size();
|
||||||
|
*spirv = output->data();
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Destroys a buffer created by convert_glsl_to_spirv
|
||||||
|
*/
|
||||||
|
EMSCRIPTEN_KEEPALIVE
|
||||||
|
void destroy_output_buffer(void* p)
|
||||||
|
{
|
||||||
|
delete static_cast<std::vector<uint32_t>*>(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // extern "C"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For non-Emscripten builds we supply a generic main, so that the glslang.js
|
||||||
|
* build target can generate an executable with a trivial use case instead of
|
||||||
|
* generating a WASM binary. This is done so that there is a target that can be
|
||||||
|
* built and output analyzed using desktop tools, since WASM binaries are
|
||||||
|
* specific to the Emscripten toolchain.
|
||||||
|
*/
|
||||||
|
#ifndef __EMSCRIPTEN__
|
||||||
|
int main() {
|
||||||
|
const char* input = R"(#version 310 es
|
||||||
|
|
||||||
|
void main() { })";
|
||||||
|
|
||||||
|
uint32_t* output;
|
||||||
|
size_t output_len;
|
||||||
|
|
||||||
|
void* id = convert_glsl_to_spirv(input, 4, false, &output, &output_len);
|
||||||
|
assert(output != nullptr);
|
||||||
|
assert(output_len != 0);
|
||||||
|
destroy_output_buffer(id);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif // ifndef __EMSCRIPTEN__
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
Module['compileGLSLZeroCopy'] = function(glsl, shader_stage, gen_debug) {
|
||||||
|
gen_debug = !!gen_debug;
|
||||||
|
|
||||||
|
var shader_stage_int;
|
||||||
|
if (shader_stage === 'vertex') {
|
||||||
|
shader_stage_int = 0;
|
||||||
|
} else if (shader_stage === 'fragment') {
|
||||||
|
shader_stage_int = 4;
|
||||||
|
} else if (shader_stage === 'compute') {
|
||||||
|
shader_stage_int = 5;
|
||||||
|
} else {
|
||||||
|
throw new Error("shader_stage must be 'vertex', 'fragment', or 'compute'");
|
||||||
|
}
|
||||||
|
|
||||||
|
var p_output = Module['_malloc'](4);
|
||||||
|
var p_output_len = Module['_malloc'](4);
|
||||||
|
var id = ccall('convert_glsl_to_spirv',
|
||||||
|
'number',
|
||||||
|
['string', 'number', 'boolean', 'number', 'number'],
|
||||||
|
[glsl, shader_stage_int, gen_debug, p_output, p_output_len]);
|
||||||
|
var output = getValue(p_output, 'i32');
|
||||||
|
var output_len = getValue(p_output_len, 'i32');
|
||||||
|
Module['_free'](p_output);
|
||||||
|
Module['_free'](p_output_len);
|
||||||
|
|
||||||
|
if (id === 0) {
|
||||||
|
throw new Error('GLSL compilation failed');
|
||||||
|
}
|
||||||
|
|
||||||
|
var ret = {};
|
||||||
|
var outputIndexU32 = output / 4;
|
||||||
|
ret['data'] = Module['HEAPU32'].subarray(outputIndexU32, outputIndexU32 + output_len);
|
||||||
|
ret['free'] = function() {
|
||||||
|
Module['_destroy_output_buffer'](id);
|
||||||
|
};
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
|
Module['compileGLSL'] = function(glsl, shader_stage, gen_debug) {
|
||||||
|
var compiled = Module['compileGLSLZeroCopy'](glsl, shader_stage, gen_debug);
|
||||||
|
var ret = compiled['data'].slice()
|
||||||
|
compiled['free']();
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
@@ -68,7 +68,7 @@
|
|||||||
// This should always increase, as some paths to do not consume
|
// This should always increase, as some paths to do not consume
|
||||||
// a more major number.
|
// a more major number.
|
||||||
// It should increment by one when new functionality is added.
|
// It should increment by one when new functionality is added.
|
||||||
#define GLSLANG_MINOR_VERSION 12
|
#define GLSLANG_MINOR_VERSION 13
|
||||||
|
|
||||||
//
|
//
|
||||||
// Call before doing any other compiler/linker operations.
|
// Call before doing any other compiler/linker operations.
|
||||||
@@ -126,36 +126,37 @@ class TType;
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShSourceNone,
|
EShSourceNone,
|
||||||
EShSourceGlsl,
|
EShSourceGlsl, // GLSL, includes ESSL (OpenGL ES GLSL)
|
||||||
EShSourceHlsl,
|
EShSourceHlsl, // HLSL
|
||||||
} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead
|
} EShSource; // if EShLanguage were EShStage, this could be EShLanguage instead
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShClientNone,
|
EShClientNone, // use when there is no client, e.g. for validation
|
||||||
EShClientVulkan,
|
EShClientVulkan,
|
||||||
EShClientOpenGL,
|
EShClientOpenGL,
|
||||||
} EShClient;
|
} EShClient;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShTargetNone,
|
EShTargetNone,
|
||||||
EShTargetSpv, // preferred spelling
|
EShTargetSpv, // SPIR-V (preferred spelling)
|
||||||
EshTargetSpv = EShTargetSpv, // legacy spelling
|
EshTargetSpv = EShTargetSpv, // legacy spelling
|
||||||
} EShTargetLanguage;
|
} EShTargetLanguage;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShTargetVulkan_1_0 = (1 << 22),
|
EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0
|
||||||
EShTargetVulkan_1_1 = (1 << 22) | (1 << 12),
|
EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1
|
||||||
EShTargetOpenGL_450 = 450,
|
EShTargetOpenGL_450 = 450, // OpenGL
|
||||||
} EShTargetClientVersion;
|
} EShTargetClientVersion;
|
||||||
|
|
||||||
typedef EShTargetClientVersion EshTargetClientVersion;
|
typedef EShTargetClientVersion EshTargetClientVersion;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EShTargetSpv_1_0 = (1 << 16),
|
EShTargetSpv_1_0 = (1 << 16), // SPIR-V 1.0
|
||||||
EShTargetSpv_1_1 = (1 << 16) | (1 << 8),
|
EShTargetSpv_1_1 = (1 << 16) | (1 << 8), // SPIR-V 1.1
|
||||||
EShTargetSpv_1_2 = (1 << 16) | (2 << 8),
|
EShTargetSpv_1_2 = (1 << 16) | (2 << 8), // SPIR-V 1.2
|
||||||
EShTargetSpv_1_3 = (1 << 16) | (3 << 8),
|
EShTargetSpv_1_3 = (1 << 16) | (3 << 8), // SPIR-V 1.3
|
||||||
EShTargetSpv_1_4 = (1 << 16) | (4 << 8),
|
EShTargetSpv_1_4 = (1 << 16) | (4 << 8), // SPIR-V 1.4
|
||||||
|
EShTargetSpv_1_5 = (1 << 16) | (5 << 8), // SPIR-V 1.5
|
||||||
} EShTargetLanguageVersion;
|
} EShTargetLanguageVersion;
|
||||||
|
|
||||||
struct TInputLanguage {
|
struct TInputLanguage {
|
||||||
@@ -432,15 +433,42 @@ public:
|
|||||||
void addUniformLocationOverride(const char* name, int loc);
|
void addUniformLocationOverride(const char* name, int loc);
|
||||||
void setUniformLocationBase(int base);
|
void setUniformLocationBase(int base);
|
||||||
void setInvertY(bool invert);
|
void setInvertY(bool invert);
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
void setHlslIoMapping(bool hlslIoMap);
|
void setHlslIoMapping(bool hlslIoMap);
|
||||||
void setFlattenUniformArrays(bool flatten);
|
void setFlattenUniformArrays(bool flatten);
|
||||||
|
#endif
|
||||||
void setNoStorageFormat(bool useUnknownFormat);
|
void setNoStorageFormat(bool useUnknownFormat);
|
||||||
|
void setNanMinMaxClamp(bool nanMinMaxClamp);
|
||||||
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
|
void setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode);
|
||||||
|
|
||||||
// For setting up the environment (cleared to nothingness in the constructor).
|
// For setting up the environment (cleared to nothingness in the constructor).
|
||||||
// These must be called so that parsing is done for the right source language and
|
// These must be called so that parsing is done for the right source language and
|
||||||
// target environment, either indirectly through TranslateEnvironment() based on
|
// target environment, either indirectly through TranslateEnvironment() based on
|
||||||
// EShMessages et. al., or directly by the user.
|
// EShMessages et. al., or directly by the user.
|
||||||
|
//
|
||||||
|
// setEnvInput: The input source language and stage. If generating code for a
|
||||||
|
// specific client, the input client semantics to use and the
|
||||||
|
// version of the that client's input semantics to use, otherwise
|
||||||
|
// use EShClientNone and version of 0, e.g. for validation mode.
|
||||||
|
// Note 'version' does not describe the target environment,
|
||||||
|
// just the version of the source dialect to compile under.
|
||||||
|
//
|
||||||
|
// See the definitions of TEnvironment, EShSource, EShLanguage,
|
||||||
|
// and EShClient for choices and more detail.
|
||||||
|
//
|
||||||
|
// setEnvClient: The client that will be hosting the execution, and it's version.
|
||||||
|
// Note 'version' is not the version of the languages involved, but
|
||||||
|
// the version of the client environment.
|
||||||
|
// Use EShClientNone and version of 0 if there is no client, e.g.
|
||||||
|
// for validation mode.
|
||||||
|
//
|
||||||
|
// See EShTargetClientVersion for choices.
|
||||||
|
//
|
||||||
|
// setEnvTarget: The language to translate to when generating code, and that
|
||||||
|
// language's version.
|
||||||
|
// Use EShTargetNone and version of 0 if there is no client, e.g.
|
||||||
|
// for validation mode.
|
||||||
|
//
|
||||||
void setEnvInput(EShSource lang, EShLanguage envStage, EShClient client, int version)
|
void setEnvInput(EShSource lang, EShLanguage envStage, EShClient client, int version)
|
||||||
{
|
{
|
||||||
environment.input.languageFamily = lang;
|
environment.input.languageFamily = lang;
|
||||||
@@ -458,8 +486,15 @@ public:
|
|||||||
environment.target.language = lang;
|
environment.target.language = lang;
|
||||||
environment.target.version = version;
|
environment.target.version = version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void getStrings(const char* const* &s, int& n) { s = strings; n = numStrings; }
|
||||||
|
|
||||||
|
#ifdef ENABLE_HLSL
|
||||||
void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; }
|
void setEnvTargetHlslFunctionality1() { environment.target.hlslFunctionality1 = true; }
|
||||||
bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; }
|
bool getEnvTargetHlslFunctionality1() const { return environment.target.hlslFunctionality1; }
|
||||||
|
#else
|
||||||
|
bool getEnvTargetHlslFunctionality1() const { return false; }
|
||||||
|
#endif
|
||||||
|
|
||||||
// Interface to #include handlers.
|
// Interface to #include handlers.
|
||||||
//
|
//
|
||||||
@@ -610,6 +645,8 @@ private:
|
|||||||
TShader& operator=(TShader&);
|
TShader& operator=(TShader&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
//
|
//
|
||||||
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
|
// A reflection database and its interface, consistent with the OpenGL API reflection queries.
|
||||||
//
|
//
|
||||||
@@ -647,6 +684,7 @@ protected:
|
|||||||
|
|
||||||
class TReflection;
|
class TReflection;
|
||||||
class TIoMapper;
|
class TIoMapper;
|
||||||
|
struct TVarEntryInfo;
|
||||||
|
|
||||||
// Allows to customize the binding layout after linking.
|
// Allows to customize the binding layout after linking.
|
||||||
// All used uniform variables will invoke at least validateBinding.
|
// All used uniform variables will invoke at least validateBinding.
|
||||||
@@ -678,42 +716,54 @@ public:
|
|||||||
|
|
||||||
// Should return true if the resulting/current binding would be okay.
|
// Should return true if the resulting/current binding would be okay.
|
||||||
// Basic idea is to do aliasing binding checks with this.
|
// Basic idea is to do aliasing binding checks with this.
|
||||||
virtual bool validateBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual bool validateBinding(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return a value >= 0 if the current binding should be overridden.
|
// Should return a value >= 0 if the current binding should be overridden.
|
||||||
// Return -1 if the current binding (including no binding) should be kept.
|
// Return -1 if the current binding (including no binding) should be kept.
|
||||||
virtual int resolveBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual int resolveBinding(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return a value >= 0 if the current set should be overridden.
|
// Should return a value >= 0 if the current set should be overridden.
|
||||||
// Return -1 if the current set (including no set) should be kept.
|
// Return -1 if the current set (including no set) should be kept.
|
||||||
virtual int resolveSet(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual int resolveSet(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return a value >= 0 if the current location should be overridden.
|
// Should return a value >= 0 if the current location should be overridden.
|
||||||
// Return -1 if the current location (including no location) should be kept.
|
// Return -1 if the current location (including no location) should be kept.
|
||||||
virtual int resolveUniformLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual int resolveUniformLocation(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return true if the resulting/current setup would be okay.
|
// Should return true if the resulting/current setup would be okay.
|
||||||
// Basic idea is to do aliasing checks and reject invalid semantic names.
|
// Basic idea is to do aliasing checks and reject invalid semantic names.
|
||||||
virtual bool validateInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual bool validateInOut(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return a value >= 0 if the current location should be overridden.
|
// Should return a value >= 0 if the current location should be overridden.
|
||||||
// Return -1 if the current location (including no location) should be kept.
|
// Return -1 if the current location (including no location) should be kept.
|
||||||
virtual int resolveInOutLocation(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual int resolveInOutLocation(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return a value >= 0 if the current component index should be overridden.
|
// Should return a value >= 0 if the current component index should be overridden.
|
||||||
// Return -1 if the current component index (including no index) should be kept.
|
// Return -1 if the current component index (including no index) should be kept.
|
||||||
virtual int resolveInOutComponent(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual int resolveInOutComponent(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Should return a value >= 0 if the current color index should be overridden.
|
// Should return a value >= 0 if the current color index should be overridden.
|
||||||
// Return -1 if the current color index (including no index) should be kept.
|
// Return -1 if the current color index (including no index) should be kept.
|
||||||
virtual int resolveInOutIndex(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual int resolveInOutIndex(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Notification of a uniform variable
|
// Notification of a uniform variable
|
||||||
virtual void notifyBinding(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual void notifyBinding(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Notification of a in or out variable
|
// Notification of a in or out variable
|
||||||
virtual void notifyInOut(EShLanguage stage, const char* name, const TType& type, bool is_live) = 0;
|
virtual void notifyInOut(EShLanguage stage, TVarEntryInfo& ent) = 0;
|
||||||
// Called by mapIO when it has finished the notify pass
|
|
||||||
virtual void endNotifications(EShLanguage stage) = 0;
|
|
||||||
// Called by mapIO when it starts its notify pass for the given stage
|
// Called by mapIO when it starts its notify pass for the given stage
|
||||||
virtual void beginNotifications(EShLanguage stage) = 0;
|
virtual void beginNotifications(EShLanguage stage) = 0;
|
||||||
|
// Called by mapIO when it has finished the notify pass
|
||||||
|
virtual void endNotifications(EShLanguage stage) = 0;
|
||||||
// Called by mipIO when it starts its resolve pass for the given stage
|
// Called by mipIO when it starts its resolve pass for the given stage
|
||||||
virtual void beginResolve(EShLanguage stage) = 0;
|
virtual void beginResolve(EShLanguage stage) = 0;
|
||||||
// Called by mapIO when it has finished the resolve pass
|
// Called by mapIO when it has finished the resolve pass
|
||||||
virtual void endResolve(EShLanguage stage) = 0;
|
virtual void endResolve(EShLanguage stage) = 0;
|
||||||
|
// Called by mapIO when it starts its symbol collect for teh given stage
|
||||||
|
virtual void beginCollect(EShLanguage stage) = 0;
|
||||||
|
// Called by mapIO when it has finished the symbol collect
|
||||||
|
virtual void endCollect(EShLanguage stage) = 0;
|
||||||
|
// Called by TSlotCollector to resolve storage locations or bindings
|
||||||
|
virtual void reserverStorageSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0;
|
||||||
|
// Called by TSlotCollector to resolve resource locations or bindings
|
||||||
|
virtual void reserverResourceSlot(TVarEntryInfo& ent, TInfoSink& infoSink) = 0;
|
||||||
|
// Called by mapIO.addStage to set shader stage mask to mark a stage be added to this pipeline
|
||||||
|
virtual void addStage(EShLanguage stage) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif // GLSLANG_WEB
|
||||||
|
|
||||||
// Make one TProgram per set of shaders that will get linked together. Add all
|
// Make one TProgram per set of shaders that will get linked together. Add all
|
||||||
// the shaders that are to be linked together. After calling shader.parse()
|
// the shaders that are to be linked together. After calling shader.parse()
|
||||||
// for all shaders, call link().
|
// for all shaders, call link().
|
||||||
@@ -725,7 +775,7 @@ public:
|
|||||||
TProgram();
|
TProgram();
|
||||||
virtual ~TProgram();
|
virtual ~TProgram();
|
||||||
void addShader(TShader* shader) { stages[shader->stage].push_back(shader); }
|
void addShader(TShader* shader) { stages[shader->stage].push_back(shader); }
|
||||||
|
std::list<TShader*>& getShaders(EShLanguage stage) { return stages[stage]; }
|
||||||
// Link Validation interface
|
// Link Validation interface
|
||||||
bool link(EShMessages);
|
bool link(EShMessages);
|
||||||
const char* getInfoLog();
|
const char* getInfoLog();
|
||||||
@@ -733,14 +783,15 @@ public:
|
|||||||
|
|
||||||
TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
|
TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; }
|
||||||
|
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
|
|
||||||
// Reflection Interface
|
// Reflection Interface
|
||||||
|
|
||||||
// call first, to do liveness analysis, index mapping, etc.; returns false on failure
|
// call first, to do liveness analysis, index mapping, etc.; returns false on failure
|
||||||
bool buildReflection(int opts = EShReflectionDefault);
|
bool buildReflection(int opts = EShReflectionDefault);
|
||||||
|
|
||||||
unsigned getLocalSize(int dim) const; // return dim'th local size
|
unsigned getLocalSize(int dim) const; // return dim'th local size
|
||||||
int getReflectionIndex(const char *name) const;
|
int getReflectionIndex(const char *name) const;
|
||||||
|
int getReflectionPipeIOIndex(const char* name, const bool inOrOut) const;
|
||||||
int getNumUniformVariables() const;
|
int getNumUniformVariables() const;
|
||||||
const TObjectReflection& getUniform(int index) const;
|
const TObjectReflection& getUniform(int index) const;
|
||||||
int getNumUniformBlocks() const;
|
int getNumUniformBlocks() const;
|
||||||
@@ -770,6 +821,9 @@ public:
|
|||||||
// can be used for glGetUniformIndices()
|
// can be used for glGetUniformIndices()
|
||||||
int getUniformIndex(const char *name) const { return getReflectionIndex(name); }
|
int getUniformIndex(const char *name) const { return getReflectionIndex(name); }
|
||||||
|
|
||||||
|
int getPipeIOIndex(const char *name, const bool inOrOut) const
|
||||||
|
{ return getReflectionPipeIOIndex(name, inOrOut); }
|
||||||
|
|
||||||
// can be used for "name" part of glGetActiveUniform()
|
// can be used for "name" part of glGetActiveUniform()
|
||||||
const char *getUniformName(int index) const { return getUniform(index).name.c_str(); }
|
const char *getUniformName(int index) const { return getUniform(index).name.c_str(); }
|
||||||
|
|
||||||
@@ -819,11 +873,11 @@ public:
|
|||||||
const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); }
|
const TType *getAttributeTType(int index) const { return getPipeInput(index).getType(); }
|
||||||
|
|
||||||
void dumpReflection();
|
void dumpReflection();
|
||||||
|
|
||||||
// I/O mapping: apply base offsets and map live unbound variables
|
// I/O mapping: apply base offsets and map live unbound variables
|
||||||
// If resolver is not provided it uses the previous approach
|
// If resolver is not provided it uses the previous approach
|
||||||
// and respects auto assignment and offsets.
|
// and respects auto assignment and offsets.
|
||||||
bool mapIO(TIoMapResolver* resolver = NULL);
|
bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool linkStage(EShLanguage, EShMessages);
|
bool linkStage(EShLanguage, EShMessages);
|
||||||
@@ -833,8 +887,9 @@ protected:
|
|||||||
TIntermediate* intermediate[EShLangCount];
|
TIntermediate* intermediate[EShLangCount];
|
||||||
bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage
|
bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage
|
||||||
TInfoSink* infoSink;
|
TInfoSink* infoSink;
|
||||||
|
#ifndef GLSLANG_WEB
|
||||||
TReflection* reflection;
|
TReflection* reflection;
|
||||||
TIoMapper* ioMapper;
|
#endif
|
||||||
bool linked;
|
bool linked;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
Reference in New Issue
Block a user