From d7e0856dc62a9fe6feb1040c0878152422aa4301 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sun, 31 Dec 2023 16:06:45 -0400 Subject: [PATCH 01/29] tests: add basic graphics Buffer tests. issue #1986 --- testing/tests/graphics.lua | 91 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/testing/tests/graphics.lua b/testing/tests/graphics.lua index 34e849a1d..ff6476265 100644 --- a/testing/tests/graphics.lua +++ b/testing/tests/graphics.lua @@ -8,6 +8,97 @@ -------------------------------------------------------------------------------- +-- GraphicsBuffer (love.graphics.newBuffer) +love.test.graphics.Buffer = function(test) + local vertexformat = { + {name="VertexPosition", format="floatvec2"}, + {name="VertexTexCoord", format="floatvec2"}, + {name="VertexColor", format="unorm8vec4"}, + } + + local vertexdata = { + {0, 0, 0, 0, 1, 0, 1, 1}, + {10, 0, 1, 0, 0, 1, 1, 1}, + {10, 10, 1, 1, 0, 0, 1, 1}, + {0, 10, 0, 1, 1, 0, 0, 1}, + } + + local flatvertexdata = {} + for i, vert in ipairs(vertexdata) do + for j, v in ipairs(vert) do + table.insert(flatvertexdata, v) + end + end + + local vertexbuffer1 = love.graphics.newBuffer(vertexformat, 4, {vertex=true, debugname='testvertexbuffer'}) + local vertexbuffer2 = love.graphics.newBuffer(vertexformat, vertexdata, {vertex=true}) + + test:assertObject(vertexbuffer1) + test:assertObject(vertexbuffer2) + + test:assertEquals(4, vertexbuffer1:getElementCount(), 'check vertex count 1') + test:assertEquals(4, vertexbuffer2:getElementCount(), 'check vertex count 2') + + -- vertex buffers have their elements tightly packed. + test:assertEquals(20, vertexbuffer1:getElementStride(), 'check vertex array stride') + + test:assertEquals(20 * 4, vertexbuffer1:getSize(), 'check vertex buffer size') + + vertexbuffer1:setArrayData(vertexdata) + vertexbuffer1:setArrayData(flatvertexdata) + + vertexbuffer1:clear(8, 8) -- partial clear (the first texcoord) + + test:assertTrue(vertexbuffer1:isBufferType('vertex'), 'check is vertex buffer') + test:assertFalse(vertexbuffer1:isBufferType('index'), 'check is not index buffer') + test:assertFalse(vertexbuffer1:isBufferType('texel'), 'check is not texel buffer') + test:assertFalse(vertexbuffer1:isBufferType('shaderstorage'), 'check is not shader storage buffer') + + test:assertEquals('testvertexbuffer', vertexbuffer1:getDebugName(), 'check buffer debug name') + + local format = vertexbuffer1:getFormat() + test:assertEquals('table', type(format), 'check buffer format is table') + test:assertEquals(#vertexformat, #format, 'check buffer format length') + + for i, v in ipairs(vertexformat) do + test:assertEquals(v.name, format[i].name, string.format('check buffer format %d name', i)) + test:assertEquals(v.format, format[i].format, string.format('check buffer format %d format', i)) + test:assertEquals(0, format[i].arraylength, string.format('check buffer format %d array length', i)) + test:assertNotNil(format[i].offset) + end + + local indexbuffer = love.graphics.newBuffer('uint16', 128, {index=true}) + test:assertTrue(indexbuffer:isBufferType('index'), 'check is index buffer') +end + + +-- Shader Storage GraphicsBuffer (love.graphics.newBuffer) +-- Separated from the above test so we can skip it when they aren't supported. +love.test.graphics.ShaderStorageBuffer = function(test) + if not love.graphics.getSupported().glsl4 then + test:skipTest('GLSL 4 and shader storage buffers are not supported on this system') + return + end + + local format = { + { name="1", format="float" }, + { name="2", format="floatmat4x4" }, + { name="3", format="floatvec2" } + } + + local buffer = love.graphics.newBuffer(format, 1, {shaderstorage = true}) + + test:assertEquals(96, buffer:getElementStride(), 'check shader storage buffer element stride') + + local data = {} + for i = 1, 19 do + data[i] = 0 + end + + buffer:setArrayData(data) +end + + -- Canvas (love.graphics.newCanvas) love.test.graphics.Canvas = function(test) From 9b537ede2b18dadf30371412eeeddda0dd57fb8a Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sun, 31 Dec 2023 16:32:12 -0400 Subject: [PATCH 02/29] Fix out of bounds memory access in Buffer:setArrayData with matrices. Issue #1986 --- src/modules/graphics/wrap_Buffer.cpp | 29 +++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/modules/graphics/wrap_Buffer.cpp b/src/modules/graphics/wrap_Buffer.cpp index e020c1ae4..8f2aebce5 100644 --- a/src/modules/graphics/wrap_Buffer.cpp +++ b/src/modules/graphics/wrap_Buffer.cpp @@ -66,6 +66,17 @@ static inline size_t writeUNormData(lua_State *L, int startidx, int components, return sizeof(T) * components; } +template +static inline size_t writeDataRequired(lua_State *L, int startidx, int components, char *data) +{ + auto componentdata = (T*)data; + + for (int i = 0; i < components; i++) + componentdata[i] = (T)(luaL_checknumber(L, startidx + i)); + + return sizeof(T) * components; +} + void luax_writebufferdata(lua_State *L, int startidx, DataFormat format, char *data) { switch (format) @@ -75,17 +86,17 @@ void luax_writebufferdata(lua_State *L, int startidx, DataFormat format, char *d case DATAFORMAT_FLOAT_VEC3: writeData(L, startidx, 3, data); break; case DATAFORMAT_FLOAT_VEC4: writeData(L, startidx, 4, data); break; - case DATAFORMAT_FLOAT_MAT2X2: writeData(L, startidx, 4, data); break; - case DATAFORMAT_FLOAT_MAT2X3: writeData(L, startidx, 6, data); break; - case DATAFORMAT_FLOAT_MAT2X4: writeData(L, startidx, 8, data); break; + case DATAFORMAT_FLOAT_MAT2X2: writeDataRequired(L, startidx, 4, data); break; + case DATAFORMAT_FLOAT_MAT2X3: writeDataRequired(L, startidx, 6, data); break; + case DATAFORMAT_FLOAT_MAT2X4: writeDataRequired(L, startidx, 8, data); break; - case DATAFORMAT_FLOAT_MAT3X2: writeData(L, startidx, 6, data); break; - case DATAFORMAT_FLOAT_MAT3X3: writeData(L, startidx, 9, data); break; - case DATAFORMAT_FLOAT_MAT3X4: writeData(L, startidx, 12, data); break; + case DATAFORMAT_FLOAT_MAT3X2: writeDataRequired(L, startidx, 6, data); break; + case DATAFORMAT_FLOAT_MAT3X3: writeDataRequired(L, startidx, 9, data); break; + case DATAFORMAT_FLOAT_MAT3X4: writeDataRequired(L, startidx, 12, data); break; - case DATAFORMAT_FLOAT_MAT4X2: writeData(L, startidx, 8, data); break; - case DATAFORMAT_FLOAT_MAT4X3: writeData(L, startidx, 12, data); break; - case DATAFORMAT_FLOAT_MAT4X4: writeData(L, startidx, 16, data); break; + case DATAFORMAT_FLOAT_MAT4X2: writeDataRequired(L, startidx, 8, data); break; + case DATAFORMAT_FLOAT_MAT4X3: writeDataRequired(L, startidx, 12, data); break; + case DATAFORMAT_FLOAT_MAT4X4: writeDataRequired(L, startidx, 16, data); break; case DATAFORMAT_INT32: writeData(L, startidx, 1, data); break; case DATAFORMAT_INT32_VEC2: writeData(L, startidx, 2, data); break; From 0523aa6f8f95b27b942261d6e387ce9b8c4c2767 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Mon, 1 Jan 2024 15:41:31 -0400 Subject: [PATCH 03/29] metal: check for depth compare mode support before setting it on a texture. --- src/modules/graphics/metal/Graphics.h | 2 ++ src/modules/graphics/metal/Graphics.mm | 7 ++++++- src/modules/graphics/metal/Texture.mm | 3 +++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/modules/graphics/metal/Graphics.h b/src/modules/graphics/metal/Graphics.h index d735349ce..a949aa250 100644 --- a/src/modules/graphics/metal/Graphics.h +++ b/src/modules/graphics/metal/Graphics.h @@ -137,6 +137,8 @@ class Graphics final : public love::graphics::Graphics id getCachedSampler(const SamplerState &s); + bool isDepthCompareSamplerSupported() const; + StreamBuffer *getUniformBuffer() const { return uniformBuffer; } Buffer *getDefaultAttributesBuffer() const { return defaultAttributesBuffer; } diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index 0f960652b..a89c6d5fe 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -810,7 +810,7 @@ static bool isClampOne(SamplerState::WrapMode w) desc.lodMinClamp = s.minLod; desc.lodMaxClamp = s.maxLod; - // TODO: This isn't supported on some older iOS devices... + // This isn't supported on some older iOS devices. Texture code checks for support. if (s.depthSampleMode.hasValue) desc.compareFunction = getMTLCompareFunction(s.depthSampleMode.value); @@ -822,6 +822,11 @@ static bool isClampOne(SamplerState::WrapMode w) return sampler; }} +bool Graphics::isDepthCompareSamplerSupported() const +{ + return families.mac[1] || families.macCatalyst[1] || families.apple[3]; +} + id Graphics::getCachedDepthStencilState(const DepthState &depth, const StencilState &stencil) { uint64 key = (depth.compare << 0) | ((uint32)depth.write << 8) diff --git a/src/modules/graphics/metal/Texture.mm b/src/modules/graphics/metal/Texture.mm index d9b07f67e..ee84998e1 100644 --- a/src/modules/graphics/metal/Texture.mm +++ b/src/modules/graphics/metal/Texture.mm @@ -339,6 +339,9 @@ static MTLTextureType getMTLTextureType(TextureType type, int msaa) void Texture::setSamplerState(const SamplerState &s) { @autoreleasepool { + if (s.depthSampleMode.hasValue && !Graphics::getInstance()->isDepthCompareSamplerSupported()) + throw love::Exception("Depth comparison sampling in shaders is not supported on this system."); + // Base class does common validation and assigns samplerState. love::graphics::Texture::setSamplerState(s); From af840bb2cfe1a416725e92b4e8214534a2c9d741 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Mon, 1 Jan 2024 16:12:24 -0400 Subject: [PATCH 04/29] metal: texel buffers align their size according to device requirements --- src/modules/graphics/metal/Buffer.mm | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/modules/graphics/metal/Buffer.mm b/src/modules/graphics/metal/Buffer.mm index 20394d0aa..c3b964ff2 100644 --- a/src/modules/graphics/metal/Buffer.mm +++ b/src/modules/graphics/metal/Buffer.mm @@ -21,6 +21,8 @@ #include "Buffer.h" #include "Graphics.h" +#include "common/memory.h" + namespace love { namespace graphics @@ -65,6 +67,19 @@ static MTLPixelFormat getMTLPixelFormat(DataFormat format) size = getSize(); arraylength = getArrayLength(); + if (usageFlags & BUFFERUSAGEFLAG_TEXEL) + { + if (@available(iOS 12, macOS 10.14, *)) + { + MTLPixelFormat pixformat = getMTLPixelFormat(getDataMember(0).decl.format); + NSUInteger alignment = 1; + if (pixformat != MTLPixelFormatInvalid) + alignment = [device minimumTextureBufferAlignmentForPixelFormat:pixformat]; + + size = alignUp(size, (size_t) alignment); + } + } + MTLResourceOptions opts = 0; if (settings.dataUsage == BUFFERDATAUSAGE_READBACK) opts |= MTLResourceStorageModeShared; @@ -83,8 +98,6 @@ static MTLPixelFormat getMTLPixelFormat(DataFormat format) { if (@available(iOS 12, macOS 10.14, *)) { - // TODO: minimumTextureBufferAlignmentForPixelFormat - MTLPixelFormat pixformat = getMTLPixelFormat(getDataMember(0).decl.format); if (pixformat == MTLPixelFormatInvalid) throw love::Exception("Could not create Metal texel buffer: invalid format."); From 77c5ea1d6b3fa2abc8eaaf18b2b104dbda1cb57c Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Tue, 2 Jan 2024 11:13:31 -0400 Subject: [PATCH 05/29] graphics: move buffer:clear error checking to high level code --- src/modules/graphics/Buffer.cpp | 14 ++++++++++++++ src/modules/graphics/Buffer.h | 4 +++- src/modules/graphics/metal/Buffer.h | 3 ++- src/modules/graphics/metal/Buffer.mm | 11 +---------- src/modules/graphics/opengl/Buffer.cpp | 11 +---------- src/modules/graphics/opengl/Buffer.h | 3 ++- src/modules/graphics/vulkan/Buffer.cpp | 11 +---------- src/modules/graphics/vulkan/Buffer.h | 4 +++- 8 files changed, 27 insertions(+), 34 deletions(-) diff --git a/src/modules/graphics/Buffer.cpp b/src/modules/graphics/Buffer.cpp index c9c9828f1..9b46218f6 100644 --- a/src/modules/graphics/Buffer.cpp +++ b/src/modules/graphics/Buffer.cpp @@ -265,6 +265,20 @@ int Buffer::getDataMemberIndex(const std::string &name) const return -1; } +void Buffer::clear(size_t offset, size_t size) +{ + if (isImmutable()) + throw love::Exception("Cannot clear an immutable Buffer."); + else if (isMapped()) + throw love::Exception("Cannot clear a mapped Buffer."); + else if (offset + size > getSize()) + throw love::Exception("The given offset and size parameters to clear() are not within the Buffer's size."); + else if (offset % 4 != 0 || size % 4 != 0) + throw love::Exception("clear() must be used with offset and size parameters that are multiples of 4 bytes."); + + clearInternal(offset, size); +} + std::vector Buffer::getCommonFormatDeclaration(CommonFormat format) { switch (format) diff --git a/src/modules/graphics/Buffer.h b/src/modules/graphics/Buffer.h index 51717c7f5..6e1245502 100644 --- a/src/modules/graphics/Buffer.h +++ b/src/modules/graphics/Buffer.h @@ -141,7 +141,7 @@ class Buffer : public love::Object, public Resource /** * Reset the given portion of this buffer's data to 0. */ - virtual void clear(size_t offset, size_t size) = 0; + void clear(size_t offset, size_t size); /** * Copy a portion of this Buffer's data to another buffer, using the GPU. @@ -178,6 +178,8 @@ class Buffer : public love::Object, public Resource protected: + virtual void clearInternal(size_t offset, size_t size) = 0; + std::vector dataMembers; size_t arrayLength; size_t arrayStride; diff --git a/src/modules/graphics/metal/Buffer.h b/src/modules/graphics/metal/Buffer.h index 1bd6d46e2..9e2e4854a 100644 --- a/src/modules/graphics/metal/Buffer.h +++ b/src/modules/graphics/metal/Buffer.h @@ -41,7 +41,6 @@ class Buffer final : public love::graphics::Buffer void *map(MapType map, size_t offset, size_t size) override; void unmap(size_t usedoffset, size_t usedsize) override; bool fill(size_t offset, size_t size, const void *data) override; - void clear(size_t offset, size_t size) override; void copyTo(love::graphics::Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size) override; ptrdiff_t getHandle() const override { return (ptrdiff_t) buffer; } @@ -49,6 +48,8 @@ class Buffer final : public love::graphics::Buffer private: + void clearInternal(size_t offset, size_t size) override; + id buffer; id texture; diff --git a/src/modules/graphics/metal/Buffer.mm b/src/modules/graphics/metal/Buffer.mm index c3b964ff2..d1b85f601 100644 --- a/src/modules/graphics/metal/Buffer.mm +++ b/src/modules/graphics/metal/Buffer.mm @@ -222,17 +222,8 @@ static MTLPixelFormat getMTLPixelFormat(DataFormat format) return true; }} -void Buffer::clear(size_t offset, size_t size) +void Buffer::clearInternal(size_t offset, size_t size) { @autoreleasepool { - if (isImmutable()) - throw love::Exception("Cannot clear an immutable Buffer."); - else if (isMapped()) - throw love::Exception("Cannot clear a mapped Buffer."); - else if (offset + size > getSize()) - throw love::Exception("The given offset and size parameters to clear() are not within the Buffer's size."); - else if (offset % 4 != 0 || size % 4 != 0) - throw love::Exception("clear() must be used with offset and size parameters that are multiples of 4 bytes."); - auto gfx = Graphics::getInstance(); auto encoder = gfx->useBlitEncoder(); diff --git a/src/modules/graphics/opengl/Buffer.cpp b/src/modules/graphics/opengl/Buffer.cpp index 04a843559..8dc5b57e8 100644 --- a/src/modules/graphics/opengl/Buffer.cpp +++ b/src/modules/graphics/opengl/Buffer.cpp @@ -299,17 +299,8 @@ bool Buffer::fill(size_t offset, size_t size, const void *data) return true; } -void Buffer::clear(size_t offset, size_t size) +void Buffer::clearInternal(size_t offset, size_t size) { - if (isImmutable()) - throw love::Exception("Cannot clear an immutable Buffer."); - else if (isMapped()) - throw love::Exception("Cannot clear a mapped Buffer."); - else if (offset + size > getSize()) - throw love::Exception("The given offset and size parameters to clear() are not within the Buffer's size."); - else if (offset % 4 != 0 || size % 4 != 0) - throw love::Exception("clear() must be used with offset and size parameters that are multiples of 4 bytes."); - if (GLAD_VERSION_4_3) { gl.bindBuffer(mapUsage, buffer); diff --git a/src/modules/graphics/opengl/Buffer.h b/src/modules/graphics/opengl/Buffer.h index acee82aa7..15cacab28 100644 --- a/src/modules/graphics/opengl/Buffer.h +++ b/src/modules/graphics/opengl/Buffer.h @@ -53,7 +53,6 @@ class Buffer final : public love::graphics::Buffer, public Volatile void *map(MapType map, size_t offset, size_t size) override; void unmap(size_t usedoffset, size_t usedsize) override; bool fill(size_t offset, size_t size, const void *data) override; - void clear(size_t offset, size_t size) override; void copyTo(love::graphics::Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size) override; ptrdiff_t getHandle() const override { return buffer; }; @@ -66,6 +65,8 @@ class Buffer final : public love::graphics::Buffer, public Volatile bool load(const void *initialdata); bool supportsOrphan() const; + void clearInternal(size_t offset, size_t size) override; + BufferUsage mapUsage = BUFFERUSAGE_VERTEX; GLenum target = 0; diff --git a/src/modules/graphics/vulkan/Buffer.cpp b/src/modules/graphics/vulkan/Buffer.cpp index 48c89deac..b68ae9c1a 100644 --- a/src/modules/graphics/vulkan/Buffer.cpp +++ b/src/modules/graphics/vulkan/Buffer.cpp @@ -266,17 +266,8 @@ void Buffer::unmap(size_t usedoffset, size_t usedsize) } } -void Buffer::clear(size_t offset, size_t size) +void Buffer::clearInternal(size_t offset, size_t size) { - if (isImmutable()) - throw love::Exception("Cannot clear an immutable Buffer."); - else if (isMapped()) - throw love::Exception("Cannot clear a mapped Buffer."); - else if (offset + size > getSize()) - throw love::Exception("The given offset and size parameters to clear() are not within the Buffer's size."); - else if (offset % 4 != 0 || size % 4 != 0) - throw love::Exception("clear() must be used with offset and size parameters that are multiples of 4 bytes."); - vkCmdFillBuffer(vgfx->getCommandBufferForDataTransfer(), buffer, offset, size, 0); } diff --git a/src/modules/graphics/vulkan/Buffer.h b/src/modules/graphics/vulkan/Buffer.h index e6dd674b3..6b393b52b 100644 --- a/src/modules/graphics/vulkan/Buffer.h +++ b/src/modules/graphics/vulkan/Buffer.h @@ -51,12 +51,14 @@ class Buffer final void *map(MapType map, size_t offset, size_t size) override; void unmap(size_t usedoffset, size_t usedsize) override; bool fill(size_t offset, size_t size, const void *data) override; - void clear(size_t offset, size_t size) override; void copyTo(love::graphics::Buffer *dest, size_t sourceoffset, size_t destoffset, size_t size) override; ptrdiff_t getHandle() const override; ptrdiff_t getTexelBufferHandle() const override; private: + + void clearInternal(size_t offset, size_t size) override; + bool zeroInitialize; const void *initialData; VkBuffer buffer = VK_NULL_HANDLE; From 9b5851e039d3e396d9976d40b7ef5983e7c05bf2 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Thu, 4 Jan 2024 16:23:49 -0400 Subject: [PATCH 06/29] Move current love.graphics.setStencilMode functionality to setStencilState. Add new higher level love.graphics.setStencilMode function. - Add love.graphics.setStencilMode(mode [, value = 1]) - Add love.graphics.setStencilMode(). - Add mode, value = love.graphics.getStencilMode(). The possible modes are "off" (same as no parameters), "draw", and "test". The "draw" mode disables color writes and sets the stencil state to ("replace", "always") using the given value. The "test" mode enables color writes and sets the stencil state to ("keep", "equal") using the given value to compare to. --- changes.txt | 7 +-- src/modules/graphics/Graphics.cpp | 33 ++++++++++-- src/modules/graphics/Graphics.h | 8 ++- src/modules/graphics/metal/Graphics.h | 2 +- src/modules/graphics/metal/Graphics.mm | 4 +- src/modules/graphics/opengl/Graphics.cpp | 4 +- src/modules/graphics/opengl/Graphics.h | 2 +- src/modules/graphics/renderstate.cpp | 48 ++++++++++++++++-- src/modules/graphics/renderstate.h | 13 +++++ src/modules/graphics/vulkan/Graphics.cpp | 2 +- src/modules/graphics/vulkan/Graphics.h | 2 +- src/modules/graphics/wrap_Graphics.cpp | 45 ++++++++++++++-- src/modules/graphics/wrap_Graphics.lua | 18 +++---- ... love.test.graphics.setStencilState-1.png} | Bin testing/tests/graphics.lua | 22 ++++---- 15 files changed, 165 insertions(+), 45 deletions(-) rename testing/output/expected/{love.test.graphics.setStencilMode-1.png => love.test.graphics.setStencilState-1.png} (100%) diff --git a/changes.txt b/changes.txt index 6ac3a5921..83966c68f 100644 --- a/changes.txt +++ b/changes.txt @@ -68,7 +68,8 @@ Released: N/A * Added APIs to override the default orthographic projection: love.graphics.setOrthoProjection, setPerspectiveProjection, and resetProjection. * Added ability to set point size within a vertex shader by setting the 'love_PointSize' variable. * Added love.graphics.setBlendState, which gives lower level control over blend operations than setBlendMode. -* Added love.graphics.setStencilMode and getStencilMode. Replaces love.graphics.stencil as well as setStencilTest. +* Added high level love.graphics.setStencilMode and getStencilMode functions. Replaces love.graphics.stencil and setStencilTest. +* Added lower level love.graphics.setStencilState and getStencilState functions. * Added a variant of love.graphics.setColorMask which accepts a single boolean. * Added new 'clampone' wrap mode. * Added 'clampone', 'texelbuffer', 'indexbuffer32bit', 'mipmaprange', and 'indirectdraw' graphics feature enums. @@ -113,8 +114,8 @@ Released: N/A * Deprecated love.graphics.setNewFont (use love.graphics.newFont and love.graphics.setFont instead). * Deprecated love.graphics.newText (renamed to love.graphics.newTextBatch). * Deprecated love.graphics.getImageFormats and love.graphics.getCanvasFormats (replaced by getTextureFormats). -* Deprecated love.graphics.stencil (replaced by love.graphics.setStencilMode). -* Deprecated love.graphics.setStencilTest and love.graphics.getStencilTest (replaced by love.graphics.setStencilMode and getStencilMode). +* Deprecated love.graphics.stencil (replaced by love.graphics.setStencilMode or love.graphics.setStencilState). +* Deprecated love.graphics.setStencilTest and love.graphics.getStencilTest (replaced by love.graphics.setStencilMode or setStencilState). * Deprecated t.window.highdpi in love.conf and the highdpi flag of love.window.setMode (replaced by t.highdpi in love.conf). * Deprecated t.accelerometerjoystick in love.conf (replaced by love.sensor module). * Deprecated the variants of Mesh:attachAttribute and SpriteBatch:attachAttribute which accept a Mesh (replaced by variants which accept a Buffer). diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index b451bc301..808262e27 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -700,7 +700,7 @@ void Graphics::restoreState(const DisplayState &s) setShader(s.shader.get()); setRenderTargets(s.renderTargets); - setStencilMode(s.stencil.action, s.stencil.compare, s.stencil.value, s.stencil.readMask, s.stencil.writeMask); + setStencilState(s.stencil.action, s.stencil.compare, s.stencil.value, s.stencil.readMask, s.stencil.writeMask); setDepthMode(s.depthTest, s.depthWrite); setColorMask(s.colorMask); @@ -776,7 +776,7 @@ void Graphics::restoreStateChecked(const DisplayState &s) setRenderTargets(s.renderTargets); if (!(s.stencil == cur.stencil)) - setStencilMode(s.stencil.action, s.stencil.compare, s.stencil.value, s.stencil.readMask, s.stencil.writeMask); + setStencilState(s.stencil.action, s.stencil.compare, s.stencil.value, s.stencil.readMask, s.stencil.writeMask); if (s.depthTest != cur.depthTest || s.depthWrite != cur.depthWrite) setDepthMode(s.depthTest, s.depthWrite); @@ -1309,12 +1309,37 @@ bool Graphics::getScissor(Rect &rect) const return state.scissor; } +void Graphics::setStencilMode(StencilMode mode, int value) +{ + StencilState s = computeStencilState(mode, value); + setStencilState(s.action, s.compare, s.value, s.readMask, s.writeMask); + if (mode == STENCIL_MODE_DRAW) + setColorMask({ false, false, false, false }); + else + setColorMask({ true, true, true, true }); +} + void Graphics::setStencilMode() { - setStencilMode(STENCIL_KEEP, COMPARE_ALWAYS, 0, LOVE_UINT32_MAX, LOVE_UINT32_MAX); + StencilState s = computeStencilState(STENCIL_MODE_OFF, 0); + setStencilState(s.action, s.compare, s.value, s.readMask, s.writeMask); + setColorMask({ true, true, true, true }); +} + +StencilMode Graphics::getStencilMode(int &value) const +{ + const DisplayState& state = states.back(); + StencilMode mode = computeStencilMode(state.stencil); + value = state.stencil.value; + return mode; +} + +void Graphics::setStencilState() +{ + setStencilState(STENCIL_KEEP, COMPARE_ALWAYS, 0, LOVE_UINT32_MAX, LOVE_UINT32_MAX); } -void Graphics::getStencilMode(StencilAction &action, CompareMode &compare, int &value, uint32 &readmask, uint32 &writemask) const +void Graphics::getStencilState(StencilAction &action, CompareMode &compare, int &value, uint32 &readmask, uint32 &writemask) const { const DisplayState &state = states.back(); action = state.stencil.action; diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index e668b6925..61800a72f 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -613,9 +613,13 @@ class Graphics : public Module */ bool getScissor(Rect &rect) const; - virtual void setStencilMode(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) = 0; + void setStencilMode(StencilMode mode, int value); void setStencilMode(); - void getStencilMode(StencilAction &action, CompareMode &compare, int &value, uint32 &readmask, uint32 &writemask) const; + StencilMode getStencilMode(int &value) const; + + virtual void setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) = 0; + void setStencilState(); + void getStencilState(StencilAction &action, CompareMode &compare, int &value, uint32 &readmask, uint32 &writemask) const; virtual void setDepthMode(CompareMode compare, bool write) = 0; void setDepthMode(); diff --git a/src/modules/graphics/metal/Graphics.h b/src/modules/graphics/metal/Graphics.h index a949aa250..936be0792 100644 --- a/src/modules/graphics/metal/Graphics.h +++ b/src/modules/graphics/metal/Graphics.h @@ -96,7 +96,7 @@ class Graphics final : public love::graphics::Graphics void setScissor(const Rect &rect) override; void setScissor() override; - void setStencilMode(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) override; + void setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) override; void setDepthMode(CompareMode compare, bool write) override; diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index a89c6d5fe..daffad45e 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -846,7 +846,7 @@ static bool isClampOne(SamplerState::WrapMode w) * example, if the compare function is GREATER then the stencil test will * pass if the reference value is greater than the value in the stencil * buffer. With our API it's more intuitive to assume that - * setStencilMode(STENCIL_KEEP, COMPARE_GREATER, 4) will make it pass if the + * setStencilState(STENCIL_KEEP, COMPARE_GREATER, 4) will make it pass if the * stencil buffer has a value greater than 4. **/ stencildesc.stencilCompareFunction = getMTLCompareFunction(getReversedCompareMode(stencil.compare)); @@ -1760,7 +1760,7 @@ static inline void advanceVertexOffsets(const VertexAttributes &attributes, Buff } } -void Graphics::setStencilMode(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) +void Graphics::setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) { DisplayState &state = states.back(); diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index e2b863049..728918aa6 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -1434,7 +1434,7 @@ void Graphics::setScissor() gl.setEnableState(OpenGL::ENABLE_SCISSOR_TEST, false); } -void Graphics::setStencilMode(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) +void Graphics::setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) { DisplayState &state = states.back(); @@ -1493,7 +1493,7 @@ void Graphics::setStencilMode(StencilAction action, CompareMode compare, int val * example, if the compare function is GREATER then the stencil test will * pass if the reference value is greater than the value in the stencil * buffer. With our API it's more intuitive to assume that - * setStencilMode(STENCIL_KEEP, COMPARE_GREATER, 4) will make it pass if the + * setStencilState(STENCIL_KEEP, COMPARE_GREATER, 4) will make it pass if the * stencil buffer has a value greater than 4. **/ GLenum glcompare = OpenGL::getGLCompareMode(getReversedCompareMode(compare)); diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 2b3525b0d..ee8a940cb 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -92,7 +92,7 @@ class Graphics final : public love::graphics::Graphics void setScissor(const Rect &rect) override; void setScissor() override; - void setStencilMode(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) override; + void setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) override; void setDepthMode(CompareMode compare, bool write) override; diff --git a/src/modules/graphics/renderstate.cpp b/src/modules/graphics/renderstate.cpp index 133db2bb0..171103de0 100644 --- a/src/modules/graphics/renderstate.cpp +++ b/src/modules/graphics/renderstate.cpp @@ -28,7 +28,7 @@ namespace graphics // These are all with premultiplied alpha. computeBlendState adjusts for // alpha-multiply if needed. -static const BlendState states[BLEND_MAX_ENUM] = +static const BlendState blendStates[BLEND_MAX_ENUM] = { // BLEND_ALPHA {BLENDOP_ADD, BLENDOP_ADD, BLENDFACTOR_ONE, BLENDFACTOR_ONE, BLENDFACTOR_ONE_MINUS_SRC_ALPHA, BLENDFACTOR_ONE_MINUS_SRC_ALPHA}, @@ -63,7 +63,7 @@ static const BlendState states[BLEND_MAX_ENUM] = BlendState computeBlendState(BlendMode mode, BlendAlpha alphamode) { - BlendState s = states[mode]; + BlendState s = blendStates[mode]; // We can only do alpha-multiplication when srcRGB would have been unmodified. if (s.srcFactorRGB == BLENDFACTOR_ONE && alphamode == BLENDALPHA_MULTIPLY && mode != BLEND_NONE) @@ -87,7 +87,7 @@ BlendMode computeBlendMode(BlendState s, BlendAlpha &alphamode) for (int i = 0; i < (int) BLEND_MAX_ENUM; i++) { - if (i != (int) BLEND_CUSTOM && states[i] == s) + if (i != (int) BLEND_CUSTOM && blendStates[i] == s) { alphamode = alphamultiply ? BLENDALPHA_MULTIPLY : BLENDALPHA_PREMULTIPLIED; return (BlendMode) i; @@ -111,6 +111,39 @@ bool isAlphaMultiplyBlendSupported(BlendMode mode) } } +static const StencilState stencilStates[STENCIL_MODE_MAX_ENUM] = +{ + // STENCIL_MODE_OFF + {}, + + // STENCIL_MODE_DRAW + {COMPARE_ALWAYS, STENCIL_REPLACE}, + + // STENCIL_MODE_TEST + {COMPARE_EQUAL, STENCIL_KEEP}, + + // STENCIL_MODE_CUSTOM - N/A + {}, +}; + +StencilState computeStencilState(StencilMode mode, int value) +{ + StencilState s = stencilStates[mode]; + s.value = value; + return s; +} + +StencilMode computeStencilMode(const StencilState &s) +{ + for (int i = 0; i < (int)STENCIL_MODE_MAX_ENUM; i++) + { + if (stencilStates[i].action == s.action && stencilStates[i].compare == s.compare) + return (StencilMode) i; + } + + return STENCIL_MODE_CUSTOM; +} + CompareMode getReversedCompareMode(CompareMode mode) { switch (mode) @@ -171,6 +204,15 @@ STRINGMAP_BEGIN(BlendOperation, BLENDOP_MAX_ENUM, blendOperation) } STRINGMAP_END(BlendOperation, BLENDOP_MAX_ENUM, blendOperation) +STRINGMAP_BEGIN(StencilMode, STENCIL_MODE_MAX_ENUM, stencilMode) +{ + { "off", STENCIL_MODE_OFF }, + { "draw", STENCIL_MODE_DRAW }, + { "test", STENCIL_MODE_TEST }, + { "custom", STENCIL_MODE_CUSTOM }, +} +STRINGMAP_END(StencilMode, STENCIL_MODE_MAX_ENUM, stencilMode) + STRINGMAP_BEGIN(StencilAction, STENCIL_MAX_ENUM, stencilAction) { { "keep", STENCIL_KEEP }, diff --git a/src/modules/graphics/renderstate.h b/src/modules/graphics/renderstate.h index fb86f0489..193dc567c 100644 --- a/src/modules/graphics/renderstate.h +++ b/src/modules/graphics/renderstate.h @@ -83,6 +83,15 @@ enum BlendOperation BLENDOP_MAX_ENUM }; +enum StencilMode // High level wrappers. +{ + STENCIL_MODE_OFF, + STENCIL_MODE_DRAW, + STENCIL_MODE_TEST, + STENCIL_MODE_CUSTOM, + STENCIL_MODE_MAX_ENUM +}; + enum StencilAction { STENCIL_KEEP, @@ -194,6 +203,9 @@ BlendState computeBlendState(BlendMode mode, BlendAlpha alphamode); BlendMode computeBlendMode(BlendState s, BlendAlpha &alphamode); bool isAlphaMultiplyBlendSupported(BlendMode mode); +StencilState computeStencilState(StencilMode mode, int value); +StencilMode computeStencilMode(const StencilState &s); + /** * GPU APIs do the comparison in the opposite way of what makes sense for some * of love's APIs. For example in OpenGL if the compare function is GL_GREATER, @@ -208,6 +220,7 @@ STRINGMAP_DECLARE(BlendMode); STRINGMAP_DECLARE(BlendAlpha); STRINGMAP_DECLARE(BlendFactor); STRINGMAP_DECLARE(BlendOperation); +STRINGMAP_DECLARE(StencilMode); STRINGMAP_DECLARE(StencilAction); STRINGMAP_DECLARE(CompareMode); diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index b6886fe96..ff4b9aef2 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -1001,7 +1001,7 @@ void Graphics::setScissor() vkCmdSetScissor(commandBuffers.at(currentFrame), 0, 1, &scissor); } -void Graphics::setStencilMode(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) +void Graphics::setStencilState(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) { if (action != STENCIL_KEEP) { diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index 62a6cb075..89d1ba8b0 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -293,7 +293,7 @@ class Graphics final : public love::graphics::Graphics void setColor(Colorf c) override; void setScissor(const Rect &rect) override; void setScissor() override; - void setStencilMode(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) override; + void setStencilState(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) override; void setDepthMode(CompareMode compare, bool write) override; void setFrontFaceWinding(Winding winding) override; void setColorMask(ColorChannelMask mask) override; diff --git a/src/modules/graphics/wrap_Graphics.cpp b/src/modules/graphics/wrap_Graphics.cpp index 5bbeba3d9..3f5558ab4 100644 --- a/src/modules/graphics/wrap_Graphics.cpp +++ b/src/modules/graphics/wrap_Graphics.cpp @@ -608,7 +608,40 @@ int w_setStencilMode(lua_State *L) { if (lua_gettop(L) <= 1 && lua_isnoneornil(L, 1)) { - luax_catchexcept(L, [&](){ instance()->setStencilMode(); }); + luax_catchexcept(L, [&]() { instance()->setStencilMode(); }); + return 0; + } + + StencilMode mode = STENCIL_MODE_OFF; + const char *modestr = luaL_checkstring(L, 1); + if (!getConstant(modestr, mode)) + return luax_enumerror(L, "stencil mode", getConstants(mode), modestr); + + int value = (int) luaL_optinteger(L, 3, 1); + + luax_catchexcept(L, [&]() { instance()->setStencilMode(mode, value); }); + return 0; +} + +int w_getStencilMode(lua_State *L) +{ + int value = 0; + StencilMode mode = instance()->getStencilMode(value); + + const char *modestr; + if (!getConstant(mode, modestr)) + return luaL_error(L, "Unknown stencil mode."); + + lua_pushstring(L, modestr); + lua_pushinteger(L, value); + return 2; +} + +int w_setStencilState(lua_State *L) +{ + if (lua_gettop(L) <= 1 && lua_isnoneornil(L, 1)) + { + luax_catchexcept(L, [&](){ instance()->setStencilState(); }); return 0; } @@ -627,11 +660,11 @@ int w_setStencilMode(lua_State *L) uint32 readmask = (uint32) luaL_optnumber(L, 4, LOVE_UINT32_MAX); uint32 writemask = (uint32) luaL_optnumber(L, 5, LOVE_UINT32_MAX); - luax_catchexcept(L, [&](){ instance()->setStencilMode(action, compare, value, readmask, writemask); }); + luax_catchexcept(L, [&](){ instance()->setStencilState(action, compare, value, readmask, writemask); }); return 0; } -int w_getStencilMode(lua_State *L) +int w_getStencilState(lua_State *L) { StencilAction action = STENCIL_KEEP; CompareMode compare = COMPARE_ALWAYS; @@ -639,7 +672,7 @@ int w_getStencilMode(lua_State *L) uint32 readmask = LOVE_UINT32_MAX; uint32 writemask = LOVE_UINT32_MAX; - instance()->getStencilMode(action, compare, value, readmask, writemask); + instance()->getStencilState(action, compare, value, readmask, writemask); const char *actionstr; if (!getConstant(action, actionstr)) @@ -651,7 +684,7 @@ int w_getStencilMode(lua_State *L) lua_pushstring(L, actionstr); lua_pushstring(L, comparestr); - lua_pushnumber(L, value); + lua_pushinteger(L, value); lua_pushnumber(L, readmask); lua_pushnumber(L, writemask); return 5; @@ -3936,6 +3969,8 @@ static const luaL_Reg functions[] = { "setStencilMode", w_setStencilMode }, { "getStencilMode", w_getStencilMode }, + { "setStencilState", w_setStencilState }, + { "getStencilState", w_getStencilState }, { "points", w_points }, { "line", w_line }, diff --git a/src/modules/graphics/wrap_Graphics.lua b/src/modules/graphics/wrap_Graphics.lua index 6448f048f..3d6a3b259 100644 --- a/src/modules/graphics/wrap_Graphics.lua +++ b/src/modules/graphics/wrap_Graphics.lua @@ -53,7 +53,7 @@ function graphics.newVideo(file, settings) end function graphics.stencil(func, action, value, keepvalues) - love.markDeprecated(2, "love.graphics.stencil", "function", "replaced", "love.graphics.setStencilMode") + love.markDeprecated(2, "love.graphics.stencil", "function", "replaced", "love.graphics.setStencilMode or setStencilState") if not keepvalues then graphics.clear(false, true, false) @@ -61,15 +61,15 @@ function graphics.stencil(func, action, value, keepvalues) if value == nil then value = 1 end - local action2, mode2, value2, readmask2, writemask2 = graphics.getStencilMode() + local action2, mode2, value2, readmask2, writemask2 = graphics.getStencilState() local mr, mg, mb, ma = graphics.getColorMask() - graphics.setStencilMode(action, "always", value) + graphics.setStencilState(action, "always", value) graphics.setColorMask(false) local success, err = pcall(func) - graphics.setStencilMode(action2, mode2, value2, readmask2, writemask2) + graphics.setStencilState(action2, mode2, value2, readmask2, writemask2) graphics.setColorMask(mr, mg, mb, ma) if not success then @@ -78,19 +78,19 @@ function graphics.stencil(func, action, value, keepvalues) end function graphics.setStencilTest(mode, value) - love.markDeprecated(2, "love.graphics.setStencilTest", "function", "replaced", "love.graphics.setStencilMode") + love.markDeprecated(2, "love.graphics.setStencilTest", "function", "replaced", "love.graphics.setStencilMode or setStencilState") if mode ~= nil then - graphics.setStencilMode("keep", mode, value) + graphics.setStencilState("keep", mode, value) else - graphics.setStencilMode() + graphics.setStencilState() end end function graphics.getStencilTest() - love.markDeprecated(2, "love.graphics.getStencilTest", "function", "replaced", "love.graphics.getStencilMode") + love.markDeprecated(2, "love.graphics.getStencilTest", "function", "replaced", "love.graphics.getStencilMode or getStencilState") - local action, mode, value = graphics.getStencilMode() + local action, mode, value = graphics.getStencilState() return mode, value end diff --git a/testing/output/expected/love.test.graphics.setStencilMode-1.png b/testing/output/expected/love.test.graphics.setStencilState-1.png similarity index 100% rename from testing/output/expected/love.test.graphics.setStencilMode-1.png rename to testing/output/expected/love.test.graphics.setStencilState-1.png diff --git a/testing/tests/graphics.lua b/testing/tests/graphics.lua index ff6476265..ec20edb01 100644 --- a/testing/tests/graphics.lua +++ b/testing/tests/graphics.lua @@ -1929,20 +1929,20 @@ love.test.graphics.getStackDepth = function(test) end --- love.graphics.getStencilMode -love.test.graphics.getStencilMode = function(test) +-- love.graphics.getStencilState +love.test.graphics.getStencilState = function(test) -- check default vals - local action, comparemode, value = love.graphics.getStencilMode( ) + local action, comparemode, value = love.graphics.getStencilState( ) test:assertEquals('keep', action, 'check default stencil action') test:assertEquals('always', comparemode, 'check default stencil compare') test:assertEquals(0, value, 'check default stencil value') -- check set stencil values is returned - love.graphics.setStencilMode('replace', 'less', 255) - local action, comparemode, value = love.graphics.getStencilMode() + love.graphics.setStencilState('replace', 'less', 255) + local action, comparemode, value = love.graphics.getStencilState() test:assertEquals('replace', action, 'check changed stencil action') test:assertEquals('less', comparemode, 'check changed stencil compare') test:assertEquals(255, value, 'check changed stencil value') - love.graphics.setStencilMode() -- reset + love.graphics.setStencilState() -- reset end @@ -2387,18 +2387,18 @@ love.test.graphics.setShader = function(test) end --- love.graphics.setStencilMode -love.test.graphics.setStencilMode = function(test) +-- love.graphics.setStencilState +love.test.graphics.setStencilState = function(test) local canvas = love.graphics.newCanvas(16, 16) love.graphics.setCanvas({canvas, stencil=true}) love.graphics.clear(0, 0, 0, 1) - love.graphics.setStencilMode('replace', 'always', 1) + love.graphics.setStencilState('replace', 'always', 1) love.graphics.circle('fill', 8, 8, 6) - love.graphics.setStencilMode('keep', 'greater', 0) + love.graphics.setStencilState('keep', 'greater', 0) love.graphics.setColor(1, 0, 0, 1) love.graphics.rectangle('fill', 0, 0, 16, 16) love.graphics.setColor(1, 1, 1, 1) - love.graphics.setStencilMode() + love.graphics.setStencilState() love.graphics.setCanvas() local imgdata = love.graphics.readbackTexture(canvas) test:assertPixels(imgdata, { From 404b2f2c4e5de8e72bac246c65a2c46fedd9ae8d Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Thu, 4 Jan 2024 21:35:18 -0400 Subject: [PATCH 07/29] address VS compiler suggestion about constexpr --- src/modules/graphics/wrap_Buffer.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/modules/graphics/wrap_Buffer.cpp b/src/modules/graphics/wrap_Buffer.cpp index 8f2aebce5..9917358f8 100644 --- a/src/modules/graphics/wrap_Buffer.cpp +++ b/src/modules/graphics/wrap_Buffer.cpp @@ -46,7 +46,7 @@ template static inline size_t writeSNormData(lua_State *L, int startidx, int components, char *data) { auto componentdata = (T *) data; - const auto maxval = std::numeric_limits::max(); + constexpr auto maxval = std::numeric_limits::max(); for (int i = 0; i < components; i++) componentdata[i] = (T) (luax_optnumberclamped(L, startidx + i, -1.0, 1.0, defaultComponents[i]) * maxval); @@ -58,7 +58,7 @@ template static inline size_t writeUNormData(lua_State *L, int startidx, int components, char *data) { auto componentdata = (T *) data; - const auto maxval = std::numeric_limits::max(); + constexpr auto maxval = std::numeric_limits::max(); for (int i = 0; i < components; i++) componentdata[i] = (T) (luax_optnumberclamped01(L, startidx + i, 1.0) * maxval); @@ -145,7 +145,7 @@ template static inline size_t readSNormData(lua_State *L, int components, const char *data) { const auto componentdata = (const T *) data; - const auto maxval = std::numeric_limits::max(); + constexpr auto maxval = std::numeric_limits::max(); for (int i = 0; i < components; i++) lua_pushnumber(L, std::max(-1.0, (lua_Number) componentdata[i] / (lua_Number)maxval)); @@ -157,7 +157,7 @@ template static inline size_t readUNormData(lua_State *L, int components, const char *data) { const auto componentdata = (const T *) data; - const auto maxval = std::numeric_limits::max(); + constexpr auto maxval = std::numeric_limits::max(); for (int i = 0; i < components; i++) lua_pushnumber(L, (lua_Number) componentdata[i] / (lua_Number)maxval); From 04462ece30f43db5d451d0c0a0d5293df1c97f56 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Thu, 4 Jan 2024 21:35:52 -0400 Subject: [PATCH 08/29] graphics: clean up some stencil code --- src/modules/graphics/Graphics.cpp | 21 +++++-------- src/modules/graphics/Graphics.h | 4 +-- src/modules/graphics/metal/Graphics.h | 2 +- src/modules/graphics/metal/Graphics.mm | 10 ++---- src/modules/graphics/opengl/Graphics.cpp | 22 ++++++------- src/modules/graphics/opengl/Graphics.h | 2 +- src/modules/graphics/vulkan/Graphics.cpp | 22 ++++++------- src/modules/graphics/vulkan/Graphics.h | 2 +- src/modules/graphics/wrap_Graphics.cpp | 39 ++++++++++-------------- 9 files changed, 50 insertions(+), 74 deletions(-) diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 808262e27..eeaeeff88 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -700,7 +700,7 @@ void Graphics::restoreState(const DisplayState &s) setShader(s.shader.get()); setRenderTargets(s.renderTargets); - setStencilState(s.stencil.action, s.stencil.compare, s.stencil.value, s.stencil.readMask, s.stencil.writeMask); + setStencilState(s.stencil); setDepthMode(s.depthTest, s.depthWrite); setColorMask(s.colorMask); @@ -776,7 +776,7 @@ void Graphics::restoreStateChecked(const DisplayState &s) setRenderTargets(s.renderTargets); if (!(s.stencil == cur.stencil)) - setStencilState(s.stencil.action, s.stencil.compare, s.stencil.value, s.stencil.readMask, s.stencil.writeMask); + setStencilState(s.stencil); if (s.depthTest != cur.depthTest || s.depthWrite != cur.depthWrite) setDepthMode(s.depthTest, s.depthWrite); @@ -1311,8 +1311,7 @@ bool Graphics::getScissor(Rect &rect) const void Graphics::setStencilMode(StencilMode mode, int value) { - StencilState s = computeStencilState(mode, value); - setStencilState(s.action, s.compare, s.value, s.readMask, s.writeMask); + setStencilState(computeStencilState(mode, value)); if (mode == STENCIL_MODE_DRAW) setColorMask({ false, false, false, false }); else @@ -1321,8 +1320,7 @@ void Graphics::setStencilMode(StencilMode mode, int value) void Graphics::setStencilMode() { - StencilState s = computeStencilState(STENCIL_MODE_OFF, 0); - setStencilState(s.action, s.compare, s.value, s.readMask, s.writeMask); + setStencilState(computeStencilState(STENCIL_MODE_OFF, 0)); setColorMask({ true, true, true, true }); } @@ -1336,17 +1334,14 @@ StencilMode Graphics::getStencilMode(int &value) const void Graphics::setStencilState() { - setStencilState(STENCIL_KEEP, COMPARE_ALWAYS, 0, LOVE_UINT32_MAX, LOVE_UINT32_MAX); + StencilState s; + setStencilState(s); } -void Graphics::getStencilState(StencilAction &action, CompareMode &compare, int &value, uint32 &readmask, uint32 &writemask) const +const StencilState &Graphics::getStencilState() const { const DisplayState &state = states.back(); - action = state.stencil.action; - compare = state.stencil.compare; - value = state.stencil.value; - readmask = state.stencil.readMask; - writemask = state.stencil.writeMask; + return state.stencil; } void Graphics::setDepthMode() diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 61800a72f..38dec2568 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -617,9 +617,9 @@ class Graphics : public Module void setStencilMode(); StencilMode getStencilMode(int &value) const; - virtual void setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) = 0; + virtual void setStencilState(const StencilState &state) = 0; void setStencilState(); - void getStencilState(StencilAction &action, CompareMode &compare, int &value, uint32 &readmask, uint32 &writemask) const; + const StencilState &getStencilState() const; virtual void setDepthMode(CompareMode compare, bool write) = 0; void setDepthMode(); diff --git a/src/modules/graphics/metal/Graphics.h b/src/modules/graphics/metal/Graphics.h index 936be0792..1d910eb5e 100644 --- a/src/modules/graphics/metal/Graphics.h +++ b/src/modules/graphics/metal/Graphics.h @@ -96,7 +96,7 @@ class Graphics final : public love::graphics::Graphics void setScissor(const Rect &rect) override; void setScissor() override; - void setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) override; + void setStencilState(const StencilState &s) override; void setDepthMode(CompareMode compare, bool write) override; diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index daffad45e..2cf4e91f4 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -1760,11 +1760,11 @@ static inline void advanceVertexOffsets(const VertexAttributes &attributes, Buff } } -void Graphics::setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) +void Graphics::setStencilState(const StencilState &s) { DisplayState &state = states.back(); - if (action != STENCIL_KEEP) + if (s.action != STENCIL_KEEP) { const auto &rts = state.renderTargets; love::graphics::Texture *dstexture = rts.depthStencil.texture.get(); @@ -1777,11 +1777,7 @@ static inline void advanceVertexOffsets(const VertexAttributes &attributes, Buff flushBatchedDraws(); - state.stencil.action = action; - state.stencil.compare = compare; - state.stencil.value = value; - state.stencil.readMask = readmask; - state.stencil.writeMask = writemask; + state.stencil = s; dirtyRenderState |= STATEBIT_STENCIL; } diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index 728918aa6..b56ed1cee 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -1434,11 +1434,11 @@ void Graphics::setScissor() gl.setEnableState(OpenGL::ENABLE_SCISSOR_TEST, false); } -void Graphics::setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) +void Graphics::setStencilState(const StencilState &s) { DisplayState &state = states.back(); - if (action != STENCIL_KEEP) + if (s.action != STENCIL_KEEP) { const auto &rts = state.renderTargets; love::graphics::Texture *dstexture = rts.depthStencil.texture.get(); @@ -1451,13 +1451,13 @@ void Graphics::setStencilState(StencilAction action, CompareMode compare, int va flushBatchedDraws(); - bool enablestencil = action != STENCIL_KEEP || compare != COMPARE_ALWAYS; + bool enablestencil = s.action != STENCIL_KEEP || s.compare != COMPARE_ALWAYS; if (enablestencil != gl.isStateEnabled(OpenGL::ENABLE_STENCIL_TEST)) gl.setEnableState(OpenGL::ENABLE_STENCIL_TEST, enablestencil); GLenum glaction = GL_KEEP; - switch (action) + switch (s.action) { case STENCIL_KEEP: glaction = GL_KEEP; @@ -1496,22 +1496,18 @@ void Graphics::setStencilState(StencilAction action, CompareMode compare, int va * setStencilState(STENCIL_KEEP, COMPARE_GREATER, 4) will make it pass if the * stencil buffer has a value greater than 4. **/ - GLenum glcompare = OpenGL::getGLCompareMode(getReversedCompareMode(compare)); + GLenum glcompare = OpenGL::getGLCompareMode(getReversedCompareMode(s.compare)); if (enablestencil) { - glStencilFunc(glcompare, value, readmask); + glStencilFunc(glcompare, s.value, s.readMask); glStencilOp(GL_KEEP, GL_KEEP, glaction); } - if (writemask != gl.getStencilWriteMask()) - gl.setStencilWriteMask(writemask); + if (s.writeMask != gl.getStencilWriteMask()) + gl.setStencilWriteMask(s.writeMask); - state.stencil.action = action; - state.stencil.compare = compare; - state.stencil.value = value; - state.stencil.readMask = readmask; - state.stencil.writeMask = writemask; + state.stencil = s; } void Graphics::setDepthMode(CompareMode compare, bool write) diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index ee8a940cb..894b52e21 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -92,7 +92,7 @@ class Graphics final : public love::graphics::Graphics void setScissor(const Rect &rect) override; void setScissor() override; - void setStencilState(StencilAction action, CompareMode compare, int value, uint32 readmask, uint32 writemask) override; + void setStencilState(const StencilState &s) override; void setDepthMode(CompareMode compare, bool write) override; diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index ff4b9aef2..399e9b4e8 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -1001,9 +1001,9 @@ void Graphics::setScissor() vkCmdSetScissor(commandBuffers.at(currentFrame), 0, 1, &scissor); } -void Graphics::setStencilState(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) +void Graphics::setStencilState(const StencilState &s) { - if (action != STENCIL_KEEP) + if (s.action != STENCIL_KEEP) { const auto& rts = states.back().renderTargets; auto dsTexture = rts.depthStencil.texture.get(); @@ -1016,23 +1016,19 @@ void Graphics::setStencilState(StencilAction action, CompareMode compare, int va flushBatchedDraws(); - vkCmdSetStencilWriteMask(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, writemask); + vkCmdSetStencilWriteMask(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, s.writeMask); - vkCmdSetStencilCompareMask(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, readmask); - vkCmdSetStencilReference(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, value); + vkCmdSetStencilCompareMask(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, s.readMask); + vkCmdSetStencilReference(commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, s.value); if (optionalDeviceExtensions.extendedDynamicState) vkCmdSetStencilOpEXT( commandBuffers.at(currentFrame), VK_STENCIL_FRONT_AND_BACK, - VK_STENCIL_OP_KEEP, Vulkan::getStencilOp(action), - VK_STENCIL_OP_KEEP, Vulkan::getCompareOp(getReversedCompareMode(compare))); - - states.back().stencil.action = action; - states.back().stencil.compare = compare; - states.back().stencil.value = value; - states.back().stencil.readMask = readmask; - states.back().stencil.writeMask = writemask; + VK_STENCIL_OP_KEEP, Vulkan::getStencilOp(s.action), + VK_STENCIL_OP_KEEP, Vulkan::getCompareOp(getReversedCompareMode(s.compare))); + + states.back().stencil = s; } void Graphics::setDepthMode(CompareMode compare, bool write) diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index 89d1ba8b0..a7c9f9ffd 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -293,7 +293,7 @@ class Graphics final : public love::graphics::Graphics void setColor(Colorf c) override; void setScissor(const Rect &rect) override; void setScissor() override; - void setStencilState(StencilAction action, CompareMode compare, int value, love::uint32 readmask, love::uint32 writemask) override; + void setStencilState(const StencilState &s) override; void setDepthMode(CompareMode compare, bool write) override; void setFrontFaceWinding(Winding winding) override; void setColorMask(ColorChannelMask mask) override; diff --git a/src/modules/graphics/wrap_Graphics.cpp b/src/modules/graphics/wrap_Graphics.cpp index 3f5558ab4..6ff392c71 100644 --- a/src/modules/graphics/wrap_Graphics.cpp +++ b/src/modules/graphics/wrap_Graphics.cpp @@ -645,48 +645,41 @@ int w_setStencilState(lua_State *L) return 0; } - StencilAction action = STENCIL_KEEP; + StencilState s; + const char *actionstr = luaL_checkstring(L, 1); - if (!getConstant(actionstr, action)) - return luax_enumerror(L, "stencil draw action", getConstants(action), actionstr); + if (!getConstant(actionstr, s.action)) + return luax_enumerror(L, "stencil draw action", getConstants(s.action), actionstr); - CompareMode compare = COMPARE_ALWAYS; const char *comparestr = luaL_checkstring(L, 2); - if (!getConstant(comparestr, compare)) - return luax_enumerror(L, "compare mode", getConstants(compare), comparestr); - - int value = (int) luaL_optinteger(L, 3, 0); + if (!getConstant(comparestr, s.compare)) + return luax_enumerror(L, "compare mode", getConstants(s.compare), comparestr); - uint32 readmask = (uint32) luaL_optnumber(L, 4, LOVE_UINT32_MAX); - uint32 writemask = (uint32) luaL_optnumber(L, 5, LOVE_UINT32_MAX); + s.value = (int) luaL_optinteger(L, 3, 0); + s.readMask = (uint32) luaL_optnumber(L, 4, LOVE_UINT32_MAX); + s.writeMask = (uint32) luaL_optnumber(L, 5, LOVE_UINT32_MAX); - luax_catchexcept(L, [&](){ instance()->setStencilState(action, compare, value, readmask, writemask); }); + luax_catchexcept(L, [&](){ instance()->setStencilState(s); }); return 0; } int w_getStencilState(lua_State *L) { - StencilAction action = STENCIL_KEEP; - CompareMode compare = COMPARE_ALWAYS; - int value = 1; - uint32 readmask = LOVE_UINT32_MAX; - uint32 writemask = LOVE_UINT32_MAX; - - instance()->getStencilState(action, compare, value, readmask, writemask); + const StencilState &s = instance()->getStencilState(); const char *actionstr; - if (!getConstant(action, actionstr)) + if (!getConstant(s.action, actionstr)) return luaL_error(L, "Unknown stencil draw action."); const char *comparestr; - if (!getConstant(compare, comparestr)) + if (!getConstant(s.compare, comparestr)) return luaL_error(L, "Unknown compare mode."); lua_pushstring(L, actionstr); lua_pushstring(L, comparestr); - lua_pushinteger(L, value); - lua_pushnumber(L, readmask); - lua_pushnumber(L, writemask); + lua_pushinteger(L, s.value); + lua_pushnumber(L, s.readMask); + lua_pushnumber(L, s.writeMask); return 5; } From 621a7547d2fc49677b1ace5c23fcf735f53d6576 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Fri, 5 Jan 2024 20:37:49 -0400 Subject: [PATCH 09/29] metal: tweak initial internal uniform buffer size --- src/modules/graphics/metal/Graphics.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index 2cf4e91f4..605172584 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -327,7 +327,7 @@ static inline void setSampler(id encoder, Graphics::Re initCapabilities(); - uniformBuffer = CreateStreamBuffer(device, BUFFERUSAGE_VERTEX, 1024 * 1024 * 1); + uniformBuffer = CreateStreamBuffer(device, BUFFERUSAGE_UNIFORM, 1024 * 512 * 1); { std::vector dataformat = { From aaab9791d57351476bb2114042fa4cebe99a4ae9 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sat, 6 Jan 2024 15:21:06 -0400 Subject: [PATCH 10/29] Improve backbuffer depth buffer. - Setting the depth buffer for the backbuffer is now done as a boolean instead of a bit depth integer, in love.conf or love.window.setMode. - Error if depth writes are enabled when the active canvas setup or backbuffer does not have a depth buffer (now it matches stencil behaviour). - Don't allocate a backbuffer depth-stencil buffer if they're not requested. Metal also determines the format for that buffer based on which combination of depth and stencil is requested. OpenGL still has to allocate the depth-stencil buffer for the backbuffer all the time, because changing it requires the context to be recreated. --- src/modules/graphics/Graphics.cpp | 35 ++++++++++ src/modules/graphics/Graphics.h | 15 +++-- src/modules/graphics/metal/Graphics.h | 5 +- src/modules/graphics/metal/Graphics.mm | 81 ++++++++++++++---------- src/modules/graphics/opengl/Graphics.cpp | 60 +++++++++--------- src/modules/graphics/opengl/Graphics.h | 4 +- src/modules/graphics/vulkan/Graphics.cpp | 62 ++++++++++-------- src/modules/graphics/vulkan/Graphics.h | 5 +- src/modules/window/Window.h | 2 +- src/modules/window/sdl/Window.cpp | 11 ++-- src/modules/window/wrap_Window.cpp | 13 +++- 11 files changed, 183 insertions(+), 110 deletions(-) diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index eeaeeff88..0797e4feb 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -185,6 +185,8 @@ Graphics::Graphics() , height(0) , pixelWidth(0) , pixelHeight(0) + , backbufferHasStencil(false) + , backbufferHasDepth(false) , created(false) , active(true) , batchedDrawState() @@ -617,6 +619,34 @@ Texture *Graphics::getTextureOrDefaultForActiveShader(Texture *tex) return getDefaultTexture(TEXTURE_2D, DATA_BASETYPE_FLOAT); } +void Graphics::validateStencilState(const StencilState &s) const +{ + if (s.action != STENCIL_KEEP) + { + const auto &rts = states.back().renderTargets; + love::graphics::Texture *dstexture = rts.depthStencil.texture.get(); + + if (!isRenderTargetActive() && !backbufferHasStencil) + throw love::Exception("The window must have stenciling enabled to draw to the main screen's stencil buffer."); + else if (isRenderTargetActive() && (rts.temporaryRTFlags & TEMPORARY_RT_STENCIL) == 0 && (dstexture == nullptr || !isPixelFormatStencil(dstexture->getPixelFormat()))) + throw love::Exception("Drawing to the stencil buffer with a Canvas active requires either stencil=true or a custom stencil-type Canvas to be used, in setCanvas."); + } +} + +void Graphics::validateDepthState(bool depthwrite) const +{ + if (depthwrite) + { + const auto &rts = states.back().renderTargets; + love::graphics::Texture *dstexture = rts.depthStencil.texture.get(); + + if (!isRenderTargetActive() && !backbufferHasDepth) + throw love::Exception("The window must have depth enabled to draw to the main screen's depth buffer."); + else if (isRenderTargetActive() && (rts.temporaryRTFlags & TEMPORARY_RT_DEPTH) == 0 && (dstexture == nullptr || !isPixelFormatDepth(dstexture->getPixelFormat()))) + throw love::Exception("Drawing to the depth buffer with a Canvas active requires either depth=true or a custom depth-type Canvas to be used, in setCanvas."); + } +} + int Graphics::getWidth() const { return width; @@ -671,6 +701,11 @@ void Graphics::reset() origin(); } +void Graphics::backbufferChanged(int width, int height, int pixelwidth, int pixelheight) +{ + backbufferChanged(width, height, pixelwidth, pixelheight, backbufferHasStencil, backbufferHasDepth, getRequestedBackbufferMSAA()); +} + /** * State functions. **/ diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 38dec2568..030d9d7f1 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -506,16 +506,15 @@ class Graphics : public Module virtual void present(void *screenshotCallbackData) = 0; /** - * Sets the current graphics display viewport dimensions. + * Called when the backbuffer changes. **/ - virtual void setViewportSize(int width, int height, int pixelwidth, int pixelheight) = 0; + virtual void backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) = 0; + void backbufferChanged(int width, int height, int pixelwidth, int pixelheight); /** * Sets the current graphics display viewport and initializes the renderer. - * @param width The viewport width. - * @param height The viewport height. **/ - virtual bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) = 0; + virtual bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) = 0; /** * Un-sets the current graphics display mode (uninitializing objects if @@ -1048,6 +1047,9 @@ class Graphics : public Module void releaseDefaultResources(); + void validateStencilState(const StencilState &s) const; + void validateDepthState(bool depthwrite) const; + void restoreState(const DisplayState &s); void restoreStateChecked(const DisplayState &s); @@ -1063,6 +1065,9 @@ class Graphics : public Module int pixelWidth; int pixelHeight; + bool backbufferHasStencil; + bool backbufferHasDepth; + bool created; bool active; diff --git a/src/modules/graphics/metal/Graphics.h b/src/modules/graphics/metal/Graphics.h index 1d910eb5e..d0477881c 100644 --- a/src/modules/graphics/metal/Graphics.h +++ b/src/modules/graphics/metal/Graphics.h @@ -68,8 +68,8 @@ class Graphics final : public love::graphics::Graphics Matrix4 computeDeviceProjection(const Matrix4 &projection, bool rendertotexture) const override; - void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override; - bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override; + void backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override; + bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override; void unSetMode() override; void setActive(bool active) override; @@ -231,7 +231,6 @@ class Graphics final : public love::graphics::Graphics uint32 dirtyRenderState; CullMode lastCullMode; Shader::RenderPipelineKey lastRenderPipelineKey; - bool windowHasStencil; int shaderSwitches; StrongRef backbufferMSAA; diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index 605172584..98dfd1c24 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -274,7 +274,6 @@ static inline void setSampler(id encoder, Graphics::Re , dirtyRenderState(STATEBIT_ALL) , lastCullMode(CULL_MAX_ENUM) , lastRenderPipelineKey() - , windowHasStencil(false) , shaderSwitches(0) , requestedBackbufferMSAA(0) , attachmentStoreActions() @@ -464,13 +463,23 @@ static inline void setSampler(id encoder, Graphics::Re return calculateDeviceProjection(projection, flags); } -void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight) +void Graphics::backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) { + bool sizechanged = width != this->width || height != this->height + || pixelwidth != this->pixelWidth || pixelheight != this->pixelHeight; + + bool dschanged = backbufferstencil != this->backbufferHasStencil || backbufferdepth != this->backbufferHasDepth; + bool msaachanged = msaa != this->requestedBackbufferMSAA; + this->width = width; this->height = height; this->pixelWidth = pixelwidth; this->pixelHeight = pixelheight; + this->backbufferHasStencil = backbufferstencil; + this->backbufferHasDepth = backbufferdepth; + this->requestedBackbufferMSAA = msaa; + if (!isRenderTargetActive()) { dirtyRenderState |= STATEBIT_VIEWPORT | STATEBIT_SCISSOR; @@ -485,26 +494,38 @@ static inline void setSampler(id encoder, Graphics::Re settings.renderTarget = true; settings.readable.set(false); - backbufferMSAA.set(nullptr); - if (settings.msaa > 1) + if (sizechanged || msaachanged) { - settings.format = isGammaCorrect() ? PIXELFORMAT_BGRA8_sRGB : PIXELFORMAT_BGRA8_UNORM; - backbufferMSAA.set(newTexture(settings), Acquire::NORETAIN); + backbufferMSAA.set(nullptr); + if (settings.msaa > 1) + { + settings.format = isGammaCorrect() ? PIXELFORMAT_BGRA8_sRGB : PIXELFORMAT_BGRA8_UNORM; + backbufferMSAA.set(newTexture(settings), Acquire::NORETAIN); + } } - settings.format = PIXELFORMAT_DEPTH24_UNORM_STENCIL8; - backbufferDepthStencil.set(newTexture(settings), Acquire::NORETAIN); + if (sizechanged || msaachanged || dschanged) + { + backbufferDepthStencil.set(nullptr); + if (backbufferstencil || backbufferdepth) + { + if (backbufferstencil && backbufferdepth) + settings.format = PIXELFORMAT_DEPTH24_UNORM_STENCIL8; + else if (backbufferstencil) + settings.format = PIXELFORMAT_STENCIL8; + else if (backbufferdepth) + settings.format = PIXELFORMAT_DEPTH24_UNORM; + backbufferDepthStencil.set(newTexture(settings), Acquire::NORETAIN); + } + } } -bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) +bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) { @autoreleasepool { this->width = width; this->height = height; this->metalLayer = (__bridge CAMetalLayer *) context; - this->windowHasStencil = windowhasstencil; - this->requestedBackbufferMSAA = msaa; - metalLayer.device = device; metalLayer.pixelFormat = isGammaCorrect() ? MTLPixelFormatBGRA8Unorm_sRGB : MTLPixelFormatBGRA8Unorm; @@ -516,7 +537,7 @@ static inline void setSampler(id encoder, Graphics::Re metalLayer.magnificationFilter = kCAFilterNearest; #endif - setViewportSize(width, height, pixelwidth, pixelheight); + backbufferChanged(width, height, pixelwidth, pixelheight, backbufferstencil, backbufferdepth, msaa); created = true; @@ -660,8 +681,10 @@ static inline void setAttachment(const Graphics::RenderTarget &rt, MTLRenderPass passDesc.colorAttachments[0].depthPlane = 0; RenderTarget rt(backbufferDepthStencil); - setAttachment(rt, passDesc.depthAttachment, attachmentStoreActions.depth, false); - setAttachment(rt, passDesc.stencilAttachment, attachmentStoreActions.stencil, false); + if (rt.texture != nullptr && isPixelFormatDepth(rt.texture->getPixelFormat())) + setAttachment(rt, passDesc.depthAttachment, attachmentStoreActions.depth, false); + if (rt.texture != nullptr && isPixelFormatStencil(rt.texture->getPixelFormat())) + setAttachment(rt, passDesc.stencilAttachment, attachmentStoreActions.stencil, false); attachmentStoreActions.depth = MTLStoreActionDontCare; attachmentStoreActions.stencil = MTLStoreActionDontCare; @@ -700,11 +723,15 @@ static inline void setAttachment(const Graphics::RenderTarget &rt, MTLRenderPass for (size_t i = 0; i < rts.colors.size(); i++) [renderEncoder setColorStoreAction:(store ? MTLStoreActionStore : actions.color[i]) atIndex:i]; - if (rts.depthStencil.texture.get() || rts.temporaryRTFlags != 0 || isbackbuffer) - { + love::graphics::Texture *ds = rts.depthStencil.texture.get(); + if (isbackbuffer) + ds = backbufferDepthStencil; + + if ((rts.temporaryRTFlags & TEMPORARY_RT_DEPTH) != 0 || (ds != nullptr && isPixelFormatDepth(ds->getPixelFormat()))) [renderEncoder setDepthStoreAction:store ? MTLStoreActionStore : actions.depth]; + + if ((rts.temporaryRTFlags & TEMPORARY_RT_STENCIL) != 0 || (ds != nullptr && isPixelFormatStencil(ds->getPixelFormat()))) [renderEncoder setStencilStoreAction:store ? MTLStoreActionStore : actions.stencil]; - } [renderEncoder endEncoding]; renderEncoder = nil; @@ -1762,28 +1789,18 @@ static inline void advanceVertexOffsets(const VertexAttributes &attributes, Buff void Graphics::setStencilState(const StencilState &s) { - DisplayState &state = states.back(); - - if (s.action != STENCIL_KEEP) - { - const auto &rts = state.renderTargets; - love::graphics::Texture *dstexture = rts.depthStencil.texture.get(); - - if (!isRenderTargetActive() && !windowHasStencil) - throw love::Exception("The window must have stenciling enabled to draw to the main screen's stencil buffer."); - else if (isRenderTargetActive() && (rts.temporaryRTFlags & TEMPORARY_RT_STENCIL) == 0 && (dstexture == nullptr || !isPixelFormatStencil(dstexture->getPixelFormat()))) - throw love::Exception("Drawing to the stencil buffer with a Canvas active requires either stencil=true or a custom stencil-type Canvas to be used, in setCanvas."); - } + validateStencilState(s); flushBatchedDraws(); - state.stencil = s; - + states.back().stencil = s; dirtyRenderState |= STATEBIT_STENCIL; } void Graphics::setDepthMode(CompareMode compare, bool write) { + validateDepthState(write); + DisplayState &state = states.back(); if (state.depthTest != compare || state.depthWrite != write) diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index b56ed1cee..f6ff52205 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -200,13 +200,23 @@ Matrix4 Graphics::computeDeviceProjection(const Matrix4 &projection, bool render return calculateDeviceProjection(projection, flags); } -void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight) +void Graphics::backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) { + bool changed = width != this->width || height != this->height + || pixelwidth != this->pixelWidth || pixelheight != this->pixelHeight; + + changed |= backbufferstencil != this->backbufferHasStencil || backbufferdepth != this->backbufferHasDepth; + changed |= msaa != this->requestedBackbufferMSAA; + this->width = width; this->height = height; this->pixelWidth = pixelwidth; this->pixelHeight = pixelheight; + this->backbufferHasStencil = backbufferstencil; + this->backbufferHasDepth = backbufferdepth; + this->requestedBackbufferMSAA = msaa; + if (!isRenderTargetActive()) { // Set the viewport to top-left corner. @@ -220,11 +230,9 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh resetProjection(); } - updateBackbuffer(width, height, pixelwidth, pixelheight, requestedBackbufferMSAA); -} + if (!changed) + return; -void Graphics::updateBackbuffer(int width, int height, int /*pixelwidth*/, int pixelheight, int msaa) -{ bool useinternalbackbuffer = false; if (msaa > 1) useinternalbackbuffer = true; @@ -253,8 +261,17 @@ void Graphics::updateBackbuffer(int width, int height, int /*pixelwidth*/, int p settings.format = isGammaCorrect() ? PIXELFORMAT_RGBA8_sRGB : PIXELFORMAT_RGBA8_UNORM; internalBackbuffer.set(newTexture(settings), Acquire::NORETAIN); - settings.format = PIXELFORMAT_DEPTH24_UNORM_STENCIL8; - internalBackbufferDepthStencil.set(newTexture(settings), Acquire::NORETAIN); + internalBackbufferDepthStencil.set(nullptr); + if (backbufferstencil || backbufferdepth) + { + if (backbufferstencil && backbufferdepth) + settings.format = PIXELFORMAT_DEPTH24_UNORM_STENCIL8; + else if (backbufferstencil) + settings.format = PIXELFORMAT_STENCIL8; + else if (backbufferdepth) + settings.format = PIXELFORMAT_DEPTH24_UNORM; + internalBackbufferDepthStencil.set(newTexture(settings), Acquire::NORETAIN); + } RenderTargets rts; rts.colors.push_back(internalBackbuffer.get()); @@ -269,8 +286,6 @@ void Graphics::updateBackbuffer(int width, int height, int /*pixelwidth*/, int p internalBackbufferFBO = 0; } - requestedBackbufferMSAA = msaa; - if (restoreFBO) gl.bindFramebuffer(OpenGL::FRAMEBUFFER_ALL, prevFBO); } @@ -300,14 +315,8 @@ GLuint Graphics::getSystemBackbufferFBO() const #endif } -bool Graphics::setMode(void */*context*/, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) +bool Graphics::setMode(void */*context*/, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) { - this->width = width; - this->height = height; - - this->windowHasStencil = windowhasstencil; - this->requestedBackbufferMSAA = msaa; - // Okay, setup OpenGL. gl.initContext(); @@ -364,7 +373,7 @@ bool Graphics::setMode(void */*context*/, int width, int height, int pixelwidth, setDebug(isDebugEnabled()); - setViewportSize(width, height, pixelwidth, pixelheight); + backbufferChanged(width, height, pixelwidth, pixelheight, backbufferstencil, backbufferdepth, msaa); if (batchedDrawState.vb[0] == nullptr) { @@ -1436,18 +1445,7 @@ void Graphics::setScissor() void Graphics::setStencilState(const StencilState &s) { - DisplayState &state = states.back(); - - if (s.action != STENCIL_KEEP) - { - const auto &rts = state.renderTargets; - love::graphics::Texture *dstexture = rts.depthStencil.texture.get(); - - if (!isRenderTargetActive() && !windowHasStencil) - throw love::Exception("The window must have stenciling enabled to draw to the main screen's stencil buffer."); - else if (isRenderTargetActive() && (rts.temporaryRTFlags & TEMPORARY_RT_STENCIL) == 0 && (dstexture == nullptr || !isPixelFormatStencil(dstexture->getPixelFormat()))) - throw love::Exception("Drawing to the stencil buffer with a render target active requires either stencil=true or a custom stencil-type texture to be used, in setRenderTarget."); - } + validateStencilState(s); flushBatchedDraws(); @@ -1507,11 +1505,13 @@ void Graphics::setStencilState(const StencilState &s) if (s.writeMask != gl.getStencilWriteMask()) gl.setStencilWriteMask(s.writeMask); - state.stencil = s; + states.back().stencil = s; } void Graphics::setDepthMode(CompareMode compare, bool write) { + validateDepthState(write); + DisplayState &state = states.back(); if (state.depthTest != compare || state.depthWrite != write) diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 894b52e21..7e064420e 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -64,8 +64,8 @@ class Graphics final : public love::graphics::Graphics Matrix4 computeDeviceProjection(const Matrix4 &projection, bool rendertotexture) const override; - void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override; - bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override; + void backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override; + bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override; void unSetMode() override; void setActive(bool active) override; diff --git a/src/modules/graphics/vulkan/Graphics.cpp b/src/modules/graphics/vulkan/Graphics.cpp index 399e9b4e8..98e64e520 100644 --- a/src/modules/graphics/vulkan/Graphics.cpp +++ b/src/modules/graphics/vulkan/Graphics.cpp @@ -587,9 +587,10 @@ void Graphics::present(void *screenshotCallbackdata) beginFrame(); } -void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelheight) +void Graphics::backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) { - if (swapChain != VK_NULL_HANDLE && (pixelwidth != this->pixelWidth || pixelheight != this->pixelHeight || width != this->width || height != this->height)) + if (swapChain != VK_NULL_HANDLE && (pixelwidth != this->pixelWidth || pixelheight != this->pixelHeight || width != this->width || height != this->height + || backbufferstencil != this->backbufferHasStencil || backbufferdepth != this->backbufferHasDepth || msaa != requestedMsaa)) requestSwapchainRecreation(); this->width = width; @@ -597,17 +598,21 @@ void Graphics::setViewportSize(int width, int height, int pixelwidth, int pixelh this->pixelWidth = pixelwidth; this->pixelHeight = pixelheight; + this->backbufferHasStencil = backbufferstencil; + this->backbufferHasDepth = backbufferdepth; + this->requestedMsaa = msaa; + if (!isRenderTargetActive()) resetProjection(); + + if (swapChain != VK_NULL_HANDLE) + msaaSamples = getMsaaCount(requestedMsaa); } -bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) +bool Graphics::setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) { - requestedMsaa = msaa; - windowHasStencil = windowhasstencil; - // Must be called before the swapchain is created. - setViewportSize(width, height, pixelwidth, pixelheight); + backbufferChanged(width, height, pixelwidth, pixelheight, backbufferstencil, backbufferdepth, msaa); cleanUpFunctions.clear(); cleanUpFunctions.resize(MAX_FRAMES_IN_FLIGHT); @@ -1003,16 +1008,7 @@ void Graphics::setScissor() void Graphics::setStencilState(const StencilState &s) { - if (s.action != STENCIL_KEEP) - { - const auto& rts = states.back().renderTargets; - auto dsTexture = rts.depthStencil.texture.get(); - - if (!isRenderTargetActive() && !windowHasStencil) - throw love::Exception("The window must have stenciling enabled to draw to the main screen's stencil buffer"); - else if (isRenderTargetActive() && (rts.temporaryRTFlags & TEMPORARY_RT_STENCIL) == 0 && (dsTexture == nullptr || !isPixelFormatStencil(dsTexture->getPixelFormat()))) - throw love::Exception("drawing to the stencil buffer with a render target active requires either stencil=true or a custom stencil-type to be used, in setRenderTarget"); - } + validateStencilState(s); flushBatchedDraws(); @@ -1033,6 +1029,8 @@ void Graphics::setStencilState(const StencilState &s) void Graphics::setDepthMode(CompareMode compare, bool write) { + validateDepthState(write); + flushBatchedDraws(); if (optionalDeviceExtensions.extendedDynamicState) @@ -1284,11 +1282,12 @@ void Graphics::beginFrame() if (transitionColorDepthLayouts) { - Vulkan::cmdTransitionImageLayout( - commandBuffers.at(currentFrame), - depthImage, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); + if (depthImage) + Vulkan::cmdTransitionImageLayout( + commandBuffers.at(currentFrame), + depthImage, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL); if (colorImage) Vulkan::cmdTransitionImageLayout( @@ -2935,6 +2934,13 @@ VkFormat Graphics::findDepthFormat() void Graphics::createDepthResources() { + if (!backbufferHasDepth && !backbufferHasStencil) + { + depthImage = VK_NULL_HANDLE; + depthImageView = VK_NULL_HANDLE; + return; + } + VkImageCreateInfo imageInfo{}; imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO; imageInfo.imageType = VK_IMAGE_TYPE_2D; @@ -2966,8 +2972,9 @@ void Graphics::createDepthResources() imageViewInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY; imageViewInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY; imageViewInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY; - imageViewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; - if (windowHasStencil) + if (backbufferHasDepth) + imageViewInfo.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT; + if (backbufferHasStencil) imageViewInfo.subresourceRange.aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT; imageViewInfo.subresourceRange.baseMipLevel = 0; imageViewInfo.subresourceRange.levelCount = 1; @@ -3076,8 +3083,11 @@ void Graphics::cleanupSwapChain() vkDestroyImageView(device, colorImageView, nullptr); vmaDestroyImage(vmaAllocator, colorImage, colorImageAllocation); } - vkDestroyImageView(device, depthImageView, nullptr); - vmaDestroyImage(vmaAllocator, depthImage, depthImageAllocation); + if (depthImage) + { + vkDestroyImageView(device, depthImageView, nullptr); + vmaDestroyImage(vmaAllocator, depthImage, depthImageAllocation); + } for (const auto &swapChainImageView : swapChainImageViews) vkDestroyImageView(device, swapChainImageView, nullptr); swapChainImageViews.clear(); diff --git a/src/modules/graphics/vulkan/Graphics.h b/src/modules/graphics/vulkan/Graphics.h index a7c9f9ffd..fc51d69ce 100644 --- a/src/modules/graphics/vulkan/Graphics.h +++ b/src/modules/graphics/vulkan/Graphics.h @@ -284,8 +284,8 @@ class Graphics final : public love::graphics::Graphics Matrix4 computeDeviceProjection(const Matrix4 &projection, bool rendertotexture) const override; void discard(const std::vector& colorbuffers, bool depthstencil) override; void present(void *screenshotCallbackdata) override; - void setViewportSize(int width, int height, int pixelwidth, int pixelheight) override; - bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool windowhasstencil, int msaa) override; + void backbufferChanged(int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override; + bool setMode(void *context, int width, int height, int pixelwidth, int pixelheight, bool backbufferstencil, bool backbufferdepth, int msaa) override; void unSetMode() override; void setActive(bool active) override; int getRequestedBackbufferMSAA() const override; @@ -394,7 +394,6 @@ class Graphics final : public love::graphics::Graphics VkInstance instance = VK_NULL_HANDLE; VkPhysicalDevice physicalDevice = VK_NULL_HANDLE; uint32_t deviceApiVersion = VK_API_VERSION_1_0; - bool windowHasStencil = false; int requestedMsaa = 0; VkDevice device = VK_NULL_HANDLE; OptionalInstanceExtensions optionalInstanceExtensions; diff --git a/src/modules/window/Window.h b/src/modules/window/Window.h index d15091e43..9676dd455 100644 --- a/src/modules/window/Window.h +++ b/src/modules/window/Window.h @@ -262,7 +262,7 @@ struct WindowSettings int vsync = 1; int msaa = 0; bool stencil = true; - int depth = 0; + bool depth = false; bool resizable = false; int minwidth = 1; int minheight = 1; diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index b124bd54e..5205bcd7e 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -127,8 +127,7 @@ void Window::setGLFramebufferAttributes(bool sRGB) SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_RETAINED_BACKING, 0); - // Always use 24/8 depth/stencil (make sure any Graphics implementations - // that have their own backbuffer match this, too). + // Always use 24/8 depth/stencil. // Changing this after initial window creation would need the context to be // destroyed and recreated, which we really don't want. SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); @@ -639,12 +638,12 @@ bool Window::setWindow(int width, int height, WindowSettings *settings) context = (void *) SDL_Metal_GetLayer(metalView); #endif - graphics->setMode(context, (int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil, f.msaa); + graphics->setMode(context, (int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil, f.depth, f.msaa); this->settings.msaa = graphics->getBackbufferMSAA(); } else { - graphics->setViewportSize((int) scaledw, (int) scaledh, pixelWidth, pixelHeight); + graphics->backbufferChanged((int) scaledw, (int) scaledh, pixelWidth, pixelHeight, f.stencil, f.depth, f.msaa); } } @@ -687,7 +686,7 @@ bool Window::onSizeChanged(int width, int height) { double scaledw, scaledh; fromPixels((double) pixelWidth, (double) pixelHeight, scaledw, scaledh); - graphics->setViewportSize((int) scaledw, (int) scaledh, pixelWidth, pixelHeight); + graphics->backbufferChanged((int) scaledw, (int) scaledh, pixelWidth, pixelHeight); } return true; @@ -771,7 +770,7 @@ void Window::updateSettings(const WindowSettings &newsettings, bool updateGraphi { double scaledw, scaledh; fromPixels((double) pixelWidth, (double) pixelHeight, scaledw, scaledh); - graphics->setViewportSize((int) scaledw, (int) scaledh, pixelWidth, pixelHeight); + graphics->backbufferChanged((int) scaledw, (int) scaledh, pixelWidth, pixelHeight); } } diff --git a/src/modules/window/wrap_Window.cpp b/src/modules/window/wrap_Window.cpp index 3d3d86708..60aea2993 100644 --- a/src/modules/window/wrap_Window.cpp +++ b/src/modules/window/wrap_Window.cpp @@ -68,7 +68,6 @@ static int readWindowSettings(lua_State *L, int idx, WindowSettings &settings) settings.fullscreen = luax_boolflag(L, idx, settingName(Window::SETTING_FULLSCREEN), settings.fullscreen); settings.msaa = luax_intflag(L, idx, settingName(Window::SETTING_MSAA), settings.msaa); settings.stencil = luax_boolflag(L, idx, settingName(Window::SETTING_STENCIL), settings.stencil); - settings.depth = luax_intflag(L, idx, settingName(Window::SETTING_DEPTH), settings.depth); settings.resizable = luax_boolflag(L, idx, settingName(Window::SETTING_RESIZABLE), settings.resizable); settings.minwidth = luax_intflag(L, idx, settingName(Window::SETTING_MIN_WIDTH), settings.minwidth); settings.minheight = luax_intflag(L, idx, settingName(Window::SETTING_MIN_HEIGHT), settings.minheight); @@ -76,6 +75,16 @@ static int readWindowSettings(lua_State *L, int idx, WindowSettings &settings) settings.centered = luax_boolflag(L, idx, settingName(Window::SETTING_CENTERED), settings.centered); settings.usedpiscale = luax_boolflag(L, idx, settingName(Window::SETTING_USE_DPISCALE), settings.usedpiscale); + lua_getfield(L, idx, settingName(Window::SETTING_DEPTH)); + if (lua_type(L, -1) == LUA_TNUMBER) + { + luax_markdeprecated(L, 1, "window.depth number", API_FIELD, DEPRECATED_REPLACED, "window.depth boolean field"); + settings.depth = (int) luaL_checknumber(L, -1); + } + else if (!lua_isnoneornil(L, -1)) + settings.depth = lua_toboolean(L, -1); + lua_pop(L, 1); + settings.displayindex = luax_intflag(L, idx, settingName(Window::SETTING_DISPLAYINDEX), settings.displayindex + 1) - 1; lua_getfield(L, idx, settingName(Window::SETTING_DISPLAY)); if (!lua_isnoneornil(L, -1)) @@ -197,7 +206,7 @@ int w_getMode(lua_State *L) luax_pushboolean(L, settings.stencil); lua_setfield(L, -2, settingName(Window::SETTING_STENCIL)); - lua_pushinteger(L, settings.depth); + luax_pushboolean(L, settings.depth); lua_setfield(L, -2, settingName(Window::SETTING_DEPTH)); luax_pushboolean(L, settings.resizable); From 131b6c51e03071aac98e869efc013cc5b227ca38 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sat, 6 Jan 2024 15:22:02 -0400 Subject: [PATCH 11/29] graphics: fix recursion when creating a default texture. --- src/modules/graphics/Graphics.cpp | 9 ++++++--- src/modules/graphics/Graphics.h | 2 ++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 0797e4feb..bb18efc77 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -1927,7 +1927,7 @@ void Graphics::flushBatchedDraws() { auto &sbstate = batchedDrawState; - if (sbstate.vertexCount == 0 && sbstate.indexCount == 0) + if (sbstate.vertexCount == 0 && sbstate.indexCount == 0 || sbstate.flushing) return; VertexAttributes attributes; @@ -1952,6 +1952,8 @@ void Graphics::flushBatchedDraws() if (attributes.enableBits == 0) return; + sbstate.flushing = true; + Colorf nc = getColor(); if (attributes.isEnabled(ATTRIB_COLOR)) setColor(Colorf(1.0f, 1.0f, 1.0f, 1.0f)); @@ -1996,8 +1998,9 @@ void Graphics::flushBatchedDraws() if (attributes.isEnabled(ATTRIB_COLOR)) setColor(nc); - batchedDrawState.vertexCount = 0; - batchedDrawState.indexCount = 0; + sbstate.vertexCount = 0; + sbstate.indexCount = 0; + sbstate.flushing = false; } void Graphics::flushBatchedDrawsGlobal() diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 030d9d7f1..4a2c92b9c 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -989,6 +989,8 @@ class Graphics : public Module StreamBuffer::MapInfo vbMap[2]; StreamBuffer::MapInfo indexBufferMap = StreamBuffer::MapInfo(); + bool flushing = false; + BatchedDrawState() { vb[0] = vb[1] = nullptr; From fffb835358e31a9a838a7b28ebd35b8aa7f595eb Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sat, 6 Jan 2024 15:36:50 -0400 Subject: [PATCH 12/29] tests: fix love.graphics.setDepthMode test --- testing/conf.lua | 2 ++ testing/main.lua | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/testing/conf.lua b/testing/conf.lua index e6f579550..787650a49 100644 --- a/testing/conf.lua +++ b/testing/conf.lua @@ -4,5 +4,7 @@ function love.conf(t) t.window.width = 360 t.window.height = 240 t.window.resizable = true + t.window.depth = true + t.window.stencil = true t.renderers = {"opengl"} end diff --git a/testing/main.lua b/testing/main.lua index c5f74677e..6c7b26165 100644 --- a/testing/main.lua +++ b/testing/main.lua @@ -36,7 +36,7 @@ love.load = function(args) -- setup basic img to display if love.window ~= nil then - love.window.setMode(360, 240, { + love.window.updateMode(360, 240, { fullscreen = false, resizable = true, centered = true From 501c41e10fe67b5b6d7c0d4c6cacfd7b2c00be3d Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sat, 6 Jan 2024 15:44:39 -0400 Subject: [PATCH 13/29] Fix compiler warning --- src/modules/graphics/Graphics.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index bb18efc77..44b196a44 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -1927,7 +1927,7 @@ void Graphics::flushBatchedDraws() { auto &sbstate = batchedDrawState; - if (sbstate.vertexCount == 0 && sbstate.indexCount == 0 || sbstate.flushing) + if ((sbstate.vertexCount == 0 && sbstate.indexCount == 0) || sbstate.flushing) return; VertexAttributes attributes; From a99d5afc57b6901fbab5420e6d86ba2be28762eb Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sun, 7 Jan 2024 21:14:01 -0400 Subject: [PATCH 14/29] update glslang --- CMakeLists.txt | 17 +- .../xcode/liblove.xcodeproj/project.pbxproj | 66 +- .../glslang/OGLCompilersDLL/InitializeDll.cpp | 165 - src/libraries/glslang/SPIRV/GLSL.ext.ARM.h | 35 + src/libraries/glslang/SPIRV/GLSL.ext.EXT.h | 2 + src/libraries/glslang/SPIRV/GLSL.ext.KHR.h | 6 +- src/libraries/glslang/SPIRV/GLSL.ext.NV.h | 6 + src/libraries/glslang/SPIRV/GLSL.ext.QCOM.h | 41 + src/libraries/glslang/SPIRV/GLSL.std.450.h | 2 +- src/libraries/glslang/SPIRV/GlslangToSpv.cpp | 1722 +++- src/libraries/glslang/SPIRV/GlslangToSpv.h | 24 +- src/libraries/glslang/SPIRV/Logger.cpp | 4 - src/libraries/glslang/SPIRV/Logger.h | 9 - .../glslang/SPIRV/NonSemanticDebugPrintf.h | 10 +- .../SPIRV/NonSemanticShaderDebugInfo100.h | 171 + src/libraries/glslang/SPIRV/SPVRemapper.cpp | 60 +- src/libraries/glslang/SPIRV/SPVRemapper.h | 38 +- src/libraries/glslang/SPIRV/SpvBuilder.cpp | 1085 ++- src/libraries/glslang/SPIRV/SpvBuilder.h | 145 +- .../glslang/SPIRV/SpvPostProcess.cpp | 18 +- src/libraries/glslang/SPIRV/SpvTools.cpp | 73 +- src/libraries/glslang/SPIRV/SpvTools.h | 31 +- src/libraries/glslang/SPIRV/disassemble.cpp | 111 +- src/libraries/glslang/SPIRV/doc.cpp | 3145 +++--- src/libraries/glslang/SPIRV/doc.h | 11 +- src/libraries/glslang/SPIRV/hex_float.h | 13 - src/libraries/glslang/SPIRV/spirv.hpp | 5110 +++++----- src/libraries/glslang/SPIRV/spvIR.h | 60 +- .../GL_EXT_shader_realtime_clock.glsl} | 19 +- .../glslang/GenericCodeGen/CodeGen.cpp | 8 +- .../glslang/glslang/GenericCodeGen/Link.cpp | 10 +- .../glslang/glslang/Include/BaseTypes.h | 59 +- .../glslang/glslang/Include/Common.h | 51 +- .../glslang/glslang/Include/ConstantUnion.h | 38 +- .../glslang/Include/InitializeGlobals.h | 2 +- .../glslang/glslang/Include/PoolAlloc.h | 21 +- .../glslang/glslang/Include/ResourceLimits.h | 9 + .../glslang/glslang/Include/ShHandle.h | 16 +- .../glslang/glslang/Include/SpirvIntrinsics.h | 26 +- src/libraries/glslang/glslang/Include/Types.h | 1149 ++- .../glslang/glslang/Include/arrays.h | 29 +- .../glslang/Include/glslang_c_interface.h | 253 - .../glslang/Include/glslang_c_shader_types.h | 207 - .../glslang/glslang/Include/intermediate.h | 178 +- .../glslang/MachineIndependent/Constant.cpp | 36 +- .../glslang/MachineIndependent/Initialize.cpp | 1387 ++- .../glslang/MachineIndependent/Initialize.h | 3 + .../MachineIndependent/Intermediate.cpp | 193 +- .../MachineIndependent/ParseContextBase.cpp | 51 +- .../MachineIndependent/ParseHelper.cpp | 1659 +++- .../glslang/MachineIndependent/ParseHelper.h | 35 +- .../glslang/MachineIndependent/PoolAlloc.cpp | 48 +- .../glslang/MachineIndependent/Scan.cpp | 131 +- .../glslang/MachineIndependent/ShaderLang.cpp | 250 +- .../MachineIndependent/SpirvIntrinsics.cpp | 74 +- .../MachineIndependent/SymbolTable.cpp | 29 +- .../glslang/MachineIndependent/SymbolTable.h | 66 +- .../glslang/MachineIndependent/Versions.cpp | 129 +- .../glslang/MachineIndependent/Versions.h | 37 +- .../glslang/MachineIndependent/attribute.cpp | 7 +- .../glslang/MachineIndependent/attribute.h | 1 + .../MachineIndependent/glslang_tab.cpp | 8645 +++++++++-------- .../MachineIndependent/glslang_tab.cpp.h | 602 +- .../glslang/MachineIndependent/intermOut.cpp | 84 +- .../glslang/MachineIndependent/iomapper.cpp | 53 +- .../glslang/MachineIndependent/iomapper.h | 15 +- .../glslang/MachineIndependent/limits.cpp | 2 - .../MachineIndependent/linkValidate.cpp | 508 +- .../MachineIndependent/localintermediate.h | 219 +- .../glslang/MachineIndependent/parseConst.cpp | 2 +- .../MachineIndependent/parseVersions.h | 78 +- .../MachineIndependent/preprocessor/Pp.cpp | 28 +- .../preprocessor/PpContext.cpp | 2 +- .../preprocessor/PpContext.h | 60 +- .../preprocessor/PpScanner.cpp | 119 +- .../preprocessor/PpTokens.cpp | 11 +- .../propagateNoContraction.cpp | 8 +- .../glslang/MachineIndependent/reflection.cpp | 26 +- .../glslang/MachineIndependent/reflection.h | 4 - .../glslang/glslang/MachineIndependent/span.h | 92 + .../glslang/OSDependent/Unix/ossource.cpp | 151 - .../glslang/OSDependent/Web/glslang.js.cpp | 9 + .../glslang/OSDependent/Web/glslang.pre.js | 2 +- .../glslang/OSDependent/Windows/ossource.cpp | 80 - .../glslang/glslang/OSDependent/osinclude.h | 19 - .../main.cpp => Public/ResourceLimits.h} | 55 +- .../glslang/glslang/Public/ShaderLang.h | 76 +- .../glslang/ResourceLimits/ResourceLimits.cpp | 542 ++ src/libraries/glslang/glslang/build_info.h | 26 +- src/modules/graphics/ShaderStage.cpp | 111 +- src/modules/graphics/metal/Shader.mm | 111 +- src/modules/graphics/vulkan/Shader.cpp | 110 +- 92 files changed, 17389 insertions(+), 12852 deletions(-) delete mode 100644 src/libraries/glslang/OGLCompilersDLL/InitializeDll.cpp create mode 100644 src/libraries/glslang/SPIRV/GLSL.ext.ARM.h create mode 100644 src/libraries/glslang/SPIRV/GLSL.ext.QCOM.h mode change 100644 => 100755 src/libraries/glslang/SPIRV/GlslangToSpv.cpp create mode 100644 src/libraries/glslang/SPIRV/NonSemanticShaderDebugInfo100.h mode change 100644 => 100755 src/libraries/glslang/SPIRV/doc.cpp rename src/libraries/glslang/{OGLCompilersDLL/InitializeDll.h => glslang/ExtensionHeaders/GL_EXT_shader_realtime_clock.glsl} (79%) mode change 100644 => 100755 src/libraries/glslang/glslang/Include/BaseTypes.h delete mode 100644 src/libraries/glslang/glslang/Include/glslang_c_interface.h delete mode 100644 src/libraries/glslang/glslang/Include/glslang_c_shader_types.h mode change 100644 => 100755 src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp mode change 100644 => 100755 src/libraries/glslang/glslang/MachineIndependent/Versions.h create mode 100644 src/libraries/glslang/glslang/MachineIndependent/span.h rename src/libraries/glslang/glslang/{OSDependent/Windows/main.cpp => Public/ResourceLimits.h} (61%) create mode 100644 src/libraries/glslang/glslang/ResourceLimits/ResourceLimits.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 52390b865..4c679fecb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1391,6 +1391,7 @@ set(LOVE_SRC_3P_GLSLANG_GLSLANG_MACHINEINDEPENDENT src/libraries/glslang/glslang/MachineIndependent/Scan.h src/libraries/glslang/glslang/MachineIndependent/ScanContext.h src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp + src/libraries/glslang/glslang/MachineIndependent/span.h src/libraries/glslang/glslang/MachineIndependent/SpirvIntrinsics.cpp src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h @@ -1405,7 +1406,6 @@ set(LOVE_SRC_3P_GLSLANG_GLSLANG_OSDEPENDENT if(MSVC OR MINGW) set(LOVE_SRC_3P_GLSLANG_GLSLANG_OSDEPENDENT ${LOVE_SRC_3P_GLSLANG_GLSLANG_OSDEPENDENT} - src/libraries/glslang/glslang/OSDependent/Windows/main.cpp src/libraries/glslang/glslang/OSDependent/Windows/ossource.cpp ) else() @@ -1416,9 +1416,14 @@ else() endif() set(LOVE_SRC_3P_GLSLANG_GLSLANG_PUBLIC + src/libraries/glslang/glslang/Public/ResourceLimits.h src/libraries/glslang/glslang/Public/ShaderLang.h ) +set(LOVE_SRC_3P_GLSLANG_GLSLANG_RESOURCELIMITS + src/libraries/glslang/glslang/ResourceLimits/ResourceLimits.cpp +) + set(LOVE_SRC_3P_GLSLANG_GLSLANG src/libraries/glslang/glslang/build_info.h ${LOVE_SRC_3P_GLSLANG_GLSLANG_GENERICCODEGEN} @@ -1426,11 +1431,7 @@ set(LOVE_SRC_3P_GLSLANG_GLSLANG ${LOVE_SRC_3P_GLSLANG_GLSLANG_MACHINEINDEPENDENT} ${LOVE_SRC_3P_GLSLANG_GLSLANG_OSDEPENDENT} ${LOVE_SRC_3P_GLSLANG_GLSLANG_PUBLIC} -) - -set(LOVE_SRC_3P_GLSLANG_OGLCOMPILERSDLL - src/libraries/glslang/OGLCompilersDLL/InitializeDll.cpp - src/libraries/glslang/OGLCompilersDLL/InitializeDll.h + ${LOVE_SRC_3P_GLSLANG_GLSLANG_RESOURCELIMITS} ) set(LOVE_SRC_3P_GLSLANG_SPIRV @@ -1440,9 +1441,11 @@ set(LOVE_SRC_3P_GLSLANG_SPIRV 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.ARM.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.ext.QCOM.h src/libraries/glslang/SPIRV/GLSL.std.450.h src/libraries/glslang/SPIRV/GlslangToSpv.cpp src/libraries/glslang/SPIRV/GlslangToSpv.h @@ -1451,6 +1454,7 @@ set(LOVE_SRC_3P_GLSLANG_SPIRV src/libraries/glslang/SPIRV/Logger.cpp src/libraries/glslang/SPIRV/Logger.h src/libraries/glslang/SPIRV/NonSemanticDebugPrintf.h + src/libraries/glslang/SPIRV/NonSemanticShaderDebugInfo100.h src/libraries/glslang/SPIRV/spirv.hpp src/libraries/glslang/SPIRV/SpvBuilder.cpp src/libraries/glslang/SPIRV/SpvBuilder.h @@ -1464,7 +1468,6 @@ set(LOVE_SRC_3P_GLSLANG_SPIRV set(LOVE_SRC_3P_GLSLANG ${LOVE_SRC_3P_GLSLANG_GLSLANG} - ${LOVE_SRC_3P_GLSLANG_OGLCOMPILERSDLL} ${LOVE_SRC_3P_GLSLANG_SPIRV} ) diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index e591d2743..7a206b70e 100644 --- a/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/platform/xcode/liblove.xcodeproj/project.pbxproj @@ -64,6 +64,15 @@ D9DAB92D2961F10000C64820 /* TextShaper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D9DAB9282961F10000C64820 /* TextShaper.cpp */; }; D9DAB92E2961F10000C64820 /* TextShaper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D9DAB9282961F10000C64820 /* TextShaper.cpp */; }; D9DAB9322963CD7500C64820 /* harfbuzz.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D9DAB9312963CD7500C64820 /* harfbuzz.framework */; }; + D9DB6E272B4B40660037A1F6 /* ResourceLimits.h in Headers */ = {isa = PBXBuildFile; fileRef = D9DB6E252B4B40660037A1F6 /* ResourceLimits.h */; }; + D9DB6E292B4B40970037A1F6 /* span.h in Headers */ = {isa = PBXBuildFile; fileRef = D9DB6E282B4B40970037A1F6 /* span.h */; }; + D9DB6E362B4B41100037A1F6 /* ResourceLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D9DB6E332B4B41100037A1F6 /* ResourceLimits.cpp */; }; + D9DB6E372B4B41100037A1F6 /* ResourceLimits.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D9DB6E332B4B41100037A1F6 /* ResourceLimits.cpp */; }; + D9DB6E3E2B4B41580037A1F6 /* NonSemanticDebugPrintf.h in Headers */ = {isa = PBXBuildFile; fileRef = D9DB6E382B4B41570037A1F6 /* NonSemanticDebugPrintf.h */; }; + D9DB6E3F2B4B41580037A1F6 /* NonSemanticShaderDebugInfo100.h in Headers */ = {isa = PBXBuildFile; fileRef = D9DB6E392B4B41570037A1F6 /* NonSemanticShaderDebugInfo100.h */; }; + D9DB6E402B4B41580037A1F6 /* GLSL.ext.ARM.h in Headers */ = {isa = PBXBuildFile; fileRef = D9DB6E3A2B4B41570037A1F6 /* GLSL.ext.ARM.h */; }; + D9DB6E412B4B41580037A1F6 /* GLSL.ext.QCOM.h in Headers */ = {isa = PBXBuildFile; fileRef = D9DB6E3B2B4B41580037A1F6 /* GLSL.ext.QCOM.h */; }; + D9DB6E452B4B80E80037A1F6 /* build_info.h in Headers */ = {isa = PBXBuildFile; fileRef = D9DB6E442B4B80E80037A1F6 /* build_info.h */; }; FA0A3A5F23366CE9001C269E /* floattypes.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0A3A5D23366CE9001C269E /* floattypes.h */; }; FA0A3A6023366CE9001C269E /* floattypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0A3A5E23366CE9001C269E /* floattypes.cpp */; }; FA0A3A6123366CE9001C269E /* floattypes.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA0A3A5E23366CE9001C269E /* floattypes.cpp */; }; @@ -1288,9 +1297,6 @@ FAF140BB1E20934C00F898D2 /* ossource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF140211E20934C00F898D2 /* ossource.cpp */; }; FAF140BC1E20934C00F898D2 /* ossource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF140211E20934C00F898D2 /* ossource.cpp */; }; FAF140C41E20934C00F898D2 /* ShaderLang.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF140291E20934C00F898D2 /* ShaderLang.h */; }; - FAF140DB1E20934C00F898D2 /* 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 */; }; 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 */; }; @@ -1409,6 +1415,14 @@ D9DAB9272961F0FF00C64820 /* TextShaper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextShaper.h; sourceTree = ""; }; D9DAB9282961F10000C64820 /* TextShaper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextShaper.cpp; sourceTree = ""; }; D9DAB9312963CD7500C64820 /* harfbuzz.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = harfbuzz.framework; path = macosx/Frameworks/harfbuzz.framework; sourceTree = ""; }; + D9DB6E252B4B40660037A1F6 /* ResourceLimits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLimits.h; sourceTree = ""; }; + D9DB6E282B4B40970037A1F6 /* span.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = span.h; sourceTree = ""; }; + D9DB6E332B4B41100037A1F6 /* ResourceLimits.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceLimits.cpp; sourceTree = ""; }; + D9DB6E382B4B41570037A1F6 /* NonSemanticDebugPrintf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NonSemanticDebugPrintf.h; sourceTree = ""; }; + D9DB6E392B4B41570037A1F6 /* NonSemanticShaderDebugInfo100.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NonSemanticShaderDebugInfo100.h; sourceTree = ""; }; + D9DB6E3A2B4B41570037A1F6 /* GLSL.ext.ARM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLSL.ext.ARM.h; sourceTree = ""; }; + D9DB6E3B2B4B41580037A1F6 /* GLSL.ext.QCOM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GLSL.ext.QCOM.h; sourceTree = ""; }; + D9DB6E442B4B80E80037A1F6 /* build_info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = build_info.h; sourceTree = ""; }; FA08F5AE16C7525600F007B5 /* liblove-macosx.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "liblove-macosx.plist"; path = "macosx/liblove-macosx.plist"; sourceTree = ""; }; FA0A3A5D23366CE9001C269E /* floattypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = floattypes.h; sourceTree = ""; }; FA0A3A5E23366CE9001C269E /* floattypes.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = floattypes.cpp; sourceTree = ""; }; @@ -1945,8 +1959,6 @@ FA7DA04C1C16874A0056B200 /* wrap_Math.lua */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wrap_Math.lua; sourceTree = ""; }; FA7E9206277E120900C24CB2 /* theora.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = theora.xcframework; path = ios/libraries/theora.xcframework; sourceTree = ""; }; FA84DE5D2778D7DB002674C6 /* SpirvIntrinsics.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SpirvIntrinsics.h; sourceTree = ""; }; - FA84DE5E2778D7DC002674C6 /* glslang_c_interface.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = glslang_c_interface.h; sourceTree = ""; }; - FA84DE5F2778D7DC002674C6 /* glslang_c_shader_types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = glslang_c_shader_types.h; sourceTree = ""; }; FA84DE602778D7F3002674C6 /* SpirvIntrinsics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpirvIntrinsics.cpp; sourceTree = ""; }; FA84DE6427791C36002674C6 /* GraphicsReadback.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsReadback.cpp; sourceTree = ""; }; FA84DE6527791C36002674C6 /* GraphicsReadback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GraphicsReadback.h; sourceTree = ""; }; @@ -2199,7 +2211,6 @@ FADF543A1E3DAFF700012CC0 /* wrap_Graphics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Graphics.h; sourceTree = ""; }; FAE272501C05A15B00A67640 /* ParticleSystem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleSystem.cpp; sourceTree = ""; }; FAE272511C05A15B00A67640 /* ParticleSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleSystem.h; sourceTree = ""; }; - FAEC229F2534F25100EBD925 /* build_info.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = build_info.h; sourceTree = ""; }; FAECA1B01F3164700095D008 /* CompressedSlice.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedSlice.cpp; sourceTree = ""; }; FAECA1B11F3164700095D008 /* CompressedSlice.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CompressedSlice.h; sourceTree = ""; }; FAF13FC21E20934C00F898D2 /* CodeGen.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CodeGen.cpp; sourceTree = ""; }; @@ -2261,8 +2272,6 @@ FAF140031E20934C00F898D2 /* osinclude.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = osinclude.h; sourceTree = ""; }; FAF140211E20934C00F898D2 /* ossource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ossource.cpp; sourceTree = ""; }; FAF140291E20934C00F898D2 /* ShaderLang.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShaderLang.h; sourceTree = ""; }; - FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeDll.cpp; sourceTree = ""; }; - FAF1403C1E20934C00F898D2 /* InitializeDll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeDll.h; sourceTree = ""; }; FAF1889C1E9DA834008C1479 /* Optional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Optional.h; sourceTree = ""; }; FAF6C9C123C2DE2900D7B5BC /* SPVRemapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SPVRemapper.h; sourceTree = ""; }; FAF6C9C223C2DE2900D7B5BC /* SpvBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpvBuilder.h; sourceTree = ""; }; @@ -2371,6 +2380,14 @@ sourceTree = ""; usesTabs = 1; }; + D9DB6E312B4B41100037A1F6 /* ResourceLimits */ = { + isa = PBXGroup; + children = ( + D9DB6E332B4B41100037A1F6 /* ResourceLimits.cpp */, + ); + path = ResourceLimits; + sourceTree = ""; + }; FA08F5AC16C751BA00F007B5 /* Resources */ = { isa = PBXGroup; children = ( @@ -3870,7 +3887,6 @@ isa = PBXGroup; children = ( FAF13FC01E20934C00F898D2 /* glslang */, - FAF1403A1E20934C00F898D2 /* OGLCompilersDLL */, FAF6C9C023C2DE2900D7B5BC /* SPIRV */, ); path = glslang; @@ -3879,12 +3895,13 @@ FAF13FC01E20934C00F898D2 /* glslang */ = { isa = PBXGroup; children = ( - FAEC229F2534F25100EBD925 /* build_info.h */, + D9DB6E442B4B80E80037A1F6 /* build_info.h */, FAF13FC11E20934C00F898D2 /* GenericCodeGen */, FAF13FC41E20934C00F898D2 /* Include */, FAF13FD21E20934C00F898D2 /* MachineIndependent */, FAF140021E20934C00F898D2 /* OSDependent */, FAF140281E20934C00F898D2 /* Public */, + D9DB6E312B4B41100037A1F6 /* ResourceLimits */, ); path = glslang; sourceTree = ""; @@ -3905,8 +3922,6 @@ FAF13FC61E20934C00F898D2 /* BaseTypes.h */, FAF13FC71E20934C00F898D2 /* Common.h */, FAF13FC81E20934C00F898D2 /* ConstantUnion.h */, - FA84DE5E2778D7DC002674C6 /* glslang_c_interface.h */, - FA84DE5F2778D7DC002674C6 /* glslang_c_shader_types.h */, FAF13FC91E20934C00F898D2 /* InfoSink.h */, FAF13FCA1E20934C00F898D2 /* InitializeGlobals.h */, FAF13FCB1E20934C00F898D2 /* intermediate.h */, @@ -3958,6 +3973,7 @@ FAF13FFB1E20934C00F898D2 /* Scan.h */, FAF13FFC1E20934C00F898D2 /* ScanContext.h */, FAF13FFD1E20934C00F898D2 /* ShaderLang.cpp */, + D9DB6E282B4B40970037A1F6 /* span.h */, FA84DE602778D7F3002674C6 /* SpirvIntrinsics.cpp */, FAF13FFE1E20934C00F898D2 /* SymbolTable.cpp */, FAF13FFF1E20934C00F898D2 /* SymbolTable.h */, @@ -4001,20 +4017,12 @@ FAF140281E20934C00F898D2 /* Public */ = { isa = PBXGroup; children = ( + D9DB6E252B4B40660037A1F6 /* ResourceLimits.h */, FAF140291E20934C00F898D2 /* ShaderLang.h */, ); path = Public; sourceTree = ""; }; - FAF1403A1E20934C00F898D2 /* OGLCompilersDLL */ = { - isa = PBXGroup; - children = ( - FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */, - FAF1403C1E20934C00F898D2 /* InitializeDll.h */, - ); - path = OGLCompilersDLL; - sourceTree = ""; - }; FAF6C9C023C2DE2900D7B5BC /* SPIRV */ = { isa = PBXGroup; children = ( @@ -4024,9 +4032,11 @@ FAF6C9D823C2DE2900D7B5BC /* doc.cpp */, FAF6C9C823C2DE2900D7B5BC /* doc.h */, FAF6C9C723C2DE2900D7B5BC /* GLSL.ext.AMD.h */, + D9DB6E3A2B4B41570037A1F6 /* GLSL.ext.ARM.h */, FAF6C9CB23C2DE2900D7B5BC /* GLSL.ext.EXT.h */, FAF6C9CC23C2DE2900D7B5BC /* GLSL.ext.KHR.h */, FAF6C9CD23C2DE2900D7B5BC /* GLSL.ext.NV.h */, + D9DB6E3B2B4B41580037A1F6 /* GLSL.ext.QCOM.h */, FAF6C9D323C2DE2900D7B5BC /* GLSL.std.450.h */, FAF6C9CE23C2DE2900D7B5BC /* GlslangToSpv.cpp */, FAF6C9D223C2DE2900D7B5BC /* GlslangToSpv.h */, @@ -4034,6 +4044,8 @@ FAF6C9C623C2DE2900D7B5BC /* InReadableOrder.cpp */, FAF6C9D523C2DE2900D7B5BC /* Logger.cpp */, FAF6C9D723C2DE2900D7B5BC /* Logger.h */, + D9DB6E382B4B41570037A1F6 /* NonSemanticDebugPrintf.h */, + D9DB6E392B4B41570037A1F6 /* NonSemanticShaderDebugInfo100.h */, FAF6C9C923C2DE2900D7B5BC /* spirv.hpp */, FAF6C9CA23C2DE2900D7B5BC /* SpvBuilder.cpp */, FAF6C9C223C2DE2900D7B5BC /* SpvBuilder.h */, @@ -4091,6 +4103,7 @@ FAF6C9EF23C2DE2900D7B5BC /* disassemble.h in Headers */, FA18CF4123DCF67900263725 /* spirv_common.hpp in Headers */, FAC7CD901FE35E95006A60C7 /* physfs_miniz.h in Headers */, + D9DB6E3F2B4B41580037A1F6 /* NonSemanticShaderDebugInfo100.h in Headers */, FA0B791D1A958E3B000E1D17 /* b64.h in Headers */, FA0B7DC61A95902C000E1D17 /* wrap_JoystickModule.h in Headers */, FA0B7D201A95902C000E1D17 /* ImageRasterizer.h in Headers */, @@ -4109,6 +4122,7 @@ FAF140871E20934C00F898D2 /* parseVersions.h in Headers */, FA0B7AC61A958EA3000E1D17 /* types.h in Headers */, FA0B7DBD1A95902C000E1D17 /* Joystick.h in Headers */, + D9DB6E452B4B80E80037A1F6 /* build_info.h in Headers */, FA0B7D0E1A95902C000E1D17 /* wrap_Filesystem.h in Headers */, FA0B7EE41A95902D000E1D17 /* Window.h in Headers */, FA0B7CFC1A95902C000E1D17 /* Filesystem.h in Headers */, @@ -4297,12 +4311,14 @@ FA0B7AC81A958EA3000E1D17 /* utility.h in Headers */, FABDA9BA2552448300B5C523 /* b2_weld_joint.h in Headers */, FA522D5323F9FF2A0059EE3C /* dr_mp3.h in Headers */, + D9DB6E272B4B40660037A1F6 /* ResourceLimits.h in Headers */, FA0B791F1A958E3B000E1D17 /* Data.h in Headers */, FA18CF4523DD1A8100263725 /* ShaderStage.h in Headers */, 217DFBE41D9F6D490055D849 /* headers.lua.h in Headers */, FA0B7D021A95902C000E1D17 /* Filesystem.h in Headers */, FA0B7E471A95902C000E1D17 /* wrap_Contact.h in Headers */, FA0B7E021A95902C000E1D17 /* CircleShape.h in Headers */, + D9DB6E3E2B4B41580037A1F6 /* NonSemanticDebugPrintf.h in Headers */, FABDA9E92552448300B5C523 /* b2_timer.h in Headers */, FA0B7E111A95902C000E1D17 /* FrictionJoint.h in Headers */, FA0B7AE01A958EA3000E1D17 /* lodepng.h in Headers */, @@ -4362,6 +4378,7 @@ FA0B7DC31A95902C000E1D17 /* wrap_Joystick.h in Headers */, FA18CF3B23DCF67900263725 /* spirv_cross_util.hpp in Headers */, FAF140631E20934C00F898D2 /* Types.h in Headers */, + D9DB6E292B4B40970037A1F6 /* span.h in Headers */, FACA06AF293EE5CD001A2557 /* Sensor.h in Headers */, FA4F2BE61DE6650600CA37D7 /* wrap_Transform.h in Headers */, FA0B7EE71A95902D000E1D17 /* Window.h in Headers */, @@ -4378,7 +4395,6 @@ FABDA9DD2552448300B5C523 /* b2_contact.h in Headers */, FABDA9802552448200B5C523 /* b2_circle_contact.h in Headers */, 217DFC101D9F6D490055D849 /* url.lua.h in Headers */, - FAF140DD1E20934C00F898D2 /* InitializeDll.h in Headers */, FA0B7DF31A95902C000E1D17 /* wrap_Cursor.h in Headers */, FA18CF2023DCF67900263725 /* spirv_hlsl.hpp in Headers */, FA0B7D271A95902C000E1D17 /* wrap_Font.h in Headers */, @@ -4437,6 +4453,7 @@ 217DFC021D9F6D490055D849 /* tcp.h in Headers */, FA3C5E441F8C368C0003C579 /* ShaderStage.h in Headers */, FA0B79261A958E3B000E1D17 /* Exception.h in Headers */, + D9DB6E402B4B41580037A1F6 /* GLSL.ext.ARM.h in Headers */, FA0B7D4D1A95902C000E1D17 /* Shader.h in Headers */, FA0B793D1A958E3B000E1D17 /* runtime.h in Headers */, FAF6C9E323C2DE2900D7B5BC /* GLSL.ext.AMD.h in Headers */, @@ -4463,6 +4480,7 @@ FA6BDF90281219E900240F2A /* DataStream.h in Headers */, FAF6C9DB23C2DE2900D7B5BC /* SpvBuilder.h in Headers */, FA0B7EA21A95902C000E1D17 /* Sound.h in Headers */, + D9DB6E412B4B41580037A1F6 /* GLSL.ext.QCOM.h in Headers */, FA0B7B331A958EA3000E1D17 /* wuff_config.h in Headers */, FA0B7D3B1A95902C000E1D17 /* Graphics.h in Headers */, FA0B7E6E1A95902C000E1D17 /* wrap_RevoluteJoint.h in Headers */, @@ -4636,6 +4654,7 @@ FAF140A81E20934C00F898D2 /* ShaderLang.cpp in Sources */, FA1BA09E1E16CFCE00AA2803 /* Font.cpp in Sources */, FABDA9A12552448300B5C523 /* b2_gear_joint.cpp in Sources */, + D9DB6E372B4B41100037A1F6 /* ResourceLimits.cpp in Sources */, FAE64A8A2071363100BC7981 /* physfs_archiver_wad.c in Sources */, FA18CF4723DD1A8100263725 /* ShaderStage.mm in Sources */, FA0B7ECC1A95902C000E1D17 /* wrap_Channel.cpp in Sources */, @@ -4746,7 +4765,6 @@ FAF140AD1E20934C00F898D2 /* Versions.cpp in Sources */, FA0B793C1A958E3B000E1D17 /* runtime.cpp in Sources */, FA6BDF8A280B62A000240F2A /* GraphicsReadback.mm in Sources */, - FAF140DC1E20934C00F898D2 /* InitializeDll.cpp in Sources */, FA0B7DBC1A95902C000E1D17 /* Joystick.cpp in Sources */, FA0B7DAF1A95902C000E1D17 /* wrap_CompressedImageData.cpp in Sources */, FA0B7AD51A958EA3000E1D17 /* unix.c in Sources */, @@ -5065,6 +5083,7 @@ FA0B7D7C1A95902C000E1D17 /* Texture.cpp in Sources */, FAF140BB1E20934C00F898D2 /* ossource.cpp in Sources */, FA0B7ECB1A95902C000E1D17 /* wrap_Channel.cpp in Sources */, + D9DB6E362B4B41100037A1F6 /* ResourceLimits.cpp in Sources */, FACA02F21F5E396B0084B28F /* HashFunction.cpp in Sources */, FABDA9A02552448300B5C523 /* b2_gear_joint.cpp in Sources */, FAF140A71E20934C00F898D2 /* ShaderLang.cpp in Sources */, @@ -5186,7 +5205,6 @@ FAC7CD811FE35E95006A60C7 /* physfs_platform_os2.c in Sources */, FABDA9962552448300B5C523 /* b2_distance_joint.cpp in Sources */, FA0B7DBB1A95902C000E1D17 /* Joystick.cpp in Sources */, - FAF140DB1E20934C00F898D2 /* InitializeDll.cpp in Sources */, FA0B7DAE1A95902C000E1D17 /* wrap_CompressedImageData.cpp in Sources */, FA6A2B701F5F845F0074C308 /* wrap_DataView.cpp in Sources */, FAB17BE61ABFAA9000F9BA27 /* lz4.c in Sources */, diff --git a/src/libraries/glslang/OGLCompilersDLL/InitializeDll.cpp b/src/libraries/glslang/OGLCompilersDLL/InitializeDll.cpp deleted file mode 100644 index abea9108b..000000000 --- a/src/libraries/glslang/OGLCompilersDLL/InitializeDll.cpp +++ /dev/null @@ -1,165 +0,0 @@ -// -// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. -// 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. -// - -#define SH_EXPORTING - -#include - -#include "InitializeDll.h" -#include "../glslang/Include/InitializeGlobals.h" -#include "../glslang/Public/ShaderLang.h" -#include "../glslang/Include/PoolAlloc.h" - -namespace glslang { - -OS_TLSIndex ThreadInitializeIndex = OS_INVALID_TLS_INDEX; - -// Per-process initialization. -// Needs to be called at least once before parsing, etc. is done. -// Will also do thread initialization for the calling thread; other -// threads will need to do that explicitly. -bool InitProcess() -{ - glslang::GetGlobalLock(); - - if (ThreadInitializeIndex != OS_INVALID_TLS_INDEX) { - // - // Function is re-entrant. - // - - glslang::ReleaseGlobalLock(); - return true; - } - - ThreadInitializeIndex = OS_AllocTLSIndex(); - - if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "InitProcess(): Failed to allocate TLS area for init flag"); - - glslang::ReleaseGlobalLock(); - return false; - } - - if (! InitializePoolIndex()) { - assert(0 && "InitProcess(): Failed to initialize global pool"); - - glslang::ReleaseGlobalLock(); - return false; - } - - if (! InitThread()) { - assert(0 && "InitProcess(): Failed to initialize thread"); - - glslang::ReleaseGlobalLock(); - return false; - } - - glslang::ReleaseGlobalLock(); - return true; -} - -// Per-thread scoped initialization. -// Must be called at least once by each new thread sharing the -// symbol tables, etc., needed to parse. -bool InitThread() -{ - // - // This function is re-entrant - // - if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "InitThread(): Process hasn't been initalised."); - return false; - } - - if (OS_GetTLSValue(ThreadInitializeIndex) != 0) - return true; - - if (! OS_SetTLSValue(ThreadInitializeIndex, (void *)1)) { - assert(0 && "InitThread(): Unable to set init flag."); - return false; - } - - glslang::SetThreadPoolAllocator(nullptr); - - return true; -} - -// Not necessary to call this: InitThread() is reentrant, and the need -// to do per thread tear down has been removed. -// -// This is kept, with memory management removed, to satisfy any exiting -// calls to it that rely on it. -bool DetachThread() -{ - bool success = true; - - if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) - return true; - - // - // Function is re-entrant and this thread may not have been initialized. - // - if (OS_GetTLSValue(ThreadInitializeIndex) != 0) { - if (!OS_SetTLSValue(ThreadInitializeIndex, (void *)0)) { - assert(0 && "DetachThread(): Unable to clear init flag."); - success = false; - } - } - - return success; -} - -// Not necessary to call this: InitProcess() is reentrant. -// -// This is kept, with memory management removed, to satisfy any exiting -// calls to it that rely on it. -// -// Users of glslang should call shFinalize() or glslang::FinalizeProcess() for -// process-scoped memory tear down. -bool DetachProcess() -{ - bool success = true; - - if (ThreadInitializeIndex == OS_INVALID_TLS_INDEX) - return true; - - success = DetachThread(); - - OS_FreeTLSIndex(ThreadInitializeIndex); - ThreadInitializeIndex = OS_INVALID_TLS_INDEX; - - return success; -} - -} // end namespace glslang diff --git a/src/libraries/glslang/SPIRV/GLSL.ext.ARM.h b/src/libraries/glslang/SPIRV/GLSL.ext.ARM.h new file mode 100644 index 000000000..14425be1e --- /dev/null +++ b/src/libraries/glslang/SPIRV/GLSL.ext.ARM.h @@ -0,0 +1,35 @@ +/* +** Copyright (c) 2022 ARM Limited +** +** 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 GLSLextARM_H +#define GLSLextARM_H + +static const int GLSLextARMVersion = 100; +static const int GLSLextARMRevision = 1; + +static const char * const E_SPV_ARM_core_builtins = "SPV_ARM_core_builtins"; + +#endif // #ifndef GLSLextARM_H diff --git a/src/libraries/glslang/SPIRV/GLSL.ext.EXT.h b/src/libraries/glslang/SPIRV/GLSL.ext.EXT.h index f48f1304d..caab27938 100644 --- a/src/libraries/glslang/SPIRV/GLSL.ext.EXT.h +++ b/src/libraries/glslang/SPIRV/GLSL.ext.EXT.h @@ -39,5 +39,7 @@ static const char* const E_SPV_EXT_shader_atomic_float_add = "SPV_EXT_shader_ato static const char* const E_SPV_EXT_shader_atomic_float16_add = "SPV_EXT_shader_atomic_float16_add"; static const char* const E_SPV_EXT_shader_atomic_float_min_max = "SPV_EXT_shader_atomic_float_min_max"; static const char* const E_SPV_EXT_shader_image_int64 = "SPV_EXT_shader_image_int64"; +static const char* const E_SPV_EXT_shader_tile_image = "SPV_EXT_shader_tile_image"; +static const char* const E_SPV_EXT_mesh_shader = "SPV_EXT_mesh_shader"; #endif // #ifndef GLSLextEXT_H diff --git a/src/libraries/glslang/SPIRV/GLSL.ext.KHR.h b/src/libraries/glslang/SPIRV/GLSL.ext.KHR.h index 5eb3e9448..121defa16 100644 --- a/src/libraries/glslang/SPIRV/GLSL.ext.KHR.h +++ b/src/libraries/glslang/SPIRV/GLSL.ext.KHR.h @@ -29,7 +29,7 @@ #define GLSLextKHR_H static const int GLSLextKHRVersion = 100; -static const int GLSLextKHRRevision = 2; +static const int GLSLextKHRRevision = 3; 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"; @@ -52,5 +52,9 @@ static const char* const E_SPV_KHR_fragment_shading_rate = "SPV_KHR_fragm static const char* const E_SPV_KHR_terminate_invocation = "SPV_KHR_terminate_invocation"; static const char* const E_SPV_KHR_workgroup_memory_explicit_layout = "SPV_KHR_workgroup_memory_explicit_layout"; static const char* const E_SPV_KHR_subgroup_uniform_control_flow = "SPV_KHR_subgroup_uniform_control_flow"; +static const char* const E_SPV_KHR_fragment_shader_barycentric = "SPV_KHR_fragment_shader_barycentric"; +static const char* const E_SPV_AMD_shader_early_and_late_fragment_tests = "SPV_AMD_shader_early_and_late_fragment_tests"; +static const char* const E_SPV_KHR_ray_tracing_position_fetch = "SPV_KHR_ray_tracing_position_fetch"; +static const char* const E_SPV_KHR_cooperative_matrix = "SPV_KHR_cooperative_matrix"; #endif // #ifndef GLSLextKHR_H diff --git a/src/libraries/glslang/SPIRV/GLSL.ext.NV.h b/src/libraries/glslang/SPIRV/GLSL.ext.NV.h index 93c98bf62..9889bc9f9 100644 --- a/src/libraries/glslang/SPIRV/GLSL.ext.NV.h +++ b/src/libraries/glslang/SPIRV/GLSL.ext.NV.h @@ -81,4 +81,10 @@ 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"; +//SPV_NV_shader_execution_reorder +const char* const E_SPV_NV_shader_invocation_reorder = "SPV_NV_shader_invocation_reorder"; + +//SPV_NV_displacement_micromap +const char* const E_SPV_NV_displacement_micromap = "SPV_NV_displacement_micromap"; + #endif // #ifndef GLSLextNV_H diff --git a/src/libraries/glslang/SPIRV/GLSL.ext.QCOM.h b/src/libraries/glslang/SPIRV/GLSL.ext.QCOM.h new file mode 100644 index 000000000..f13bb6935 --- /dev/null +++ b/src/libraries/glslang/SPIRV/GLSL.ext.QCOM.h @@ -0,0 +1,41 @@ +/* +** Copyright (c) 2021 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 GLSLextQCOM_H +#define GLSLextQCOM_H + +enum BuiltIn; +enum Decoration; +enum Op; +enum Capability; + +static const int GLSLextQCOMVersion = 100; +static const int GLSLextQCOMRevision = 1; + +//SPV_QCOM_image_processing +const char* const E_SPV_QCOM_image_processing = "SPV_QCOM_image_processing"; + +#endif // #ifndef GLSLextQCOM_H diff --git a/src/libraries/glslang/SPIRV/GLSL.std.450.h b/src/libraries/glslang/SPIRV/GLSL.std.450.h index df31092be..86d3da806 100644 --- a/src/libraries/glslang/SPIRV/GLSL.std.450.h +++ b/src/libraries/glslang/SPIRV/GLSL.std.450.h @@ -13,7 +13,7 @@ ** ** 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/ +** 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, diff --git a/src/libraries/glslang/SPIRV/GlslangToSpv.cpp b/src/libraries/glslang/SPIRV/GlslangToSpv.cpp old mode 100644 new mode 100755 index 5f18677b5..7ef512804 --- a/src/libraries/glslang/SPIRV/GlslangToSpv.cpp +++ b/src/libraries/glslang/SPIRV/GlslangToSpv.cpp @@ -43,12 +43,15 @@ #include "spirv.hpp" #include "GlslangToSpv.h" #include "SpvBuilder.h" +#include "SpvTools.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" + #include "GLSL.ext.ARM.h" + #include "GLSL.ext.QCOM.h" #include "NonSemanticDebugPrintf.h" } @@ -64,6 +67,7 @@ namespace spv { #include #include #include +#include #include #include #include @@ -94,26 +98,18 @@ struct OpDecorations { public: OpDecorations(spv::Decoration precision, spv::Decoration noContraction, spv::Decoration nonUniform) : precision(precision) -#ifndef GLSLANG_WEB , noContraction(noContraction), nonUniform(nonUniform) -#endif { } spv::Decoration precision; -#ifdef GLSLANG_WEB - void addNoContraction(spv::Builder&, spv::Id) const { } - void addNonUniform(spv::Builder&, spv::Id) const { } -#else void addNoContraction(spv::Builder& builder, spv::Id t) { builder.addDecoration(t, noContraction); } void addNonUniform(spv::Builder& builder, spv::Id t) { builder.addDecoration(t, nonUniform); } protected: spv::Decoration noContraction; spv::Decoration nonUniform; -#endif - }; } // namespace @@ -139,7 +135,7 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { bool visitLoop(glslang::TVisit, glslang::TIntermLoop*); bool visitBranch(glslang::TVisit visit, glslang::TIntermBranch*); - void finishSpv(); + void finishSpv(bool compileOnly); void dumpSpv(std::vector& out); protected: @@ -170,12 +166,14 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { spv::Id convertGlslangToSpvType(const glslang::TType& type, bool forwardReferenceOnly = false); spv::Id convertGlslangToSpvType(const glslang::TType& type, glslang::TLayoutPacking, const glslang::TQualifier&, bool lastBufferBlockMember, bool forwardReferenceOnly = false); + void applySpirvDecorate(const glslang::TType& type, spv::Id id, std::optional member); bool filterMember(const glslang::TType& member); spv::Id convertGlslangStructToSpvType(const glslang::TType&, const glslang::TTypeList* glslangStruct, glslang::TLayoutPacking, const glslang::TQualifier&); + spv::LinkageType convertGlslangLinkageToSpv(glslang::TLinkType glslangLinkType); void decorateStructType(const glslang::TType&, const glslang::TTypeList* glslangStruct, glslang::TLayoutPacking, - const glslang::TQualifier&, spv::Id); - spv::Id makeArraySizeId(const glslang::TArraySizes&, int dim); + const glslang::TQualifier&, spv::Id, const std::vector& spvMembers); + spv::Id makeArraySizeId(const glslang::TArraySizes&, int dim, bool allowZero = false); spv::Id accessChainLoad(const glslang::TType& type); void accessChainStore(const glslang::TType& type, spv::Id rvalue); void multiTypeStore(const glslang::TType&, spv::Id rValue); @@ -211,7 +209,7 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { glslang::TBasicType typeProxy); spv::Id createConversion(glslang::TOperator op, OpDecorations&, spv::Id destTypeId, spv::Id operand, glslang::TBasicType typeProxy); - spv::Id createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize); + spv::Id createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize, spv::Id destType); spv::Id makeSmearedConstant(spv::Id constant, int vectorSize); spv::Id createAtomicOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId, std::vector& operands, glslang::TBasicType typeProxy, @@ -227,6 +225,7 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { spv::Id createNoArgOperation(glslang::TOperator op, spv::Decoration precision, spv::Id typeId); spv::Id getSymbolId(const glslang::TIntermSymbol* node); void addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier & qualifier); + void addImageProcessingQCOMDecoration(spv::Id id, spv::Decoration decor); spv::Id createSpvConstant(const glslang::TIntermTyped&); spv::Id createSpvConstantFromConstUnionArray(const glslang::TType& type, const glslang::TConstUnionArray&, int& nextConst, bool specConstant); @@ -260,6 +259,7 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { std::unordered_map extBuiltinMap; std::unordered_map symbolValues; + std::unordered_map builtInVariableIds; std::unordered_set rValueParameters; // set of formal function parameters passed as rValues, // rather than a pointer std::unordered_map functionMap; @@ -276,9 +276,10 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { // requiring local translation to and from SPIR-V type on every access. // Maps AST-required-type-id> std::unordered_map forceType; - - // Used later for generating OpTraceKHR/OpExecuteCallableKHR - std::unordered_map locationToSymbol[2]; + // Used by Task shader while generating opearnds for OpEmitMeshTasksEXT + spv::Id taskPayloadID; + // Used later for generating OpTraceKHR/OpExecuteCallableKHR/OpHitObjectRecordHit*/OpHitObjectGetShaderBindingTableData + std::unordered_map locationToSymbol[4]; }; // @@ -288,12 +289,6 @@ class TGlslangToSpvTraverser : public glslang::TIntermTraverser { // Translate glslang profile to SPIR-V source language. spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile profile) { -#ifdef GLSLANG_WEB - return spv::SourceLanguageESSL; -#elif defined(GLSLANG_ANGLE) - return spv::SourceLanguageGLSL; -#endif - switch (source) { case glslang::EShSourceGlsl: switch (profile) { @@ -314,13 +309,12 @@ spv::SourceLanguage TranslateSourceLanguage(glslang::EShSource source, EProfile } // Translate glslang language (stage) to SPIR-V execution model. -spv::ExecutionModel TranslateExecutionModel(EShLanguage stage) +spv::ExecutionModel TranslateExecutionModel(EShLanguage stage, bool isMeshShaderEXT = false) { switch (stage) { case EShLangVertex: return spv::ExecutionModelVertex; case EShLangFragment: return spv::ExecutionModelFragment; case EShLangCompute: return spv::ExecutionModelGLCompute; -#ifndef GLSLANG_WEB case EShLangTessControl: return spv::ExecutionModelTessellationControl; case EShLangTessEvaluation: return spv::ExecutionModelTessellationEvaluation; case EShLangGeometry: return spv::ExecutionModelGeometry; @@ -330,9 +324,8 @@ spv::ExecutionModel TranslateExecutionModel(EShLanguage stage) case EShLangClosestHit: return spv::ExecutionModelClosestHitKHR; case EShLangMiss: return spv::ExecutionModelMissKHR; case EShLangCallable: return spv::ExecutionModelCallableKHR; - case EShLangTaskNV: return spv::ExecutionModelTaskNV; - case EShLangMeshNV: return spv::ExecutionModelMeshNV; -#endif + case EShLangTask: return (isMeshShaderEXT)? spv::ExecutionModelTaskEXT : spv::ExecutionModelTaskNV; + case EShLangMesh: return (isMeshShaderEXT)? spv::ExecutionModelMeshEXT: spv::ExecutionModelMeshNV; default: assert(0); return spv::ExecutionModelFragment; @@ -350,6 +343,7 @@ spv::Dim TranslateDimensionality(const glslang::TSampler& sampler) case glslang::EsdRect: return spv::DimRect; case glslang::EsdBuffer: return spv::DimBuffer; case glslang::EsdSubpass: return spv::DimSubpassData; + case glslang::EsdAttachmentEXT: return spv::DimTileImageDataEXT; default: assert(0); return spv::Dim2D; @@ -374,26 +368,23 @@ spv::Decoration TranslatePrecisionDecoration(const glslang::TType& type) } // Translate glslang type to SPIR-V block decorations. -spv::Decoration TranslateBlockDecoration(const glslang::TType& type, bool useStorageBuffer) +spv::Decoration TranslateBlockDecoration(const glslang::TStorageQualifier storage, bool useStorageBuffer) { - if (type.getBasicType() == glslang::EbtBlock) { - switch (type.getQualifier().storage) { - case glslang::EvqUniform: return spv::DecorationBlock; - case glslang::EvqBuffer: return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock; - case glslang::EvqVaryingIn: return spv::DecorationBlock; - case glslang::EvqVaryingOut: return spv::DecorationBlock; - case glslang::EvqShared: return spv::DecorationBlock; -#ifndef GLSLANG_WEB - case glslang::EvqPayload: return spv::DecorationBlock; - case glslang::EvqPayloadIn: return spv::DecorationBlock; - case glslang::EvqHitAttr: return spv::DecorationBlock; - case glslang::EvqCallableData: return spv::DecorationBlock; - case glslang::EvqCallableDataIn: return spv::DecorationBlock; -#endif - default: - assert(0); - break; - } + switch (storage) { + case glslang::EvqUniform: return spv::DecorationBlock; + case glslang::EvqBuffer: return useStorageBuffer ? spv::DecorationBlock : spv::DecorationBufferBlock; + case glslang::EvqVaryingIn: return spv::DecorationBlock; + case glslang::EvqVaryingOut: return spv::DecorationBlock; + case glslang::EvqShared: return spv::DecorationBlock; + case glslang::EvqPayload: return spv::DecorationBlock; + case glslang::EvqPayloadIn: return spv::DecorationBlock; + case glslang::EvqHitAttr: return spv::DecorationBlock; + case glslang::EvqCallableData: return spv::DecorationBlock; + case glslang::EvqCallableDataIn: return spv::DecorationBlock; + case glslang::EvqHitObjectAttrNV: return spv::DecorationBlock; + default: + assert(0); + break; } return spv::DecorationMax; @@ -460,14 +451,13 @@ spv::Decoration TranslateLayoutDecoration(const glslang::TType& type, glslang::T assert(type.getQualifier().layoutPacking == glslang::ElpNone); } return spv::DecorationMax; -#ifndef GLSLANG_WEB case glslang::EvqPayload: case glslang::EvqPayloadIn: case glslang::EvqHitAttr: case glslang::EvqCallableData: case glslang::EvqCallableDataIn: + case glslang::EvqHitObjectAttrNV: return spv::DecorationMax; -#endif default: assert(0); return spv::DecorationMax; @@ -503,14 +493,12 @@ spv::Decoration TGlslangToSpvTraverser::TranslateAuxiliaryStorageDecoration(cons { if (qualifier.centroid) return spv::DecorationCentroid; -#ifndef GLSLANG_WEB else if (qualifier.patch) return spv::DecorationPatch; else if (qualifier.sample) { builder.addCapability(spv::CapabilitySampleRateShading); return spv::DecorationSample; } -#endif return spv::DecorationMax; } @@ -527,24 +515,20 @@ spv::Decoration TranslateInvariantDecoration(const glslang::TQualifier& qualifie // If glslang type is noContraction, return SPIR-V NoContraction decoration. spv::Decoration TranslateNoContractionDecoration(const glslang::TQualifier& qualifier) { -#ifndef GLSLANG_WEB if (qualifier.isNoContraction()) return spv::DecorationNoContraction; else -#endif return spv::DecorationMax; } // If glslang type is nonUniform, return SPIR-V NonUniform decoration. spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glslang::TQualifier& qualifier) { -#ifndef GLSLANG_WEB if (qualifier.isNonUniform()) { builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); builder.addCapability(spv::CapabilityShaderNonUniformEXT); return spv::DecorationNonUniformEXT; } else -#endif return spv::DecorationMax; } @@ -552,13 +536,11 @@ spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration(const glsl spv::Decoration TGlslangToSpvTraverser::TranslateNonUniformDecoration( const spv::Builder::AccessChain::CoherentFlags& coherentFlags) { -#ifndef GLSLANG_WEB if (coherentFlags.isNonUniform()) { builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); builder.addCapability(spv::CapabilityShaderNonUniformEXT); return spv::DecorationNonUniformEXT; } else -#endif return spv::DecorationMax; } @@ -567,7 +549,6 @@ spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess( { spv::MemoryAccessMask mask = spv::MemoryAccessMaskNone; -#ifndef GLSLANG_WEB if (!glslangIntermediate->usingVulkanMemoryModel() || coherentFlags.isImage) return mask; @@ -585,7 +566,6 @@ spv::MemoryAccessMask TGlslangToSpvTraverser::TranslateMemoryAccess( if (mask != spv::MemoryAccessMaskNone) { builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); } -#endif return mask; } @@ -595,7 +575,6 @@ spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands( { spv::ImageOperandsMask mask = spv::ImageOperandsMaskNone; -#ifndef GLSLANG_WEB if (!glslangIntermediate->usingVulkanMemoryModel()) return mask; @@ -613,7 +592,6 @@ spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands( if (mask != spv::ImageOperandsMaskNone) { builder.addCapability(spv::CapabilityVulkanMemoryModelKHR); } -#endif return mask; } @@ -621,7 +599,6 @@ spv::ImageOperandsMask TGlslangToSpvTraverser::TranslateImageOperands( spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCoherent(const glslang::TType& type) { spv::Builder::AccessChain::CoherentFlags flags = {}; -#ifndef GLSLANG_WEB flags.coherent = type.getQualifier().coherent; flags.devicecoherent = type.getQualifier().devicecoherent; flags.queuefamilycoherent = type.getQualifier().queuefamilycoherent; @@ -636,7 +613,6 @@ spv::Builder::AccessChain::CoherentFlags TGlslangToSpvTraverser::TranslateCohere flags.anyCoherent() || flags.volatil; flags.isImage = type.getBasicType() == glslang::EbtSampler; -#endif flags.nonUniform = type.getQualifier().nonUniform; return flags; } @@ -646,7 +622,6 @@ spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope( { spv::Scope scope = spv::ScopeMax; -#ifndef GLSLANG_WEB if (coherentFlags.volatil || coherentFlags.coherent) { // coherent defaults to Device scope in the old model, QueueFamilyKHR scope in the new model scope = glslangIntermediate->usingVulkanMemoryModel() ? spv::ScopeQueueFamilyKHR : spv::ScopeDevice; @@ -664,7 +639,6 @@ spv::Scope TGlslangToSpvTraverser::TranslateMemoryScope( if (glslangIntermediate->usingVulkanMemoryModel() && scope == spv::ScopeDevice) { builder.addCapability(spv::CapabilityVulkanMemoryModelDeviceScopeKHR); } -#endif return scope; } @@ -679,7 +653,6 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI { switch (builtIn) { case glslang::EbvPointSize: -#ifndef GLSLANG_WEB // Defer adding the capability until the built-in is actually used. if (! memberDeclaration) { switch (glslangIntermediate->getStage()) { @@ -694,7 +667,6 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI break; } } -#endif return spv::BuiltInPointSize; case glslang::EbvPosition: return spv::BuiltInPosition; @@ -715,7 +687,6 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI case glslang::EbvLocalInvocationIndex: return spv::BuiltInLocalInvocationIndex; case glslang::EbvGlobalInvocationId: return spv::BuiltInGlobalInvocationId; -#ifndef GLSLANG_WEB // These *Distance capabilities logically belong here, but if the member is declared and // then never used, consumers of SPIR-V prefer the capability not be declared. // They are now generated when used, rather than here when declared. @@ -762,7 +733,7 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI return spv::BuiltInSampleMask; case glslang::EbvLayer: - if (glslangIntermediate->getStage() == EShLangMeshNV) { + if (glslangIntermediate->getStage() == EShLangMesh) { return spv::BuiltInLayer; } if (glslangIntermediate->getStage() == EShLangGeometry || @@ -1007,6 +978,10 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI return spv::BuiltInRayTminKHR; case glslang::EbvRayTmax: return spv::BuiltInRayTmaxKHR; + case glslang::EbvCullMask: + return spv::BuiltInCullMaskKHR; + case glslang::EbvPositionFetch: + return spv::BuiltInHitTriangleVertexPositionsKHR; case glslang::EbvInstanceCustomIndex: return spv::BuiltInInstanceCustomIndexKHR; case glslang::EbvHitT: @@ -1037,6 +1012,22 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI builder.addExtension(spv::E_SPV_NV_ray_tracing_motion_blur); builder.addCapability(spv::CapabilityRayTracingMotionBlurNV); return spv::BuiltInCurrentRayTimeNV; + case glslang::EbvMicroTrianglePositionNV: + builder.addCapability(spv::CapabilityRayTracingDisplacementMicromapNV); + builder.addExtension("SPV_NV_displacement_micromap"); + return spv::BuiltInHitMicroTriangleVertexPositionsNV; + case glslang::EbvMicroTriangleBaryNV: + builder.addCapability(spv::CapabilityRayTracingDisplacementMicromapNV); + builder.addExtension("SPV_NV_displacement_micromap"); + return spv::BuiltInHitMicroTriangleVertexBarycentricsNV; + case glslang::EbvHitKindFrontFacingMicroTriangleNV: + builder.addCapability(spv::CapabilityRayTracingDisplacementMicromapNV); + builder.addExtension("SPV_NV_displacement_micromap"); + return spv::BuiltInHitKindFrontFacingMicroTriangleNV; + case glslang::EbvHitKindBackFacingMicroTriangleNV: + builder.addCapability(spv::CapabilityRayTracingDisplacementMicromapNV); + builder.addExtension("SPV_NV_displacement_micromap"); + return spv::BuiltInHitKindBackFacingMicroTriangleNV; // barycentrics case glslang::EbvBaryCoordNV: @@ -1048,6 +1039,15 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI builder.addCapability(spv::CapabilityFragmentBarycentricNV); return spv::BuiltInBaryCoordNoPerspNV; + case glslang::EbvBaryCoordEXT: + builder.addExtension(spv::E_SPV_KHR_fragment_shader_barycentric); + builder.addCapability(spv::CapabilityFragmentBarycentricKHR); + return spv::BuiltInBaryCoordKHR; + case glslang::EbvBaryCoordNoPerspEXT: + builder.addExtension(spv::E_SPV_KHR_fragment_shader_barycentric); + builder.addCapability(spv::CapabilityFragmentBarycentricKHR); + return spv::BuiltInBaryCoordNoPerspKHR; + // mesh shaders case glslang::EbvTaskCountNV: return spv::BuiltInTaskCountNV; @@ -1066,6 +1066,16 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI case glslang::EbvMeshViewIndicesNV: return spv::BuiltInMeshViewIndicesNV; + // SPV_EXT_mesh_shader + case glslang::EbvPrimitivePointIndicesEXT: + return spv::BuiltInPrimitivePointIndicesEXT; + case glslang::EbvPrimitiveLineIndicesEXT: + return spv::BuiltInPrimitiveLineIndicesEXT; + case glslang::EbvPrimitiveTriangleIndicesEXT: + return spv::BuiltInPrimitiveTriangleIndicesEXT; + case glslang::EbvCullPrimitiveEXT: + return spv::BuiltInCullPrimitiveEXT; + // sm builtins case glslang::EbvWarpsPerSM: builder.addExtension(spv::E_SPV_NV_shader_sm_builtins); @@ -1083,7 +1093,28 @@ spv::BuiltIn TGlslangToSpvTraverser::TranslateBuiltInDecoration(glslang::TBuiltI builder.addExtension(spv::E_SPV_NV_shader_sm_builtins); builder.addCapability(spv::CapabilityShaderSMBuiltinsNV); return spv::BuiltInSMIDNV; -#endif + + // ARM builtins + case glslang::EbvCoreCountARM: + builder.addExtension(spv::E_SPV_ARM_core_builtins); + builder.addCapability(spv::CapabilityCoreBuiltinsARM); + return spv::BuiltInCoreCountARM; + case glslang::EbvCoreIDARM: + builder.addExtension(spv::E_SPV_ARM_core_builtins); + builder.addCapability(spv::CapabilityCoreBuiltinsARM); + return spv::BuiltInCoreIDARM; + case glslang::EbvCoreMaxIDARM: + builder.addExtension(spv::E_SPV_ARM_core_builtins); + builder.addCapability(spv::CapabilityCoreBuiltinsARM); + return spv::BuiltInCoreMaxIDARM; + case glslang::EbvWarpIDARM: + builder.addExtension(spv::E_SPV_ARM_core_builtins); + builder.addCapability(spv::CapabilityCoreBuiltinsARM); + return spv::BuiltInWarpIDARM; + case glslang::EbvWarpMaxIDARM: + builder.addExtension(spv::E_SPV_ARM_core_builtins); + builder.addCapability(spv::CapabilityCoreBuiltinsARM); + return spv::BuiltInWarpMaxIDARM; default: return spv::BuiltInMax; @@ -1095,10 +1126,6 @@ spv::ImageFormat TGlslangToSpvTraverser::TranslateImageFormat(const glslang::TTy { assert(type.getBasicType() == glslang::EbtSampler); -#ifdef GLSLANG_WEB - return spv::ImageFormatUnknown; -#endif - // Check for capabilities switch (type.getQualifier().getFormat()) { case glslang::ElfRg32f: @@ -1253,24 +1280,27 @@ spv::LoopControlMask TGlslangToSpvTraverser::TranslateLoopControl(const glslang: // Translate glslang type to SPIR-V storage class. spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::TType& type) { - if (type.getBasicType() == glslang::EbtRayQuery) + if (type.getBasicType() == glslang::EbtRayQuery || type.getBasicType() == glslang::EbtHitObjectNV) return spv::StorageClassPrivate; -#ifndef GLSLANG_WEB if (type.getQualifier().isSpirvByReference()) { if (type.getQualifier().isParamInput() || type.getQualifier().isParamOutput()) return spv::StorageClassFunction; } -#endif if (type.getQualifier().isPipeInput()) return spv::StorageClassInput; if (type.getQualifier().isPipeOutput()) return spv::StorageClassOutput; + if (type.getQualifier().storage == glslang::EvqTileImageEXT || type.isAttachmentEXT()) { + builder.addExtension(spv::E_SPV_EXT_shader_tile_image); + builder.addCapability(spv::CapabilityTileImageColorReadAccessEXT); + return spv::StorageClassTileImageEXT; + } if (glslangIntermediate->getSource() != glslang::EShSourceHlsl || type.getQualifier().storage == glslang::EvqUniform) { if (type.isAtomic()) return spv::StorageClassAtomicCounter; - if (type.containsOpaque()) + if (type.containsOpaque() && !glslangIntermediate->getBindlessMode()) return spv::StorageClassUniformConstant; } @@ -1303,14 +1333,14 @@ spv::StorageClass TGlslangToSpvTraverser::TranslateStorageClass(const glslang::T case glslang::EvqConstReadOnly: return spv::StorageClassFunction; case glslang::EvqTemporary: return spv::StorageClassFunction; case glslang::EvqShared: return spv::StorageClassWorkgroup; -#ifndef GLSLANG_WEB case glslang::EvqPayload: return spv::StorageClassRayPayloadKHR; case glslang::EvqPayloadIn: return spv::StorageClassIncomingRayPayloadKHR; case glslang::EvqHitAttr: return spv::StorageClassHitAttributeKHR; case glslang::EvqCallableData: return spv::StorageClassCallableDataKHR; case glslang::EvqCallableDataIn: return spv::StorageClassIncomingCallableDataKHR; + case glslang::EvqtaskPayloadSharedEXT : return spv::StorageClassTaskPayloadWorkgroupEXT; + case glslang::EvqHitObjectAttrNV: return spv::StorageClassHitObjectAttributeNV; case glslang::EvqSpirvStorageClass: return static_cast(type.getQualifier().spirvStorageClass); -#endif default: assert(0); break; @@ -1326,7 +1356,9 @@ void TGlslangToSpvTraverser::TranslateLiterals(const glslang::TVectorgetBasicType() == glslang::EbtFloat) { float floatValue = static_cast(constant->getConstArray()[0].getDConst()); - unsigned literal = *reinterpret_cast(&floatValue); + unsigned literal; + static_assert(sizeof(literal) == sizeof(floatValue), "sizeof(unsigned) != sizeof(float)"); + memcpy(&literal, &floatValue, sizeof(literal)); literals.push_back(literal); } else if (constant->getBasicType() == glslang::EbtInt) { unsigned literal = constant->getConstArray()[0].getIConst(); @@ -1369,7 +1401,6 @@ void TGlslangToSpvTraverser::TranslateLiterals(const glslang::TVectorgetNanMinMaxClamp()), - nonSemanticDebugPrintf(0) + nonSemanticDebugPrintf(0), + taskPayloadID(0) { - spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage()); + bool isMeshShaderExt = (glslangIntermediate->getRequestedExtensions().find(glslang::E_GL_EXT_mesh_shader) != + glslangIntermediate->getRequestedExtensions().end()); + spv::ExecutionModel executionModel = TranslateExecutionModel(glslangIntermediate->getStage(), isMeshShaderExt); builder.clearAccessChain(); builder.setSource(TranslateSourceLanguage(glslangIntermediate->getSource(), glslangIntermediate->getProfile()), glslangIntermediate->getVersion()); - if (options.generateDebugInfo) { + if (options.emitNonSemanticShaderDebugSource) + this->options.emitNonSemanticShaderDebugInfo = true; + if (options.emitNonSemanticShaderDebugInfo) + this->options.generateDebugInfo = true; + + if (this->options.generateDebugInfo) { builder.setEmitOpLines(); builder.setSourceFile(glslangIntermediate->getSourceFile()); @@ -1545,6 +1583,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, for (auto iItr = include_txt.begin(); iItr != include_txt.end(); ++iItr) builder.addInclude(iItr->first, iItr->second); } + + builder.setEmitNonSemanticShaderDebugInfo(this->options.emitNonSemanticShaderDebugInfo); + builder.setEmitNonSemanticShaderDebugSource(this->options.emitNonSemanticShaderDebugSource); + stdBuiltins = builder.import("GLSL.std.450"); spv::AddressingModel addressingModel = spv::AddressingModelLogical; @@ -1566,8 +1608,12 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, builder.addCapability(spv::CapabilityVariablePointers); } - shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str()); - entryPoint = builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPointName().c_str()); + // If not linking, there is no entry point + if (!options.compileOnly) { + shaderEntry = builder.makeEntryPoint(glslangIntermediate->getEntryPointName().c_str()); + entryPoint = + builder.addEntryPoint(executionModel, shaderEntry, glslangIntermediate->getEntryPointName().c_str()); + } // Add the source extensions const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions(); @@ -1585,12 +1631,10 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, builder.addCapability(spv::CapabilityRayTraversalPrimitiveCullingKHR); } -#ifndef GLSLANG_WEB if (glslangIntermediate->getSubgroupUniformControlFlow()) { builder.addExtension(spv::E_SPV_KHR_subgroup_uniform_control_flow); builder.addExecutionMode(shaderEntry, spv::ExecutionModeSubgroupUniformControlFlowKHR); } -#endif unsigned int mode; switch (glslangIntermediate->getStage()) { @@ -1611,16 +1655,41 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, if (glslangIntermediate->getEarlyFragmentTests()) builder.addExecutionMode(shaderEntry, spv::ExecutionModeEarlyFragmentTests); + if (glslangIntermediate->getEarlyAndLateFragmentTestsAMD()) + { + builder.addExecutionMode(shaderEntry, spv::ExecutionModeEarlyAndLateFragmentTestsAMD); + builder.addExtension(spv::E_SPV_AMD_shader_early_and_late_fragment_tests); + } + if (glslangIntermediate->getPostDepthCoverage()) { builder.addCapability(spv::CapabilitySampleMaskPostDepthCoverage); builder.addExecutionMode(shaderEntry, spv::ExecutionModePostDepthCoverage); builder.addExtension(spv::E_SPV_KHR_post_depth_coverage); } + if (glslangIntermediate->getNonCoherentColorAttachmentReadEXT()) { + builder.addCapability(spv::CapabilityTileImageColorReadAccessEXT); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeNonCoherentColorAttachmentReadEXT); + builder.addExtension(spv::E_SPV_EXT_shader_tile_image); + } + + if (glslangIntermediate->getNonCoherentDepthAttachmentReadEXT()) { + builder.addCapability(spv::CapabilityTileImageDepthReadAccessEXT); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeNonCoherentDepthAttachmentReadEXT); + builder.addExtension(spv::E_SPV_EXT_shader_tile_image); + } + + if (glslangIntermediate->getNonCoherentStencilAttachmentReadEXT()) { + builder.addCapability(spv::CapabilityTileImageStencilReadAccessEXT); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeNonCoherentStencilAttachmentReadEXT); + builder.addExtension(spv::E_SPV_EXT_shader_tile_image); + } + if (glslangIntermediate->isDepthReplacing()) builder.addExecutionMode(shaderEntry, spv::ExecutionModeDepthReplacing); -#ifndef GLSLANG_WEB + if (glslangIntermediate->isStencilReplacing()) + builder.addExecutionMode(shaderEntry, spv::ExecutionModeStencilRefReplacingEXT); switch(glslangIntermediate->getDepth()) { case glslang::EldGreater: mode = spv::ExecutionModeDepthGreater; break; @@ -1628,6 +1697,20 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, case glslang::EldUnchanged: mode = spv::ExecutionModeDepthUnchanged; break; default: mode = spv::ExecutionModeMax; break; } + + if (mode != spv::ExecutionModeMax) + builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); + + switch (glslangIntermediate->getStencil()) { + case glslang::ElsRefUnchangedFrontAMD: mode = spv::ExecutionModeStencilRefUnchangedFrontAMD; break; + case glslang::ElsRefGreaterFrontAMD: mode = spv::ExecutionModeStencilRefGreaterFrontAMD; break; + case glslang::ElsRefLessFrontAMD: mode = spv::ExecutionModeStencilRefLessFrontAMD; break; + case glslang::ElsRefUnchangedBackAMD: mode = spv::ExecutionModeStencilRefUnchangedBackAMD; break; + case glslang::ElsRefGreaterBackAMD: mode = spv::ExecutionModeStencilRefGreaterBackAMD; break; + case glslang::ElsRefLessBackAMD: mode = spv::ExecutionModeStencilRefLessBackAMD; break; + default: mode = spv::ExecutionModeMax; break; + } + if (mode != spv::ExecutionModeMax) builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); switch (glslangIntermediate->getInterlockOrdering()) { @@ -1659,26 +1742,33 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, } builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock); } -#endif break; - case EShLangCompute: + case EShLangCompute: { builder.addCapability(spv::CapabilityShader); - if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) { - std::vector dimConstId; - for (int dim = 0; dim < 3; ++dim) { - bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet); - dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst)); - if (specConst) { - builder.addDecoration(dimConstId.back(), spv::DecorationSpecId, - glslangIntermediate->getLocalSizeSpecId(dim)); + bool needSizeId = false; + for (int dim = 0; dim < 3; ++dim) { + if ((glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet)) { + needSizeId = true; + break; } - } - builder.addExecutionModeId(shaderEntry, spv::ExecutionModeLocalSizeId, dimConstId); + } + if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6 && needSizeId) { + std::vector dimConstId; + for (int dim = 0; dim < 3; ++dim) { + bool specConst = (glslangIntermediate->getLocalSizeSpecId(dim) != glslang::TQualifier::layoutNotSet); + dimConstId.push_back(builder.makeUintConstant(glslangIntermediate->getLocalSize(dim), specConst)); + if (specConst) { + builder.addDecoration(dimConstId.back(), spv::DecorationSpecId, + glslangIntermediate->getLocalSizeSpecId(dim)); + needSizeId = true; + } + } + builder.addExecutionModeId(shaderEntry, spv::ExecutionModeLocalSizeId, dimConstId); } else { - builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0), - glslangIntermediate->getLocalSize(1), - glslangIntermediate->getLocalSize(2)); + builder.addExecutionMode(shaderEntry, spv::ExecutionModeLocalSize, glslangIntermediate->getLocalSize(0), + glslangIntermediate->getLocalSize(1), + glslangIntermediate->getLocalSize(2)); } if (glslangIntermediate->getLayoutDerivativeModeNone() == glslang::LayoutDerivativeGroupQuads) { builder.addCapability(spv::CapabilityComputeDerivativeGroupQuadsNV); @@ -1690,7 +1780,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, builder.addExtension(spv::E_SPV_NV_compute_shader_derivatives); } break; -#ifndef GLSLANG_WEB + } case EShLangTessEvaluation: case EShLangTessControl: builder.addCapability(spv::CapabilityTessellation); @@ -1766,7 +1856,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, case EShLangAnyHit: case EShLangClosestHit: case EShLangMiss: - case EShLangCallable: + case EShLangCallable: { auto& extensions = glslangIntermediate->getRequestedExtensions(); if (extensions.find("GL_NV_ray_tracing") == extensions.end()) { @@ -1777,12 +1867,27 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, builder.addCapability(spv::CapabilityRayTracingNV); builder.addExtension("SPV_NV_ray_tracing"); } + if (glslangIntermediate->getStage() != EShLangRayGen && glslangIntermediate->getStage() != EShLangCallable) { + if (extensions.find("GL_EXT_ray_cull_mask") != extensions.end()) { + builder.addCapability(spv::CapabilityRayCullMaskKHR); + builder.addExtension("SPV_KHR_ray_cull_mask"); + } + if (extensions.find("GL_EXT_ray_tracing_position_fetch") != extensions.end()) { + builder.addCapability(spv::CapabilityRayTracingPositionFetchKHR); + builder.addExtension("SPV_KHR_ray_tracing_position_fetch"); + } + } break; } - case EShLangTaskNV: - case EShLangMeshNV: - builder.addCapability(spv::CapabilityMeshShadingNV); - builder.addExtension(spv::E_SPV_NV_mesh_shader); + case EShLangTask: + case EShLangMesh: + if(isMeshShaderExt) { + builder.addCapability(spv::CapabilityMeshShadingEXT); + builder.addExtension(spv::E_SPV_EXT_mesh_shader); + } else { + builder.addCapability(spv::CapabilityMeshShadingNV); + builder.addExtension(spv::E_SPV_NV_mesh_shader); + } if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) { std::vector dimConstId; for (int dim = 0; dim < 3; ++dim) { @@ -1799,7 +1904,7 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, glslangIntermediate->getLocalSize(1), glslangIntermediate->getLocalSize(2)); } - if (glslangIntermediate->getStage() == EShLangMeshNV) { + if (glslangIntermediate->getStage() == EShLangMesh) { builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputVertices, glslangIntermediate->getVertices()); builder.addExecutionMode(shaderEntry, spv::ExecutionModeOutputPrimitivesNV, @@ -1815,13 +1920,11 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, builder.addExecutionMode(shaderEntry, (spv::ExecutionMode)mode); } break; -#endif default: break; } -#ifndef GLSLANG_WEB // // Add SPIR-V requirements (GL_EXT_spirv_intrinsics) // @@ -1866,27 +1969,29 @@ TGlslangToSpvTraverser::TGlslangToSpvTraverser(unsigned int spvVersion, builder.addExecutionModeId(shaderEntry, static_cast(modeId.first), operandIds); } } -#endif } // Finish creating SPV, after the traversal is complete. -void TGlslangToSpvTraverser::finishSpv() +void TGlslangToSpvTraverser::finishSpv(bool compileOnly) { - // Finish the entry point function - if (! entryPointTerminated) { - builder.setBuildPoint(shaderEntry->getLastBlock()); - builder.leaveFunction(); - } + // If not linking, an entry point is not expected + if (!compileOnly) { + // Finish the entry point function + if (!entryPointTerminated) { + builder.setBuildPoint(shaderEntry->getLastBlock()); + builder.leaveFunction(); + } - // finish off the entry-point SPV instruction by adding the Input/Output - for (auto it = iOSet.cbegin(); it != iOSet.cend(); ++it) - entryPoint->addIdOperand(*it); + // finish off the entry-point SPV instruction by adding the Input/Output + for (auto it = iOSet.cbegin(); it != iOSet.cend(); ++it) + entryPoint->addIdOperand(*it); + } // Add capabilities, extensions, remove unneeded decorations, etc., // based on the resulting SPIR-V. // Note: WebGPU code generation must have the opportunity to aggressively // prune unreachable merge blocks and continue targets. - builder.postProcess(); + builder.postProcess(compileOnly); } // Write the SPV into 'out'. @@ -1912,13 +2017,16 @@ void TGlslangToSpvTraverser::dumpSpv(std::vector& out) // void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) { + // We update the line information even though no code might be generated here + // This is helpful to yield correct lines for control flow instructions + builder.setLine(symbol->getLoc().line, symbol->getLoc().getFilename()); + SpecConstantOpModeGuard spec_constant_op_mode_setter(&builder); if (symbol->getType().isStruct()) glslangTypeToIdMap[symbol->getType().getStruct()] = symbol->getId(); if (symbol->getType().getQualifier().isSpecConstant()) spec_constant_op_mode_setter.turnOnSpecConstantOpMode(); - #ifdef ENABLE_HLSL // Skip symbol handling if it is string-typed if (symbol->getBasicType() == glslang::EbtString) @@ -1929,6 +2037,9 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) // Formal function parameters were mapped during makeFunctions(). spv::Id id = getSymbolId(symbol); + if (symbol->getType().getQualifier().isTaskPayload()) + taskPayloadID = id; // cache the taskPayloadID to be used it as operand for OpEmitMeshTasksEXT + if (builder.isPointer(id)) { if (!symbol->getType().getQualifier().isParamInput() && !symbol->getType().getQualifier().isParamOutput()) { @@ -1939,7 +2050,7 @@ void TGlslangToSpvTraverser::visitSymbol(glslang::TIntermSymbol* symbol) spv::StorageClass sc = builder.getStorageClass(id); // Before SPIR-V 1.4, we only want to include Input and Output. // Starting with SPIR-V 1.4, we want all globals. - if ((glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4 && builder.isGlobalStorage(id)) || + if ((glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_4 && builder.isGlobalVariable(id)) || (sc == spv::StorageClassInput || sc == spv::StorageClassOutput)) { iOSet.insert(id); } @@ -2061,6 +2172,9 @@ bool TGlslangToSpvTraverser::visitBinary(glslang::TVisit /* visit */, glslang::T node->getRight()->traverse(this); spv::Id rValue = accessChainLoad(node->getRight()->getType()); + // reset line number for assignment + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); + if (node->getOp() != glslang::EOpAssign) { // the left is also an r-value builder.setAccessChain(lValue); @@ -2425,12 +2539,15 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI spv::Id length; if (node->getOperand()->getType().isCoopMat()) { - spec_constant_op_mode_setter.turnOnSpecConstantOpMode(); - spv::Id typeId = convertGlslangToSpvType(node->getOperand()->getType()); assert(builder.isCooperativeMatrixType(typeId)); - length = builder.createCooperativeMatrixLength(typeId); + if (node->getOperand()->getType().isCoopMatKHR()) { + length = builder.createCooperativeMatrixLengthKHR(typeId); + } else { + spec_constant_op_mode_setter.turnOnSpecConstantOpMode(); + length = builder.createCooperativeMatrixLengthNV(typeId); + } } else { glslang::TIntermTyped* block = node->getOperand()->getAsBinaryNode()->getLeft(); block->traverse(this); @@ -2456,6 +2573,14 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI return false; } + // Force variable declaration - Debug Mode Only + if (node->getOp() == glslang::EOpDeclare) { + builder.clearAccessChain(); + node->getOperand()->traverse(this); + builder.clearAccessChain(); + return false; + } + // Start by evaluating the operand // Does it need a swizzle inversion? If so, evaluation is inverted; @@ -2472,14 +2597,42 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI operandNode = node->getOperand()->getAsBinaryNode()->getLeft(); else operandNode = node->getOperand(); - + operandNode->traverse(this); spv::Id operand = spv::NoResult; spv::Builder::AccessChain::CoherentFlags lvalueCoherentFlags; -#ifndef GLSLANG_WEB + const auto hitObjectOpsWithLvalue = [](glslang::TOperator op) { + switch(op) { + case glslang::EOpReorderThreadNV: + case glslang::EOpHitObjectGetCurrentTimeNV: + case glslang::EOpHitObjectGetHitKindNV: + case glslang::EOpHitObjectGetPrimitiveIndexNV: + case glslang::EOpHitObjectGetGeometryIndexNV: + case glslang::EOpHitObjectGetInstanceIdNV: + case glslang::EOpHitObjectGetInstanceCustomIndexNV: + case glslang::EOpHitObjectGetObjectRayDirectionNV: + case glslang::EOpHitObjectGetObjectRayOriginNV: + case glslang::EOpHitObjectGetWorldRayDirectionNV: + case glslang::EOpHitObjectGetWorldRayOriginNV: + case glslang::EOpHitObjectGetWorldToObjectNV: + case glslang::EOpHitObjectGetObjectToWorldNV: + case glslang::EOpHitObjectGetRayTMaxNV: + case glslang::EOpHitObjectGetRayTMinNV: + case glslang::EOpHitObjectIsEmptyNV: + case glslang::EOpHitObjectIsHitNV: + case glslang::EOpHitObjectIsMissNV: + case glslang::EOpHitObjectRecordEmptyNV: + case glslang::EOpHitObjectGetShaderBindingTableRecordIndexNV: + case glslang::EOpHitObjectGetShaderRecordBufferHandleNV: + return true; + default: + return false; + } + }; + if (node->getOp() == glslang::EOpAtomicCounterIncrement || node->getOp() == glslang::EOpAtomicCounterDecrement || node->getOp() == glslang::EOpAtomicCounter || @@ -2493,16 +2646,15 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI node->getOp() == glslang::EOpRayQueryGetIntersectionCandidateAABBOpaque || node->getOp() == glslang::EOpRayQueryTerminate || node->getOp() == glslang::EOpRayQueryConfirmIntersection || - (node->getOp() == glslang::EOpSpirvInst && operandNode->getAsTyped()->getQualifier().isSpirvByReference())) { + (node->getOp() == glslang::EOpSpirvInst && operandNode->getAsTyped()->getQualifier().isSpirvByReference()) || + hitObjectOpsWithLvalue(node->getOp())) { operand = builder.accessChainGetLValue(); // Special case l-value operands lvalueCoherentFlags = builder.getAccessChain().coherentFlags; lvalueCoherentFlags |= TranslateCoherent(operandNode->getAsTyped()->getType()); } else if (operandNode->getAsTyped()->getQualifier().isSpirvLiteral()) { // Will be translated to a literal value, make a placeholder here operand = spv::NoResult; - } else -#endif - { + } else { operand = accessChainLoad(node->getOperand()->getType()); } @@ -2520,7 +2672,6 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI result = createUnaryOperation(node->getOp(), decorations, resultType(), operand, node->getOperand()->getBasicType(), lvalueCoherentFlags); -#ifndef GLSLANG_WEB // it could be attached to a SPIR-V intruction if (!result) { if (node->getOp() == glslang::EOpSpirvInst) { @@ -2550,7 +2701,6 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI return false; // done with this node } } -#endif if (result) { if (invertedType) { @@ -2575,7 +2725,6 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI spv::Id one = 0; if (node->getBasicType() == glslang::EbtFloat) one = builder.makeFloatConstant(1.0F); -#ifndef GLSLANG_WEB else if (node->getBasicType() == glslang::EbtDouble) one = builder.makeDoubleConstant(1.0); else if (node->getBasicType() == glslang::EbtFloat16) @@ -2586,7 +2735,6 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI one = builder.makeInt16Constant(1); else if (node->getBasicType() == glslang::EbtInt64 || node->getBasicType() == glslang::EbtUint64) one = builder.makeInt64Constant(1); -#endif else one = builder.makeIntConstant(1); glslang::TOperator op; @@ -2615,7 +2763,6 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI return false; -#ifndef GLSLANG_WEB case glslang::EOpEmitStreamVertex: builder.createNoResultOp(spv::OpEmitStreamVertex, operand); return false; @@ -2628,7 +2775,12 @@ bool TGlslangToSpvTraverser::visitUnary(glslang::TVisit /* visit */, glslang::TI case glslang::EOpRayQueryConfirmIntersection: builder.createNoResultOp(spv::OpRayQueryConfirmIntersectionKHR, operand); return false; -#endif + case glslang::EOpReorderThreadNV: + builder.createNoResultOp(spv::OpReorderThreadWithHitObjectNV, operand); + return false; + case glslang::EOpHitObjectRecordEmptyNV: + builder.createNoResultOp(spv::OpHitObjectRecordEmptyNV, operand); + return false; default: logger->missingFunctionality("unknown glslang unary"); @@ -2693,15 +2845,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt builder.setAccessChainRValue(result); return false; - } -#ifndef GLSLANG_WEB - else if (node->getOp() == glslang::EOpImageStore || + } else if (node->getOp() == glslang::EOpImageStore || node->getOp() == glslang::EOpImageStoreLod || node->getOp() == glslang::EOpImageAtomicStore) { // "imageStore" is a special case, which has no result return false; } -#endif glslang::TOperator binOp = glslang::EOpNull; bool reduceComparison = true; @@ -2716,32 +2865,41 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt spv::Decoration precision = TranslatePrecisionDecoration(node->getOperationPrecision()); switch (node->getOp()) { + case glslang::EOpScope: case glslang::EOpSequence: { - if (preVisit) + if (visit == glslang::EvPreVisit) { ++sequenceDepth; - else - --sequenceDepth; - - if (sequenceDepth == 1) { - // If this is the parent node of all the functions, we want to see them - // early, so all call points have actual SPIR-V functions to reference. - // In all cases, still let the traverser visit the children for us. - makeFunctions(node->getAsAggregate()->getSequence()); - - // Also, we want all globals initializers to go into the beginning of the entry point, before - // anything else gets there, so visit out of order, doing them all now. - makeGlobalInitializers(node->getAsAggregate()->getSequence()); + if (sequenceDepth == 1) { + // If this is the parent node of all the functions, we want to see them + // early, so all call points have actual SPIR-V functions to reference. + // In all cases, still let the traverser visit the children for us. + makeFunctions(node->getAsAggregate()->getSequence()); + + // Global initializers is specific to the shader entry point, which does not exist in compile-only mode + if (!options.compileOnly) { + // Also, we want all globals initializers to go into the beginning of the entry point, before + // anything else gets there, so visit out of order, doing them all now. + makeGlobalInitializers(node->getAsAggregate()->getSequence()); + } - //Pre process linker objects for ray tracing stages - if (glslangIntermediate->isRayTracingStage()) - collectRayTracingLinkerObjects(); + //Pre process linker objects for ray tracing stages + if (glslangIntermediate->isRayTracingStage()) + collectRayTracingLinkerObjects(); - // Initializers are done, don't want to visit again, but functions and link objects need to be processed, - // so do them manually. - visitFunctions(node->getAsAggregate()->getSequence()); + // Initializers are done, don't want to visit again, but functions and link objects need to be processed, + // so do them manually. + visitFunctions(node->getAsAggregate()->getSequence()); - return false; + return false; + } else { + if (node->getOp() == glslang::EOpScope) + builder.enterScope(0); + } + } else { + if (sequenceDepth > 1 && node->getOp() == glslang::EOpScope) + builder.leaveScope(); + --sequenceDepth; } return true; @@ -2770,10 +2928,17 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt if (isShaderEntryPoint(node)) { inEntryPoint = true; builder.setBuildPoint(shaderEntry->getLastBlock()); + builder.enterFunction(shaderEntry); currentFunction = shaderEntry; } else { handleFunctionEntry(node); } + if (options.generateDebugInfo) { + const auto& loc = node->getLoc(); + const char* sourceFileName = loc.getFilename(); + spv::Id sourceFileId = sourceFileName ? builder.getStringId(sourceFileName) : builder.getSourceFile(); + currentFunction->setDebugLineInfo(sourceFileId, loc.line, loc.column); + } } else { if (inEntryPoint) entryPointTerminated = true; @@ -2907,16 +3072,26 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt case glslang::EOpConstructStruct: case glslang::EOpConstructTextureSampler: case glslang::EOpConstructReference: - case glslang::EOpConstructCooperativeMatrix: + case glslang::EOpConstructCooperativeMatrixNV: + case glslang::EOpConstructCooperativeMatrixKHR: { builder.setLine(node->getLoc().line, node->getLoc().getFilename()); std::vector arguments; translateArguments(*node, arguments, lvalueCoherentFlags); spv::Id constructed; - if (node->getOp() == glslang::EOpConstructTextureSampler) - constructed = builder.createOp(spv::OpSampledImage, resultType(), arguments); - else if (node->getOp() == glslang::EOpConstructStruct || - node->getOp() == glslang::EOpConstructCooperativeMatrix || + if (node->getOp() == glslang::EOpConstructTextureSampler) { + const glslang::TType& texType = node->getSequence()[0]->getAsTyped()->getType(); + if (glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6 && + texType.getSampler().isBuffer()) { + // SamplerBuffer is not supported in spirv1.6 so + // `samplerBuffer(textureBuffer, sampler)` is a no-op + // and textureBuffer is the result going forward + constructed = arguments[0]; + } else + constructed = builder.createOp(spv::OpSampledImage, resultType(), arguments); + } else if (node->getOp() == glslang::EOpConstructStruct || + node->getOp() == glslang::EOpConstructCooperativeMatrixNV || + node->getOp() == glslang::EOpConstructCooperativeMatrixKHR || node->getType().isArray()) { std::vector constituents; for (int c = 0; c < (int)arguments.size(); ++c) @@ -3014,7 +3189,6 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt atomic = true; break; -#ifndef GLSLANG_WEB case glslang::EOpAtomicStore: noReturnValue = true; // fallthrough @@ -3055,6 +3229,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt case glslang::EOpExecuteCallableNV: case glslang::EOpExecuteCallableKHR: case glslang::EOpWritePackedPrimitiveIndices4x8NV: + case glslang::EOpEmitMeshTasksEXT: + case glslang::EOpSetMeshOutputsEXT: noReturnValue = true; break; case glslang::EOpRayQueryInitialize: @@ -3089,6 +3265,8 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt break; case glslang::EOpCooperativeMatrixLoad: case glslang::EOpCooperativeMatrixStore: + case glslang::EOpCooperativeMatrixLoadNV: + case glslang::EOpCooperativeMatrixStoreNV: noReturnValue = true; break; case glslang::EOpBeginInvocationInterlock: @@ -3096,7 +3274,68 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt builder.addExtension(spv::E_SPV_EXT_fragment_shader_interlock); noReturnValue = true; break; -#endif + + case glslang::EOpHitObjectTraceRayNV: + case glslang::EOpHitObjectTraceRayMotionNV: + case glslang::EOpHitObjectGetAttributesNV: + case glslang::EOpHitObjectExecuteShaderNV: + case glslang::EOpHitObjectRecordEmptyNV: + case glslang::EOpHitObjectRecordMissNV: + case glslang::EOpHitObjectRecordMissMotionNV: + case glslang::EOpHitObjectRecordHitNV: + case glslang::EOpHitObjectRecordHitMotionNV: + case glslang::EOpHitObjectRecordHitWithIndexNV: + case glslang::EOpHitObjectRecordHitWithIndexMotionNV: + case glslang::EOpReorderThreadNV: + noReturnValue = true; + //Fallthrough + case glslang::EOpHitObjectIsEmptyNV: + case glslang::EOpHitObjectIsMissNV: + case glslang::EOpHitObjectIsHitNV: + case glslang::EOpHitObjectGetRayTMinNV: + case glslang::EOpHitObjectGetRayTMaxNV: + case glslang::EOpHitObjectGetObjectRayOriginNV: + case glslang::EOpHitObjectGetObjectRayDirectionNV: + case glslang::EOpHitObjectGetWorldRayOriginNV: + case glslang::EOpHitObjectGetWorldRayDirectionNV: + case glslang::EOpHitObjectGetObjectToWorldNV: + case glslang::EOpHitObjectGetWorldToObjectNV: + case glslang::EOpHitObjectGetInstanceCustomIndexNV: + case glslang::EOpHitObjectGetInstanceIdNV: + case glslang::EOpHitObjectGetGeometryIndexNV: + case glslang::EOpHitObjectGetPrimitiveIndexNV: + case glslang::EOpHitObjectGetHitKindNV: + case glslang::EOpHitObjectGetCurrentTimeNV: + case glslang::EOpHitObjectGetShaderBindingTableRecordIndexNV: + case glslang::EOpHitObjectGetShaderRecordBufferHandleNV: + builder.addExtension(spv::E_SPV_NV_shader_invocation_reorder); + builder.addCapability(spv::CapabilityShaderInvocationReorderNV); + break; + case glslang::EOpRayQueryGetIntersectionTriangleVertexPositionsEXT: + builder.addExtension(spv::E_SPV_KHR_ray_tracing_position_fetch); + builder.addCapability(spv::CapabilityRayQueryPositionFetchKHR); + noReturnValue = true; + break; + + case glslang::EOpImageSampleWeightedQCOM: + builder.addCapability(spv::CapabilityTextureSampleWeightedQCOM); + builder.addExtension(spv::E_SPV_QCOM_image_processing); + break; + case glslang::EOpImageBoxFilterQCOM: + builder.addCapability(spv::CapabilityTextureBoxFilterQCOM); + builder.addExtension(spv::E_SPV_QCOM_image_processing); + break; + case glslang::EOpImageBlockMatchSADQCOM: + case glslang::EOpImageBlockMatchSSDQCOM: + builder.addCapability(spv::CapabilityTextureBlockMatchQCOM); + builder.addExtension(spv::E_SPV_QCOM_image_processing); + break; + + case glslang::EOpFetchMicroTriangleVertexPositionNV: + case glslang::EOpFetchMicroTriangleVertexBarycentricNV: + builder.addExtension(spv::E_SPV_NV_displacement_micromap); + builder.addCapability(spv::CapabilityDisplacementMicromapNV); + break; case glslang::EOpDebugPrintf: noReturnValue = true; @@ -3153,6 +3392,22 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt lvalue = true; break; + + + case glslang::EOpHitObjectRecordHitNV: + case glslang::EOpHitObjectRecordHitMotionNV: + case glslang::EOpHitObjectRecordHitWithIndexNV: + case glslang::EOpHitObjectRecordHitWithIndexMotionNV: + case glslang::EOpHitObjectTraceRayNV: + case glslang::EOpHitObjectTraceRayMotionNV: + case glslang::EOpHitObjectExecuteShaderNV: + case glslang::EOpHitObjectRecordMissNV: + case glslang::EOpHitObjectRecordMissMotionNV: + case glslang::EOpHitObjectGetAttributesNV: + if (arg == 0) + lvalue = true; + break; + case glslang::EOpRayQueryInitialize: case glslang::EOpRayQueryTerminate: case glslang::EOpRayQueryConfirmIntersection: @@ -3188,7 +3443,6 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt lvalue = true; break; -#ifndef GLSLANG_WEB case glslang::EOpFrexp: if (arg == 1) lvalue = true; @@ -3242,10 +3496,12 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt lvalue = true; break; case glslang::EOpCooperativeMatrixLoad: + case glslang::EOpCooperativeMatrixLoadNV: if (arg == 0 || arg == 1) lvalue = true; break; case glslang::EOpCooperativeMatrixStore: + case glslang::EOpCooperativeMatrixStoreNV: if (arg == 1) lvalue = true; break; @@ -3253,7 +3509,15 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvByReference()) lvalue = true; break; -#endif + case glslang::EOpReorderThreadNV: + //Three variants of reorderThreadNV, two of them use hitObjectNV + if (arg == 0 && glslangOperands.size() != 2) + lvalue = true; + break; + case glslang::EOpRayQueryGetIntersectionTriangleVertexPositionsEXT: + if (arg == 0 || arg == 2) + lvalue = true; + break; default: break; } @@ -3263,9 +3527,10 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt else glslangOperands[arg]->traverse(this); -#ifndef GLSLANG_WEB if (node->getOp() == glslang::EOpCooperativeMatrixLoad || - node->getOp() == glslang::EOpCooperativeMatrixStore) { + node->getOp() == glslang::EOpCooperativeMatrixStore || + node->getOp() == glslang::EOpCooperativeMatrixLoadNV || + node->getOp() == glslang::EOpCooperativeMatrixStoreNV) { if (arg == 1) { // fold "element" parameter into the access chain @@ -3286,9 +3551,11 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt unsigned int alignment = builder.getAccessChain().alignment; int memoryAccess = TranslateMemoryAccess(coherentFlags); - if (node->getOp() == glslang::EOpCooperativeMatrixLoad) + if (node->getOp() == glslang::EOpCooperativeMatrixLoad || + node->getOp() == glslang::EOpCooperativeMatrixLoadNV) memoryAccess &= ~spv::MemoryAccessMakePointerAvailableKHRMask; - if (node->getOp() == glslang::EOpCooperativeMatrixStore) + if (node->getOp() == glslang::EOpCooperativeMatrixStore || + node->getOp() == glslang::EOpCooperativeMatrixStoreNV) memoryAccess &= ~spv::MemoryAccessMakePointerVisibleKHRMask; if (builder.getStorageClass(builder.getAccessChain().base) == spv::StorageClassPhysicalStorageBufferEXT) { @@ -3310,7 +3577,6 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt continue; } } -#endif // for l-values, pass the address, for r-values, pass the value if (lvalue) { @@ -3345,26 +3611,37 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt glslangOp == glslang::EOpRayQueryGetIntersectionObjectRayDirection || glslangOp == glslang::EOpRayQueryGetIntersectionObjectRayOrigin || glslangOp == glslang::EOpRayQueryGetIntersectionObjectToWorld || - glslangOp == glslang::EOpRayQueryGetIntersectionWorldToObject + glslangOp == glslang::EOpRayQueryGetIntersectionWorldToObject || + glslangOp == glslang::EOpRayQueryGetIntersectionTriangleVertexPositionsEXT )) { bool cond = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getBConst(); operands.push_back(builder.makeIntConstant(cond ? 1 : 0)); } else if ((arg == 10 && glslangOp == glslang::EOpTraceKHR) || (arg == 11 && glslangOp == glslang::EOpTraceRayMotionNV) || - (arg == 1 && glslangOp == glslang::EOpExecuteCallableKHR)) { - const int opdNum = glslangOp == glslang::EOpTraceKHR ? 10 : (glslangOp == glslang::EOpTraceRayMotionNV ? 11 : 1); + (arg == 1 && glslangOp == glslang::EOpExecuteCallableKHR) || + (arg == 1 && glslangOp == glslang::EOpHitObjectExecuteShaderNV) || + (arg == 11 && glslangOp == glslang::EOpHitObjectTraceRayNV) || + (arg == 12 && glslangOp == glslang::EOpHitObjectTraceRayMotionNV)) { const int set = glslangOp == glslang::EOpExecuteCallableKHR ? 1 : 0; - - const int location = glslangOperands[opdNum]->getAsConstantUnion()->getConstArray()[0].getUConst(); + const int location = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getUConst(); + auto itNode = locationToSymbol[set].find(location); + visitSymbol(itNode->second); + spv::Id symId = getSymbolId(itNode->second); + operands.push_back(symId); + } else if ((arg == 12 && glslangOp == glslang::EOpHitObjectRecordHitNV) || + (arg == 13 && glslangOp == glslang::EOpHitObjectRecordHitMotionNV) || + (arg == 11 && glslangOp == glslang::EOpHitObjectRecordHitWithIndexNV) || + (arg == 12 && glslangOp == glslang::EOpHitObjectRecordHitWithIndexMotionNV) || + (arg == 1 && glslangOp == glslang::EOpHitObjectGetAttributesNV)) { + const int location = glslangOperands[arg]->getAsConstantUnion()->getConstArray()[0].getUConst(); + const int set = 2; auto itNode = locationToSymbol[set].find(location); visitSymbol(itNode->second); spv::Id symId = getSymbolId(itNode->second); operands.push_back(symId); -#ifndef GLSLANG_WEB } else if (glslangOperands[arg]->getAsTyped()->getQualifier().isSpirvLiteral()) { // Will be translated to a literal value, make a placeholder here operands.push_back(spv::NoResult); -#endif } else { operands.push_back(accessChainLoad(glslangOperands[arg]->getAsTyped()->getType())); } @@ -3372,42 +3649,97 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt } builder.setLine(node->getLoc().line, node->getLoc().getFilename()); -#ifndef GLSLANG_WEB - if (node->getOp() == glslang::EOpCooperativeMatrixLoad) { + if (node->getOp() == glslang::EOpCooperativeMatrixLoad || + node->getOp() == glslang::EOpCooperativeMatrixLoadNV) { std::vector idImmOps; idImmOps.push_back(spv::IdImmediate(true, operands[1])); // buf - idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride - idImmOps.push_back(spv::IdImmediate(true, operands[3])); // colMajor + if (node->getOp() == glslang::EOpCooperativeMatrixLoad) { + idImmOps.push_back(spv::IdImmediate(true, operands[3])); // matrixLayout + idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride + } else { + idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride + idImmOps.push_back(spv::IdImmediate(true, operands[3])); // colMajor + } idImmOps.insert(idImmOps.end(), memoryAccessOperands.begin(), memoryAccessOperands.end()); // get the pointee type spv::Id typeId = builder.getContainedTypeId(builder.getTypeId(operands[0])); assert(builder.isCooperativeMatrixType(typeId)); // do the op - spv::Id result = builder.createOp(spv::OpCooperativeMatrixLoadNV, typeId, idImmOps); + spv::Id result = node->getOp() == glslang::EOpCooperativeMatrixLoad + ? builder.createOp(spv::OpCooperativeMatrixLoadKHR, typeId, idImmOps) + : builder.createOp(spv::OpCooperativeMatrixLoadNV, typeId, idImmOps); // store the result to the pointer (out param 'm') builder.createStore(result, operands[0]); result = 0; - } else if (node->getOp() == glslang::EOpCooperativeMatrixStore) { + } else if (node->getOp() == glslang::EOpCooperativeMatrixStore || + node->getOp() == glslang::EOpCooperativeMatrixStoreNV) { std::vector idImmOps; idImmOps.push_back(spv::IdImmediate(true, operands[1])); // buf idImmOps.push_back(spv::IdImmediate(true, operands[0])); // object - idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride - idImmOps.push_back(spv::IdImmediate(true, operands[3])); // colMajor + if (node->getOp() == glslang::EOpCooperativeMatrixStore) { + idImmOps.push_back(spv::IdImmediate(true, operands[3])); // matrixLayout + idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride + } else { + idImmOps.push_back(spv::IdImmediate(true, operands[2])); // stride + idImmOps.push_back(spv::IdImmediate(true, operands[3])); // colMajor + } idImmOps.insert(idImmOps.end(), memoryAccessOperands.begin(), memoryAccessOperands.end()); - builder.createNoResultOp(spv::OpCooperativeMatrixStoreNV, idImmOps); + if (node->getOp() == glslang::EOpCooperativeMatrixStore) + builder.createNoResultOp(spv::OpCooperativeMatrixStoreKHR, idImmOps); + else + builder.createNoResultOp(spv::OpCooperativeMatrixStoreNV, idImmOps); + result = 0; + } else if (node->getOp() == glslang::EOpRayQueryGetIntersectionTriangleVertexPositionsEXT) { + std::vector idImmOps; + + idImmOps.push_back(spv::IdImmediate(true, operands[0])); // q + idImmOps.push_back(spv::IdImmediate(true, operands[1])); // committed + + spv::Id typeId = builder.makeArrayType(builder.makeVectorType(builder.makeFloatType(32), 3), + builder.makeUintConstant(3), 0); + // do the op + + spv::Op spvOp = spv::OpRayQueryGetIntersectionTriangleVertexPositionsKHR; + + spv::Id result = builder.createOp(spvOp, typeId, idImmOps); + // store the result to the pointer (out param 'm') + builder.createStore(result, operands[2]); result = 0; - } else -#endif - if (atomic) { + } else if (node->getOp() == glslang::EOpCooperativeMatrixMulAdd) { + uint32_t matrixOperands = 0; + + // If the optional operand is present, initialize matrixOperands to that value. + if (glslangOperands.size() == 4 && glslangOperands[3]->getAsConstantUnion()) { + matrixOperands = glslangOperands[3]->getAsConstantUnion()->getConstArray()[0].getIConst(); + } + + // Determine Cooperative Matrix Operands bits from the signedness of the types. + if (isTypeSignedInt(glslangOperands[0]->getAsTyped()->getBasicType())) + matrixOperands |= spv::CooperativeMatrixOperandsMatrixASignedComponentsKHRMask; + if (isTypeSignedInt(glslangOperands[1]->getAsTyped()->getBasicType())) + matrixOperands |= spv::CooperativeMatrixOperandsMatrixBSignedComponentsKHRMask; + if (isTypeSignedInt(glslangOperands[2]->getAsTyped()->getBasicType())) + matrixOperands |= spv::CooperativeMatrixOperandsMatrixCSignedComponentsKHRMask; + if (isTypeSignedInt(node->getBasicType())) + matrixOperands |= spv::CooperativeMatrixOperandsMatrixResultSignedComponentsKHRMask; + + std::vector idImmOps; + idImmOps.push_back(spv::IdImmediate(true, operands[0])); + idImmOps.push_back(spv::IdImmediate(true, operands[1])); + idImmOps.push_back(spv::IdImmediate(true, operands[2])); + if (matrixOperands != 0) + idImmOps.push_back(spv::IdImmediate(false, matrixOperands)); + + result = builder.createOp(spv::OpCooperativeMatrixMulAddKHR, resultType(), idImmOps); + } else if (atomic) { // Handle all atomics glslang::TBasicType typeProxy = (node->getOp() == glslang::EOpAtomicStore) ? node->getSequence()[0]->getAsTyped()->getBasicType() : node->getBasicType(); result = createAtomicOperation(node->getOp(), precision, resultType(), operands, typeProxy, lvalueCoherentFlags); -#ifndef GLSLANG_WEB } else if (node->getOp() == glslang::EOpSpirvInst) { const auto& spirvInst = node->getSpirvInstruction(); if (spirvInst.set == "") { @@ -3434,7 +3766,6 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt spirvInst.id, operands); } noReturnValue = node->getBasicType() == glslang::EbtVoid; -#endif } else if (node->getOp() == glslang::EOpDebugPrintf) { if (!nonSemanticDebugPrintf) { nonSemanticDebugPrintf = builder.import("NonSemantic.DebugPrintf"); @@ -3449,7 +3780,7 @@ bool TGlslangToSpvTraverser::visitAggregate(glslang::TVisit visit, glslang::TInt break; case 1: { - OpDecorations decorations = { precision, + OpDecorations decorations = { precision, TranslateNoContractionDecoration(node->getType().getQualifier()), TranslateNonUniformDecoration(node->getType().getQualifier()) }; result = createUnaryOperation( @@ -3551,10 +3882,11 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang // Find a way of executing both sides and selecting the right result. const auto executeBothSides = [&]() -> void { // execute both sides + spv::Id resultType = convertGlslangToSpvType(node->getType()); node->getTrueBlock()->traverse(this); spv::Id trueValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType()); node->getFalseBlock()->traverse(this); - spv::Id falseValue = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType()); + spv::Id falseValue = accessChainLoad(node->getFalseBlock()->getAsTyped()->getType()); builder.setLine(node->getLoc().line, node->getLoc().getFilename()); @@ -3563,23 +3895,31 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang return; // emit code to select between trueValue and falseValue - - // see if OpSelect can handle it + // see if OpSelect can handle the result type, and that the SPIR-V types + // of the inputs match the result type. if (isOpSelectable()) { // Emit OpSelect for this selection. // smear condition to vector, if necessary (AST is always scalar) // Before 1.4, smear like for mix(), starting with 1.4, keep it scalar if (glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_4 && builder.isVector(trueValue)) { - condition = builder.smearScalar(spv::NoPrecision, condition, + condition = builder.smearScalar(spv::NoPrecision, condition, builder.makeVectorType(builder.makeBoolType(), builder.getNumComponents(trueValue))); } + // If the types do not match, it is because of mismatched decorations on aggregates. + // Since isOpSelectable only lets us get here for SPIR-V >= 1.4, we can use OpCopyObject + // to get matching types. + if (builder.getTypeId(trueValue) != resultType) { + trueValue = builder.createUnaryOp(spv::OpCopyLogical, resultType, trueValue); + } + if (builder.getTypeId(falseValue) != resultType) { + falseValue = builder.createUnaryOp(spv::OpCopyLogical, resultType, falseValue); + } + // OpSelect - result = builder.createTriOp(spv::OpSelect, - convertGlslangToSpvType(node->getType()), condition, - trueValue, falseValue); + result = builder.createTriOp(spv::OpSelect, resultType, condition, trueValue, falseValue); builder.clearAccessChain(); builder.setAccessChainRValue(result); @@ -3587,7 +3927,7 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang // We need control flow to select the result. // TODO: Once SPIR-V OpSelect allows arbitrary types, eliminate this path. result = builder.createVariable(TranslatePrecisionDecoration(node->getType()), - spv::StorageClassFunction, convertGlslangToSpvType(node->getType())); + spv::StorageClassFunction, resultType); // Selection control: const spv::SelectionControlMask control = TranslateSelectionControl(*node); @@ -3596,10 +3936,15 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang spv::Builder::If ifBuilder(condition, control, builder); // emit the "then" statement - builder.createStore(trueValue, result); + builder.clearAccessChain(); + builder.setAccessChainLValue(result); + multiTypeStore(node->getType(), trueValue); + ifBuilder.makeBeginElse(); // emit the "else" statement - builder.createStore(falseValue, result); + builder.clearAccessChain(); + builder.setAccessChainLValue(result); + multiTypeStore(node->getType(), falseValue); // finish off the control flow ifBuilder.makeEndIf(); @@ -3626,16 +3971,26 @@ bool TGlslangToSpvTraverser::visitSelection(glslang::TVisit /* visit */, glslang // emit the "then" statement if (node->getTrueBlock() != nullptr) { node->getTrueBlock()->traverse(this); - if (result != spv::NoResult) - builder.createStore(accessChainLoad(node->getTrueBlock()->getAsTyped()->getType()), result); + if (result != spv::NoResult) { + spv::Id load = accessChainLoad(node->getTrueBlock()->getAsTyped()->getType()); + + builder.clearAccessChain(); + builder.setAccessChainLValue(result); + multiTypeStore(node->getType(), load); + } } if (node->getFalseBlock() != nullptr) { ifBuilder.makeBeginElse(); // emit the "else" statement node->getFalseBlock()->traverse(this); - if (result != spv::NoResult) - builder.createStore(accessChainLoad(node->getFalseBlock()->getAsTyped()->getType()), result); + if (result != spv::NoResult) { + spv::Id load = accessChainLoad(node->getFalseBlock()->getAsTyped()->getType()); + + builder.clearAccessChain(); + builder.setAccessChainLValue(result); + multiTypeStore(node->getType(), load); + } } // finish off the control flow @@ -3715,10 +4070,8 @@ bool TGlslangToSpvTraverser::visitSwitch(glslang::TVisit /* visit */, glslang::T void TGlslangToSpvTraverser::visitConstantUnion(glslang::TIntermConstantUnion* node) { -#ifndef GLSLANG_WEB if (node->getQualifier().isSpirvLiteral()) return; // Translated to a literal value, skip further processing -#endif int nextConst = 0; spv::Id constant = createSpvConstantFromConstUnionArray(node->getType(), node->getConstArray(), nextConst, false); @@ -3742,8 +4095,8 @@ bool TGlslangToSpvTraverser::visitLoop(glslang::TVisit /* visit */, glslang::TIn // by a block-ending branch. But we don't want to put any other body/test // instructions in it, since the body/test may have arbitrary instructions, // including merges of its own. - builder.setLine(node->getLoc().line, node->getLoc().getFilename()); builder.setBuildPoint(&blocks.head); + builder.setLine(node->getLoc().line, node->getLoc().getFilename()); builder.createLoopMerge(&blocks.merge, &blocks.continue_target, control, operands); if (node->testFirst() && node->getTest()) { spv::Block& test = builder.makeNewBlock(); @@ -3849,7 +4202,6 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T builder.clearAccessChain(); break; -#ifndef GLSLANG_WEB case glslang::EOpDemote: builder.createNoResultOp(spv::OpDemoteToHelperInvocationEXT); builder.addExtension(spv::E_SPV_EXT_demote_to_helper_invocation); @@ -3861,7 +4213,6 @@ bool TGlslangToSpvTraverser::visitBranch(glslang::TVisit /* visit */, glslang::T case glslang::EOpIgnoreIntersectionKHR: builder.makeStatementTerminator(spv::OpIgnoreIntersectionKHR, "post-ignoreIntersectionKHR"); break; -#endif default: assert(0); @@ -3903,7 +4254,6 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* else builder.addCapability(spv::CapabilityStorageUniform16); break; -#ifndef GLSLANG_WEB case spv::StorageClassPushConstant: builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3); builder.addCapability(spv::CapabilityStoragePushConstant16); @@ -3913,7 +4263,6 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* builder.addIncorporatedExtension(spv::E_SPV_KHR_16bit_storage, spv::Spv_1_3); builder.addCapability(spv::CapabilityStorageUniformBufferBlock16); break; -#endif default: if (storageClass == spv::StorageClassWorkgroup && node->getType().getBasicType() == glslang::EbtBlock) { @@ -3962,7 +4311,7 @@ spv::Id TGlslangToSpvTraverser::createSpvVariable(const glslang::TIntermSymbol* initializer = builder.makeNullConstant(spvType); } - return builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer); + return builder.createVariable(spv::NoPrecision, storageClass, spvType, name, initializer, false); } // Return type Id of the sampled type. @@ -3972,7 +4321,6 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler) case glslang::EbtInt: return builder.makeIntType(32); case glslang::EbtUint: return builder.makeUintType(32); case glslang::EbtFloat: return builder.makeFloatType(32); -#ifndef GLSLANG_WEB case glslang::EbtFloat16: builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float_fetch); builder.addCapability(spv::CapabilityFloat16ImageAMD); @@ -3985,7 +4333,6 @@ spv::Id TGlslangToSpvTraverser::getSampledType(const glslang::TSampler& sampler) builder.addExtension(spv::E_SPV_EXT_shader_image_int64); builder.addCapability(spv::CapabilityInt64ImageEXT); return builder.makeUintType(64); -#endif default: assert(0); return builder.makeFloatType(32); @@ -4030,6 +4377,16 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty return convertGlslangToSpvType(type, getExplicitLayout(type), type.getQualifier(), false, forwardReferenceOnly); } +spv::LinkageType TGlslangToSpvTraverser::convertGlslangLinkageToSpv(glslang::TLinkType linkType) +{ + switch (linkType) { + case glslang::ELinkExport: + return spv::LinkageTypeExport; + default: + return spv::LinkageTypeMax; + } +} + // Do full recursive conversion of an arbitrary glslang type to a SPIR-V Id. // explicitLayout can be kept the same throughout the hierarchical recursive walk. // Mutually recursive with convertGlslangStructToSpvType(). @@ -4061,7 +4418,6 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty case glslang::EbtFloat: spvType = builder.makeFloatType(32); break; -#ifndef GLSLANG_WEB case glslang::EbtDouble: spvType = builder.makeFloatType(64); break; @@ -4139,7 +4495,6 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty } } break; -#endif case glslang::EbtSampler: { const glslang::TSampler& sampler = type.getSampler(); @@ -4150,8 +4505,10 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty spvType = builder.makeImageType(getSampledType(sampler), TranslateDimensionality(sampler), sampler.isShadow(), sampler.isArrayed(), sampler.isMultiSample(), sampler.isImageClass() ? 2 : 1, TranslateImageFormat(type)); - if (sampler.isCombined()) { - // already has both image and sampler, make the combined type + if (sampler.isCombined() && + (!sampler.isBuffer() || glslangIntermediate->getSpv().spv < glslang::EShTargetSpv_1_6)) { + // Already has both image and sampler, make the combined type. Only combine sampler to + // buffer if before SPIR-V 1.6. spvType = builder.makeSampledImageType(spvType); } } @@ -4179,7 +4536,13 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty case glslang::EbtString: // no type used for OpString return 0; -#ifndef GLSLANG_WEB + + case glslang::EbtHitObjectNV: { + builder.addExtension(spv::E_SPV_NV_shader_invocation_reorder); + builder.addCapability(spv::CapabilityShaderInvocationReorderNV); + spvType = builder.makeHitObjectNVType(); + } + break; case glslang::EbtSpirvType: { // GL_EXT_spirv_intrinsics const auto& spirvType = type.getSpirvType(); @@ -4187,48 +4550,57 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty std::vector operands; for (const auto& typeParam : spirvType.typeParams) { - // Constant expression - if (typeParam.constant->isLiteral()) { - if (typeParam.constant->getBasicType() == glslang::EbtFloat) { - float floatValue = static_cast(typeParam.constant->getConstArray()[0].getDConst()); - unsigned literal = *reinterpret_cast(&floatValue); - operands.push_back({false, literal}); - } else if (typeParam.constant->getBasicType() == glslang::EbtInt) { - unsigned literal = typeParam.constant->getConstArray()[0].getIConst(); - operands.push_back({false, literal}); - } else if (typeParam.constant->getBasicType() == glslang::EbtUint) { - unsigned literal = typeParam.constant->getConstArray()[0].getUConst(); - operands.push_back({false, literal}); - } else if (typeParam.constant->getBasicType() == glslang::EbtBool) { - unsigned literal = typeParam.constant->getConstArray()[0].getBConst(); - operands.push_back({false, literal}); - } else if (typeParam.constant->getBasicType() == glslang::EbtString) { - auto str = typeParam.constant->getConstArray()[0].getSConst()->c_str(); - unsigned literal = 0; - char* literalPtr = reinterpret_cast(&literal); - unsigned charCount = 0; - char ch = 0; - do { - ch = *(str++); - *(literalPtr++) = ch; - ++charCount; - if (charCount == 4) { + if (typeParam.getAsConstant() != nullptr) { + // Constant expression + auto constant = typeParam.getAsConstant(); + if (constant->isLiteral()) { + if (constant->getBasicType() == glslang::EbtFloat) { + float floatValue = static_cast(constant->getConstArray()[0].getDConst()); + unsigned literal; + static_assert(sizeof(literal) == sizeof(floatValue), "sizeof(unsigned) != sizeof(float)"); + memcpy(&literal, &floatValue, sizeof(literal)); + operands.push_back({false, literal}); + } else if (constant->getBasicType() == glslang::EbtInt) { + unsigned literal = constant->getConstArray()[0].getIConst(); + operands.push_back({false, literal}); + } else if (constant->getBasicType() == glslang::EbtUint) { + unsigned literal = constant->getConstArray()[0].getUConst(); + operands.push_back({false, literal}); + } else if (constant->getBasicType() == glslang::EbtBool) { + unsigned literal = constant->getConstArray()[0].getBConst(); + operands.push_back({false, literal}); + } else if (constant->getBasicType() == glslang::EbtString) { + auto str = constant->getConstArray()[0].getSConst()->c_str(); + unsigned literal = 0; + char* literalPtr = reinterpret_cast(&literal); + unsigned charCount = 0; + char ch = 0; + do { + ch = *(str++); + *(literalPtr++) = ch; + ++charCount; + if (charCount == 4) { + operands.push_back({false, literal}); + literalPtr = reinterpret_cast(&literal); + charCount = 0; + } + } while (ch != 0); + + // Partial literal is padded with 0 + if (charCount > 0) { + for (; charCount < 4; ++charCount) + *(literalPtr++) = 0; operands.push_back({false, literal}); - literalPtr = reinterpret_cast(&literal); - charCount = 0; } - } while (ch != 0); - - // Partial literal is padded with 0 - if (charCount > 0) { - for (; charCount < 4; ++charCount) - *(literalPtr++) = 0; - operands.push_back({false, literal}); - } + } else + assert(0); // Unexpected type } else - assert(0); // Unexpected type - } else - operands.push_back({true, createSpvConstant(*typeParam.constant)}); + operands.push_back({true, createSpvConstant(*constant)}); + } else { + // Type specifier + assert(typeParam.getAsType() != nullptr); + operands.push_back({true, convertGlslangToSpvType(*typeParam.getAsType())}); + } } assert(spirvInst.set == ""); // Currently, couldn't be extended instructions. @@ -4236,7 +4608,6 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty break; } -#endif default: assert(0); break; @@ -4250,9 +4621,10 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty spvType = builder.makeVectorType(spvType, type.getVectorSize()); } - if (type.isCoopMat()) { + if (type.isCoopMatNV()) { builder.addCapability(spv::CapabilityCooperativeMatrixNV); builder.addExtension(spv::E_SPV_NV_cooperative_matrix); + if (type.getBasicType() == glslang::EbtFloat16) builder.addCapability(spv::CapabilityFloat16); if (type.getBasicType() == glslang::EbtUint8 || @@ -4260,11 +4632,29 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty builder.addCapability(spv::CapabilityInt8); } - spv::Id scope = makeArraySizeId(*type.getTypeParameters(), 1); - spv::Id rows = makeArraySizeId(*type.getTypeParameters(), 2); - spv::Id cols = makeArraySizeId(*type.getTypeParameters(), 3); + spv::Id scope = makeArraySizeId(*type.getTypeParameters()->arraySizes, 1); + spv::Id rows = makeArraySizeId(*type.getTypeParameters()->arraySizes, 2); + spv::Id cols = makeArraySizeId(*type.getTypeParameters()->arraySizes, 3); + + spvType = builder.makeCooperativeMatrixTypeNV(spvType, scope, rows, cols); + } + + if (type.isCoopMatKHR()) { + builder.addCapability(spv::CapabilityCooperativeMatrixKHR); + builder.addExtension(spv::E_SPV_KHR_cooperative_matrix); + + if (type.getBasicType() == glslang::EbtFloat16) + builder.addCapability(spv::CapabilityFloat16); + if (type.getBasicType() == glslang::EbtUint8 || type.getBasicType() == glslang::EbtInt8) { + builder.addCapability(spv::CapabilityInt8); + } + + spv::Id scope = makeArraySizeId(*type.getTypeParameters()->arraySizes, 0); + spv::Id rows = makeArraySizeId(*type.getTypeParameters()->arraySizes, 1); + spv::Id cols = makeArraySizeId(*type.getTypeParameters()->arraySizes, 2); + spv::Id use = builder.makeUintConstant(type.getCoopMatKHRuse()); - spvType = builder.makeCooperativeMatrixType(spvType, scope, rows, cols); + spvType = builder.makeCooperativeMatrixTypeKHR(spvType, scope, rows, cols, use); } if (type.isArray()) { @@ -4305,12 +4695,10 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty if (type.isSizedArray()) spvType = builder.makeArrayType(spvType, makeArraySizeId(*type.getArraySizes(), 0), stride); else { -#ifndef GLSLANG_WEB if (!lastBufferBlockMember) { builder.addIncorporatedExtension("SPV_EXT_descriptor_indexing", spv::Spv_1_5); builder.addCapability(spv::CapabilityRuntimeDescriptorArrayEXT); } -#endif spvType = builder.makeRuntimeArray(spvType); } if (stride > 0) @@ -4320,13 +4708,70 @@ spv::Id TGlslangToSpvTraverser::convertGlslangToSpvType(const glslang::TType& ty return spvType; } +// Apply SPIR-V decorations to the SPIR-V object (provided by SPIR-V ID). If member index is provided, the +// decorations are applied to this member. +void TGlslangToSpvTraverser::applySpirvDecorate(const glslang::TType& type, spv::Id id, std::optional member) +{ + assert(type.getQualifier().hasSpirvDecorate()); + + const glslang::TSpirvDecorate& spirvDecorate = type.getQualifier().getSpirvDecorate(); + + // Add spirv_decorate + for (auto& decorate : spirvDecorate.decorates) { + if (!decorate.second.empty()) { + std::vector literals; + TranslateLiterals(decorate.second, literals); + if (member.has_value()) + builder.addMemberDecoration(id, *member, static_cast(decorate.first), literals); + else + builder.addDecoration(id, static_cast(decorate.first), literals); + } else { + if (member.has_value()) + builder.addMemberDecoration(id, *member, static_cast(decorate.first)); + else + builder.addDecoration(id, static_cast(decorate.first)); + } + } + + // Add spirv_decorate_id + if (member.has_value()) { + // spirv_decorate_id not applied to members + assert(spirvDecorate.decorateIds.empty()); + } else { + for (auto& decorateId : spirvDecorate.decorateIds) { + std::vector operandIds; + assert(!decorateId.second.empty()); + for (auto extraOperand : decorateId.second) { + if (extraOperand->getQualifier().isFrontEndConstant()) + operandIds.push_back(createSpvConstant(*extraOperand)); + else + operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode())); + } + builder.addDecorationId(id, static_cast(decorateId.first), operandIds); + } + } + + // Add spirv_decorate_string + for (auto& decorateString : spirvDecorate.decorateStrings) { + std::vector strings; + assert(!decorateString.second.empty()); + for (auto extraOperand : decorateString.second) { + const char* string = extraOperand->getConstArray()[0].getSConst()->c_str(); + strings.push_back(string); + } + if (member.has_value()) + builder.addMemberDecoration(id, *member, static_cast(decorateString.first), strings); + else + builder.addDecoration(id, static_cast(decorateString.first), strings); + } +} + // TODO: this functionality should exist at a higher level, in creating the AST // // Identify interface members that don't have their required extension turned on. // bool TGlslangToSpvTraverser::filterMember(const glslang::TType& member) { -#ifndef GLSLANG_WEB auto& extensions = glslangIntermediate->getRequestedExtensions(); if (member.getFieldName() == "gl_SecondaryViewportMaskNV" && @@ -4336,7 +4781,13 @@ bool TGlslangToSpvTraverser::filterMember(const glslang::TType& member) extensions.find("GL_NV_stereo_view_rendering") == extensions.end()) return true; - if (glslangIntermediate->getStage() != EShLangMeshNV) { + if (glslangIntermediate->getStage() == EShLangMesh) { + if (member.getFieldName() == "gl_PrimitiveShadingRateEXT" && + extensions.find("GL_EXT_fragment_shading_rate") == extensions.end()) + return true; + } + + if (glslangIntermediate->getStage() != EShLangMesh) { if (member.getFieldName() == "gl_ViewportMask" && extensions.find("GL_NV_viewport_array2") == extensions.end()) return true; @@ -4347,7 +4798,6 @@ bool TGlslangToSpvTraverser::filterMember(const glslang::TType& member) extensions.find("GL_NVX_multiview_per_view_attributes") == extensions.end()) return true; } -#endif return false; }; @@ -4366,14 +4816,14 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy // except sometimes for blocks std::vector > deferredForwardPointers; for (int i = 0; i < (int)glslangMembers->size(); i++) { - glslang::TType& glslangMember = *(*glslangMembers)[i].type; - if (glslangMember.hiddenMember()) { + auto& glslangMember = (*glslangMembers)[i]; + if (glslangMember.type->hiddenMember()) { ++memberDelta; if (type.getBasicType() == glslang::EbtBlock) memberRemapper[glslangTypeToIdMap[glslangMembers]][i] = -1; } else { if (type.getBasicType() == glslang::EbtBlock) { - if (filterMember(glslangMember)) { + if (filterMember(*glslangMember.type)) { memberDelta++; memberRemapper[glslangTypeToIdMap[glslangMembers]][i] = -1; continue; @@ -4381,7 +4831,7 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy memberRemapper[glslangTypeToIdMap[glslangMembers]][i] = i - memberDelta; } // modify just this child's view of the qualifier - glslang::TQualifier memberQualifier = glslangMember.getQualifier(); + glslang::TQualifier memberQualifier = glslangMember.type->getQualifier(); InheritQualifiers(memberQualifier, qualifier); // manually inherit location @@ -4392,30 +4842,43 @@ spv::Id TGlslangToSpvTraverser::convertGlslangStructToSpvType(const glslang::TTy bool lastBufferBlockMember = qualifier.storage == glslang::EvqBuffer && i == (int)glslangMembers->size() - 1; - // Make forward pointers for any pointer members, and create a list of members to - // convert to spirv types after creating the struct. - if (glslangMember.isReference()) { - if (forwardPointers.find(glslangMember.getReferentType()) == forwardPointers.end()) { - deferredForwardPointers.push_back(std::make_pair(&glslangMember, memberQualifier)); - } - spvMembers.push_back( - convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, - true)); - } else { - spvMembers.push_back( - convertGlslangToSpvType(glslangMember, explicitLayout, memberQualifier, lastBufferBlockMember, - false)); + // Make forward pointers for any pointer members. + if (glslangMember.type->isReference() && + forwardPointers.find(glslangMember.type->getReferentType()) == forwardPointers.end()) { + deferredForwardPointers.push_back(std::make_pair(glslangMember.type, memberQualifier)); + } + + // Create the member type. + auto const spvMember = convertGlslangToSpvType(*glslangMember.type, explicitLayout, memberQualifier, lastBufferBlockMember, + glslangMember.type->isReference()); + spvMembers.push_back(spvMember); + + // Update the builder with the type's location so that we can create debug types for the structure members. + // There doesn't exist a "clean" entry point for this information to be passed along to the builder so, for now, + // it is stored in the builder and consumed during the construction of composite debug types. + // TODO: This probably warrants further investigation. This approach was decided to be the least ugly of the + // quick and dirty approaches that were tried. + // Advantages of this approach: + // + Relatively clean. No direct calls into debug type system. + // + Handles nested recursive structures. + // Disadvantages of this approach: + // + Not as clean as desired. Traverser queries/sets persistent state. This is fragile. + // + Table lookup during creation of composite debug types. This really shouldn't be necessary. + if(options.emitNonSemanticShaderDebugInfo) { + builder.debugTypeLocs[spvMember].name = glslangMember.type->getFieldName().c_str(); + builder.debugTypeLocs[spvMember].line = glslangMember.loc.line; + builder.debugTypeLocs[spvMember].column = glslangMember.loc.column; } } } // Make the SPIR-V type - spv::Id spvType = builder.makeStructType(spvMembers, type.getTypeName().c_str()); + spv::Id spvType = builder.makeStructType(spvMembers, type.getTypeName().c_str(), false); if (! HasNonLayoutQualifiers(type, qualifier)) structMap[explicitLayout][qualifier.layoutMatrix][glslangMembers] = spvType; // Decorate it - decorateStructType(type, glslangMembers, explicitLayout, qualifier, spvType); + decorateStructType(type, glslangMembers, explicitLayout, qualifier, spvType, spvMembers); for (int i = 0; i < (int)deferredForwardPointers.size(); ++i) { auto it = deferredForwardPointers[i]; @@ -4429,7 +4892,8 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, const glslang::TTypeList* glslangMembers, glslang::TLayoutPacking explicitLayout, const glslang::TQualifier& qualifier, - spv::Id spvType) + spv::Id spvType, + const std::vector& spvMembers) { // Name and decorate the non-hidden members int offset = -1; @@ -4464,14 +4928,11 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, glslangIntermediate->getSource() == glslang::EShSourceHlsl) { builder.addMemberDecoration(spvType, member, TranslateInterpolationDecoration(memberQualifier)); builder.addMemberDecoration(spvType, member, TranslateAuxiliaryStorageDecoration(memberQualifier)); -#ifndef GLSLANG_WEB addMeshNVDecoration(spvType, member, memberQualifier); -#endif } } builder.addMemberDecoration(spvType, member, TranslateInvariantDecoration(memberQualifier)); -#ifndef GLSLANG_WEB if (type.getBasicType() == glslang::EbtBlock && qualifier.storage == glslang::EvqBuffer) { // Add memory decorations only to top-level members of shader storage block @@ -4481,8 +4942,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, builder.addMemberDecoration(spvType, member, memory[i]); } -#endif - // Location assignment was already completed correctly by the front end, // just track whether a member needs to be decorated. // Ignore member locations if the container is an array, as that's @@ -4515,7 +4974,6 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, if (builtIn != spv::BuiltInMax) builder.addMemberDecoration(spvType, member, spv::DecorationBuiltIn, (int)builtIn); -#ifndef GLSLANG_WEB // nonuniform builder.addMemberDecoration(spvType, member, TranslateNonUniformDecoration(glslangMember.getQualifier())); @@ -4546,50 +5004,33 @@ void TGlslangToSpvTraverser::decorateStructType(const glslang::TType& type, builder.addExtension(spv::E_SPV_NV_geometry_shader_passthrough); } - // - // Add SPIR-V decorations for members (GL_EXT_spirv_intrinsics) - // - if (glslangMember.getQualifier().hasSprivDecorate()) { - const glslang::TSpirvDecorate& spirvDecorate = glslangMember.getQualifier().getSpirvDecorate(); - - // Add spirv_decorate - for (auto& decorate : spirvDecorate.decorates) { - if (!decorate.second.empty()) { - std::vector literals; - TranslateLiterals(decorate.second, literals); - builder.addMemberDecoration(spvType, member, static_cast(decorate.first), literals); - } - else - builder.addMemberDecoration(spvType, member, static_cast(decorate.first)); - } - - // spirv_decorate_id not applied to members - assert(spirvDecorate.decorateIds.empty()); - - // Add spirv_decorate_string - for (auto& decorateString : spirvDecorate.decorateStrings) { - std::vector strings; - assert(!decorateString.second.empty()); - for (auto extraOperand : decorateString.second) { - const char* string = extraOperand->getConstArray()[0].getSConst()->c_str(); - strings.push_back(string); - } - builder.addDecoration(spvType, static_cast(decorateString.first), strings); - } - } -#endif + // Add SPIR-V decorations (GL_EXT_spirv_intrinsics) + if (glslangMember.getQualifier().hasSpirvDecorate()) + applySpirvDecorate(glslangMember, spvType, member); } // Decorate the structure builder.addDecoration(spvType, TranslateLayoutDecoration(type, qualifier.layoutMatrix)); - builder.addDecoration(spvType, TranslateBlockDecoration(type, glslangIntermediate->usingStorageBuffer())); + const auto basicType = type.getBasicType(); + const auto typeStorageQualifier = type.getQualifier().storage; + if (basicType == glslang::EbtBlock) { + builder.addDecoration(spvType, TranslateBlockDecoration(typeStorageQualifier, glslangIntermediate->usingStorageBuffer())); + } else if (basicType == glslang::EbtStruct && glslangIntermediate->getSpv().vulkan > 0) { + const auto hasRuntimeArray = !spvMembers.empty() && builder.getOpCode(spvMembers.back()) == spv::OpTypeRuntimeArray; + if (hasRuntimeArray) { + builder.addDecoration(spvType, TranslateBlockDecoration(typeStorageQualifier, glslangIntermediate->usingStorageBuffer())); + } + } + + if (qualifier.hasHitObjectShaderRecordNV()) + builder.addDecoration(spvType, spv::DecorationHitObjectShaderRecordBufferNV); } // Turn the expression forming the array size into an id. // This is not quite trivial, because of specialization constants. // Sometimes, a raw constant is turned into an Id, and sometimes // a specialization constant expression is. -spv::Id TGlslangToSpvTraverser::makeArraySizeId(const glslang::TArraySizes& arraySizes, int dim) +spv::Id TGlslangToSpvTraverser::makeArraySizeId(const glslang::TArraySizes& arraySizes, int dim, bool allowZero) { // First, see if this is sized with a node, meaning a specialization constant: glslang::TIntermTyped* specNode = arraySizes.getDimNode(dim); @@ -4603,7 +5044,10 @@ spv::Id TGlslangToSpvTraverser::makeArraySizeId(const glslang::TArraySizes& arra // Otherwise, need a compile-time (front end) size, get it: int size = arraySizes.getDimSize(dim); - assert(size > 0); + + if (!allowZero) + assert(size > 0); + return builder.makeUintConstant(size); } @@ -4619,6 +5063,16 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type) spv::Builder::AccessChain::CoherentFlags coherentFlags = builder.getAccessChain().coherentFlags; coherentFlags |= TranslateCoherent(type); + spv::MemoryAccessMask accessMask = spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask); + // If the value being loaded is HelperInvocation, SPIR-V 1.6 is being generated (so that + // SPV_EXT_demote_to_helper_invocation is in core) and the memory model is in use, add + // the Volatile MemoryAccess semantic. + if (type.getQualifier().builtIn == glslang::EbvHelperInvocation && + glslangIntermediate->usingVulkanMemoryModel() && + glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) { + accessMask = spv::MemoryAccessMask(accessMask | spv::MemoryAccessVolatileMask); + } + unsigned int alignment = builder.getAccessChain().alignment; alignment |= type.getBufferReferenceAlignment(); @@ -4626,7 +5080,7 @@ spv::Id TGlslangToSpvTraverser::accessChainLoad(const glslang::TType& type) TranslateNonUniformDecoration(builder.getAccessChain().coherentFlags), TranslateNonUniformDecoration(type.getQualifier()), nominalTypeId, - spv::MemoryAccessMask(TranslateMemoryAccess(coherentFlags) & ~spv::MemoryAccessMakePointerAvailableKHRMask), + accessMask, TranslateMemoryScope(coherentFlags), alignment); @@ -4898,7 +5352,6 @@ void TGlslangToSpvTraverser::declareUseOfStructMember(const glslang::TTypeList& switch (glslangBuiltIn) { case glslang::EbvPointSize: -#ifndef GLSLANG_WEB case glslang::EbvClipDistance: case glslang::EbvCullDistance: case glslang::EbvViewportMaskNV: @@ -4914,7 +5367,6 @@ void TGlslangToSpvTraverser::declareUseOfStructMember(const glslang::TTypeList& case glslang::EbvLayerPerViewNV: case glslang::EbvMeshViewCountNV: case glslang::EbvMeshViewIndicesNV: -#endif // Generate the associated capability. Delegate to TranslateBuiltInDecoration. // Alternately, we could just call this for any glslang built-in, since the // capability already guards against duplicates. @@ -4953,10 +5405,8 @@ bool TGlslangToSpvTraverser::originalParam(glslang::TStorageQualifier qualifier, return true; if (glslangIntermediate->getSource() == glslang::EShSourceHlsl) return paramType.getBasicType() == glslang::EbtBlock; - return paramType.containsOpaque() || // sampler, etc. -#ifndef GLSLANG_WEB + return (paramType.containsOpaque() && !glslangIntermediate->getBindlessMode()) || // sampler, etc. paramType.getQualifier().isSpirvByReference() || // spirv_by_reference -#endif (paramType.getBasicType() == glslang::EbtBlock && qualifier == glslang::EvqBuffer); // SSBO } @@ -4986,9 +5436,17 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF for (int f = 0; f < (int)glslFunctions.size(); ++f) { glslang::TIntermAggregate* glslFunction = glslFunctions[f]->getAsAggregate(); - if (! glslFunction || glslFunction->getOp() != glslang::EOpFunction || isShaderEntryPoint(glslFunction)) + if (! glslFunction || glslFunction->getOp() != glslang::EOpFunction) continue; - + if (isShaderEntryPoint(glslFunction)) { + if (glslangIntermediate->getSource() != glslang::EShSourceHlsl) { + builder.setupDebugFunctionEntry(shaderEntry, glslangIntermediate->getEntryPointMangledName().c_str(), + glslFunction->getLoc().line, + std::vector(), // main function has no param + std::vector()); + } + continue; + } // We're on a user function. Set up the basic interface for the function now, // so that it's available to call. Translating the body will happen later. // @@ -5004,6 +5462,7 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF // GLSL has copy-in/copy-out semantics. They can be handled though with a pointer to a copy. std::vector paramTypes; + std::vector paramNames; std::vector> paramDecorations; // list of decorations per parameter glslang::TIntermSequence& parameters = glslFunction->getSequence()[0]->getAsAggregate()->getSequence(); @@ -5028,11 +5487,17 @@ void TGlslangToSpvTraverser::makeFunctions(const glslang::TIntermSequence& glslF paramTypes.push_back(typeId); } + for (auto const parameter:parameters) { + paramNames.push_back(parameter->getAsSymbolNode()->getName().c_str()); + } + spv::Block* functionBlock; - spv::Function *function = builder.makeFunctionEntry(TranslatePrecisionDecoration(glslFunction->getType()), - convertGlslangToSpvType(glslFunction->getType()), - glslFunction->getName().c_str(), paramTypes, - paramDecorations, &functionBlock); + spv::Function* function = builder.makeFunctionEntry( + TranslatePrecisionDecoration(glslFunction->getType()), convertGlslangToSpvType(glslFunction->getType()), + glslFunction->getName().c_str(), convertGlslangLinkageToSpv(glslFunction->getLinkType()), paramTypes, + paramDecorations, &functionBlock); + builder.setupDebugFunctionEntry(function, glslFunction->getName().c_str(), glslFunction->getLoc().line, + paramTypes, paramNames); if (implicitThis) function->setImplicitThis(); @@ -5095,6 +5560,10 @@ void TGlslangToSpvTraverser::collectRayTracingLinkerObjects() set = 1; break; + case glslang::EvqHitObjectAttrNV: + set = 2; + break; + default: set = -1; } @@ -5121,6 +5590,7 @@ void TGlslangToSpvTraverser::handleFunctionEntry(const glslang::TIntermAggregate currentFunction = functionMap[node->getName().c_str()]; spv::Block* functionBlock = currentFunction->getEntryBlock(); builder.setBuildPoint(functionBlock); + builder.enterFunction(currentFunction); } void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& node, std::vector& arguments, @@ -5130,23 +5600,18 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& glslang::TSampler sampler = {}; bool cubeCompare = false; -#ifndef GLSLANG_WEB bool f16ShadowCompare = false; -#endif if (node.isTexture() || node.isImage()) { sampler = glslangArguments[0]->getAsTyped()->getType().getSampler(); cubeCompare = sampler.dim == glslang::EsdCube && sampler.arrayed && sampler.shadow; -#ifndef GLSLANG_WEB f16ShadowCompare = sampler.shadow && glslangArguments[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16; -#endif } for (int i = 0; i < (int)glslangArguments.size(); ++i) { builder.clearAccessChain(); glslangArguments[i]->traverse(this); -#ifndef GLSLANG_WEB // Special case l-value operands bool lvalue = false; switch (node.getOp()) { @@ -5242,6 +5707,10 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& if (i == 7) lvalue = true; break; + case glslang::EOpRayQueryGetIntersectionTriangleVertexPositionsEXT: + if (i == 2) + lvalue = true; + break; default: break; } @@ -5253,7 +5722,6 @@ void TGlslangToSpvTraverser::translateArguments(const glslang::TIntermAggregate& builder.addDecoration(lvalue_id, TranslateNonUniformDecoration(lvalueCoherentFlags)); lvalueCoherentFlags |= TranslateCoherent(glslangArguments[i]->getAsTyped()->getType()); } else -#endif arguments.push_back(accessChainLoad(glslangArguments[i]->getAsTyped()->getType())); } } @@ -5278,13 +5746,9 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO ? node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType() : node->getAsUnaryNode()->getOperand()->getAsTyped()->getType(); const glslang::TSampler sampler = imageType.getSampler(); -#ifdef GLSLANG_WEB - const bool f16ShadowCompare = false; -#else bool f16ShadowCompare = (sampler.shadow && node->getAsAggregate()) ? node->getAsAggregate()->getSequence()[1]->getAsTyped()->getType().getBasicType() == glslang::EbtFloat16 : false; -#endif const auto signExtensionMask = [&]() { if (builder.getSpvVersion() >= spv::Spv_1_4) { @@ -5330,7 +5794,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO return builder.createTextureQueryCall(spv::OpImageQuerySizeLod, params, isUnsignedResult); } else return builder.createTextureQueryCall(spv::OpImageQuerySize, params, isUnsignedResult); -#ifndef GLSLANG_WEB case glslang::EOpImageQuerySamples: case glslang::EOpTextureQuerySamples: return builder.createTextureQueryCall(spv::OpImageQuerySamples, params, isUnsignedResult); @@ -5341,7 +5804,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO return builder.createTextureQueryCall(spv::OpImageQueryLevels, params, isUnsignedResult); case glslang::EOpSparseTexelsResident: return builder.createUnaryOp(spv::OpImageSparseTexelsResident, builder.makeBoolType(), arguments[0]); -#endif default: assert(0); break; @@ -5401,6 +5863,17 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO return result; } + if (cracked.attachmentEXT) { + if (opIt != arguments.end()) { + spv::IdImmediate sample = { true, *opIt }; + operands.push_back(sample); + } + spv::Id result = builder.createOp(spv::OpColorAttachmentReadEXT, resultType(), operands); + builder.addExtension(spv::E_SPV_EXT_shader_tile_image); + builder.setPrecision(result, precision); + return result; + } + spv::IdImmediate coord = { true, *(opIt++) }; operands.push_back(coord); if (node->getOp() == glslang::EOpImageLoad || node->getOp() == glslang::EOpImageLoadLod) { @@ -5548,10 +6021,12 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO operands.push_back(sample); spv::Id resultTypeId; + glslang::TBasicType typeProxy = node->getBasicType(); // imageAtomicStore has a void return type so base the pointer type on // the type of the value operand. if (node->getOp() == glslang::EOpImageAtomicStore) { resultTypeId = builder.makePointer(spv::StorageClassImage, builder.getTypeId(*opIt)); + typeProxy = node->getAsAggregate()->getSequence()[0]->getAsTyped()->getType().getSampler().type; } else { resultTypeId = builder.makePointer(spv::StorageClassImage, resultType()); } @@ -5565,12 +6040,11 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO for (; opIt != arguments.end(); ++opIt) operands.push_back(*opIt); - return createAtomicOperation(node->getOp(), precision, resultType(), operands, node->getBasicType(), + return createAtomicOperation(node->getOp(), precision, resultType(), operands, typeProxy, lvalueCoherentFlags); } } -#ifndef GLSLANG_WEB // Check for fragment mask functions other than queries if (cracked.fragMask) { assert(sampler.ms); @@ -5604,7 +6078,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO builder.addCapability(spv::CapabilityFragmentMaskAMD); return builder.createOp(fragMaskOp, resultType(), operands); } -#endif // Check for texture functions other than queries bool sparse = node->isSparseTexture(); @@ -5638,7 +6111,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO bias = true; } -#ifndef GLSLANG_WEB if (cracked.gather) { const auto& sourceExtensions = glslangIntermediate->getRequestedExtensions(); if (bias || cracked.lod || @@ -5647,7 +6119,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO builder.addCapability(spv::CapabilityImageGatherBiasLodAMD); } } -#endif // set the rest of the arguments @@ -5707,7 +6178,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO ++extraArgs; } -#ifndef GLSLANG_WEB // lod clamp if (cracked.lodClamp) { params.lodClamp = arguments[2 + extraArgs]; @@ -5736,14 +6206,13 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO resultStruct = arguments[4 + extraArgs]; extraArgs += 3; } -#endif + // bias if (bias) { params.bias = arguments[2 + extraArgs]; ++extraArgs; } -#ifndef GLSLANG_WEB if (imageFootprint) { builder.addExtension(spv::E_SPV_NV_shader_image_footprint); builder.addCapability(spv::CapabilityImageFootprintNV); @@ -5769,10 +6238,10 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO assert(builder.isStructType(resultStructType)); //resType (SPIR-V type) contains 6 elements: - //Member 0 must be a Boolean type scalar(LOD), - //Member 1 must be a vector of integer type, whose Signedness operand is 0(anchor), - //Member 2 must be a vector of integer type, whose Signedness operand is 0(offset), - //Member 3 must be a vector of integer type, whose Signedness operand is 0(mask), + //Member 0 must be a Boolean type scalar(LOD), + //Member 1 must be a vector of integer type, whose Signedness operand is 0(anchor), + //Member 2 must be a vector of integer type, whose Signedness operand is 0(offset), + //Member 3 must be a vector of integer type, whose Signedness operand is 0(mask), //Member 4 must be a scalar of integer type, whose Signedness operand is 0(lod), //Member 5 must be a scalar of integer type, whose Signedness operand is 0(granularity). std::vector members; @@ -5785,7 +6254,7 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO //call ImageFootprintNV spv::Id res = builder.createTextureCall(precision, resType, sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params, signExtensionMask()); - + //copy resType (SPIR-V type) to resultStructType(OpenGL type) for (int i = 0; i < 5; i++) { builder.clearAccessChain(); @@ -5801,7 +6270,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } return builder.createCompositeExtract(res, resultType(), 0); } -#endif // projective component (might not to move) // GLSL: "The texture coordinates consumed from P, not including the last component of P, @@ -5826,7 +6294,6 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO } } -#ifndef GLSLANG_WEB // nonprivate if (imageType.getQualifier().nonprivate) { params.nonprivate = true; @@ -5836,9 +6303,8 @@ spv::Id TGlslangToSpvTraverser::createImageTextureFunctionCall(glslang::TIntermO if (imageType.getQualifier().volatil) { params.volatil = true; } -#endif - std::vector result( 1, + std::vector result( 1, builder.createTextureCall(precision, resultType(), sparse, cracked.fetch, cracked.proj, cracked.gather, noImplicitLod, params, signExtensionMask()) ); @@ -6490,7 +6956,6 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe case glslang::EOpUnpackHalf2x16: libCall = spv::GLSLstd450UnpackHalf2x16; break; -#ifndef GLSLANG_WEB case glslang::EOpPackSnorm4x8: libCall = spv::GLSLstd450PackSnorm4x8; break; @@ -6509,7 +6974,6 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe case glslang::EOpUnpackDouble2x32: libCall = spv::GLSLstd450UnpackDouble2x32; break; -#endif case glslang::EOpPackInt2x32: case glslang::EOpUnpackInt2x32: @@ -6564,7 +7028,6 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe libCall = spv::GLSLstd450SSign; break; -#ifndef GLSLANG_WEB case glslang::EOpDPdxFine: unaryOp = spv::OpDPdxFine; break; @@ -6736,12 +7199,108 @@ spv::Id TGlslangToSpvTraverser::createUnaryOperation(glslang::TOperator op, OpDe case glslang::EOpConvUvec2ToAccStruct: unaryOp = spv::OpConvertUToAccelerationStructureKHR; break; -#endif + + case glslang::EOpHitObjectIsEmptyNV: + unaryOp = spv::OpHitObjectIsEmptyNV; + break; + + case glslang::EOpHitObjectIsMissNV: + unaryOp = spv::OpHitObjectIsMissNV; + break; + + case glslang::EOpHitObjectIsHitNV: + unaryOp = spv::OpHitObjectIsHitNV; + break; + + case glslang::EOpHitObjectGetObjectRayOriginNV: + unaryOp = spv::OpHitObjectGetObjectRayOriginNV; + break; + + case glslang::EOpHitObjectGetObjectRayDirectionNV: + unaryOp = spv::OpHitObjectGetObjectRayDirectionNV; + break; + + case glslang::EOpHitObjectGetWorldRayOriginNV: + unaryOp = spv::OpHitObjectGetWorldRayOriginNV; + break; + + case glslang::EOpHitObjectGetWorldRayDirectionNV: + unaryOp = spv::OpHitObjectGetWorldRayDirectionNV; + break; + + case glslang::EOpHitObjectGetObjectToWorldNV: + unaryOp = spv::OpHitObjectGetObjectToWorldNV; + break; + + case glslang::EOpHitObjectGetWorldToObjectNV: + unaryOp = spv::OpHitObjectGetWorldToObjectNV; + break; + + case glslang::EOpHitObjectGetRayTMinNV: + unaryOp = spv::OpHitObjectGetRayTMinNV; + break; + + case glslang::EOpHitObjectGetRayTMaxNV: + unaryOp = spv::OpHitObjectGetRayTMaxNV; + break; + + case glslang::EOpHitObjectGetPrimitiveIndexNV: + unaryOp = spv::OpHitObjectGetPrimitiveIndexNV; + break; + + case glslang::EOpHitObjectGetInstanceIdNV: + unaryOp = spv::OpHitObjectGetInstanceIdNV; + break; + + case glslang::EOpHitObjectGetInstanceCustomIndexNV: + unaryOp = spv::OpHitObjectGetInstanceCustomIndexNV; + break; + + case glslang::EOpHitObjectGetGeometryIndexNV: + unaryOp = spv::OpHitObjectGetGeometryIndexNV; + break; + + case glslang::EOpHitObjectGetHitKindNV: + unaryOp = spv::OpHitObjectGetHitKindNV; + break; + + case glslang::EOpHitObjectGetCurrentTimeNV: + unaryOp = spv::OpHitObjectGetCurrentTimeNV; + break; + + case glslang::EOpHitObjectGetShaderBindingTableRecordIndexNV: + unaryOp = spv::OpHitObjectGetShaderBindingTableRecordIndexNV; + break; + + case glslang::EOpHitObjectGetShaderRecordBufferHandleNV: + unaryOp = spv::OpHitObjectGetShaderRecordBufferHandleNV; + break; + + case glslang::EOpFetchMicroTriangleVertexPositionNV: + unaryOp = spv::OpFetchMicroTriangleVertexPositionNV; + break; + + case glslang::EOpFetchMicroTriangleVertexBarycentricNV: + unaryOp = spv::OpFetchMicroTriangleVertexBarycentricNV; + break; case glslang::EOpCopyObject: unaryOp = spv::OpCopyObject; break; + case glslang::EOpDepthAttachmentReadEXT: + builder.addExtension(spv::E_SPV_EXT_shader_tile_image); + builder.addCapability(spv::CapabilityTileImageDepthReadAccessEXT); + unaryOp = spv::OpDepthAttachmentReadEXT; + decorations.precision = spv::NoPrecision; + break; + case glslang::EOpStencilAttachmentReadEXT: + builder.addExtension(spv::E_SPV_EXT_shader_tile_image); + builder.addCapability(spv::CapabilityTileImageStencilReadAccessEXT); + unaryOp = spv::OpStencilAttachmentReadEXT; + decorations.precision = spv::DecorationRelaxedPrecision; + break; + default: return 0; } @@ -6798,7 +7357,9 @@ spv::Id TGlslangToSpvTraverser::createUnaryMatrixOperation(spv::Op op, OpDecorat // For converting integers where both the bitwidth and the signedness could // change, but only do the width change here. The caller is still responsible // for the signedness conversion. -spv::Id TGlslangToSpvTraverser::createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize) +// destType is the final type that will be converted to, but this function +// may only be doing part of that conversion. +spv::Id TGlslangToSpvTraverser::createIntWidthConversion(glslang::TOperator op, spv::Id operand, int vectorSize, spv::Id destType) { // Get the result type width, based on the type to convert to. int width = 32; @@ -6869,6 +7430,11 @@ spv::Id TGlslangToSpvTraverser::createIntWidthConversion(glslang::TOperator op, if (vectorSize > 0) type = builder.makeVectorType(type, vectorSize); + else if (builder.getOpCode(destType) == spv::OpTypeCooperativeMatrixKHR || + builder.getOpCode(destType) == spv::OpTypeCooperativeMatrixNV) { + + type = builder.makeCooperativeMatrixTypeWithSameShape(type, destType); + } return builder.createUnaryOp(convOp, type, operand); } @@ -6900,13 +7466,10 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora case glslang::EOpConvBoolToInt: case glslang::EOpConvBoolToInt64: -#ifndef GLSLANG_WEB if (op == glslang::EOpConvBoolToInt64) { zero = builder.makeInt64Constant(0); one = builder.makeInt64Constant(1); - } else -#endif - { + } else { zero = builder.makeIntConstant(0); one = builder.makeIntConstant(1); } @@ -6916,13 +7479,10 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora case glslang::EOpConvBoolToUint: case glslang::EOpConvBoolToUint64: -#ifndef GLSLANG_WEB if (op == glslang::EOpConvBoolToUint64) { zero = builder.makeUint64Constant(0); one = builder.makeUint64Constant(1); - } else -#endif - { + } else { zero = builder.makeUintConstant(0); one = builder.makeUintConstant(1); } @@ -6985,16 +7545,13 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora case glslang::EOpConvInt64ToUint64: if (builder.isInSpecConstCodeGenMode()) { // Build zero scalar or vector for OpIAdd. -#ifndef GLSLANG_WEB if(op == glslang::EOpConvUint8ToInt8 || op == glslang::EOpConvInt8ToUint8) { zero = builder.makeUint8Constant(0); } else if (op == glslang::EOpConvUint16ToInt16 || op == glslang::EOpConvInt16ToUint16) { zero = builder.makeUint16Constant(0); } else if (op == glslang::EOpConvUint64ToInt64 || op == glslang::EOpConvInt64ToUint64) { zero = builder.makeUint64Constant(0); - } else -#endif - { + } else { zero = builder.makeUintConstant(0); } zero = makeSmearedConstant(zero, vectorSize); @@ -7021,7 +7578,6 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora convOp = spv::OpConvertFToU; break; -#ifndef GLSLANG_WEB case glslang::EOpConvInt8ToBool: case glslang::EOpConvUint8ToBool: zero = builder.makeUint8Constant(0); @@ -7141,7 +7697,7 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora case glslang::EOpConvUint64ToInt16: case glslang::EOpConvUint64ToInt: // OpSConvert/OpUConvert + OpBitCast - operand = createIntWidthConversion(op, operand, vectorSize); + operand = createIntWidthConversion(op, operand, vectorSize, destType); if (builder.isInSpecConstCodeGenMode()) { // Build zero scalar or vector for OpIAdd. @@ -7200,7 +7756,6 @@ spv::Id TGlslangToSpvTraverser::createConversion(glslang::TOperator op, OpDecora case glslang::EOpConvUvec2ToPtr: convOp = spv::OpBitcast; break; -#endif default: break; @@ -7361,7 +7916,7 @@ spv::Id TGlslangToSpvTraverser::createAtomicOperation(glslang::TOperator op, spv } else { scopeId = builder.makeUintConstant(spv::ScopeDevice); } - // semantics default to relaxed + // semantics default to relaxed spv::Id semanticsId = builder.makeUintConstant(lvalueCoherentFlags.isVolatile() && glslangIntermediate->usingVulkanMemoryModel() ? spv::MemorySemanticsVolatileMask : @@ -8192,7 +8747,6 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: } break; -#ifndef GLSLANG_WEB case glslang::EOpInterpolateAtSample: if (typeProxy == glslang::EbtFloat16) builder.addExtension(spv::E_SPV_AMD_gpu_shader_half_float); @@ -8465,10 +9019,166 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: case glslang::EOpWritePackedPrimitiveIndices4x8NV: builder.createNoResultOp(spv::OpWritePackedPrimitiveIndices4x8NV, operands); return 0; - case glslang::EOpCooperativeMatrixMulAdd: + case glslang::EOpEmitMeshTasksEXT: + if (taskPayloadID) + operands.push_back(taskPayloadID); + // As per SPV_EXT_mesh_shader make it a terminating instruction in the current block + builder.makeStatementTerminator(spv::OpEmitMeshTasksEXT, operands, "post-OpEmitMeshTasksEXT"); + return 0; + case glslang::EOpSetMeshOutputsEXT: + builder.createNoResultOp(spv::OpSetMeshOutputsEXT, operands); + return 0; + case glslang::EOpCooperativeMatrixMulAddNV: opCode = spv::OpCooperativeMatrixMulAddNV; break; -#endif // GLSLANG_WEB + case glslang::EOpHitObjectTraceRayNV: + builder.createNoResultOp(spv::OpHitObjectTraceRayNV, operands); + return 0; + case glslang::EOpHitObjectTraceRayMotionNV: + builder.createNoResultOp(spv::OpHitObjectTraceRayMotionNV, operands); + return 0; + case glslang::EOpHitObjectRecordHitNV: + builder.createNoResultOp(spv::OpHitObjectRecordHitNV, operands); + return 0; + case glslang::EOpHitObjectRecordHitMotionNV: + builder.createNoResultOp(spv::OpHitObjectRecordHitMotionNV, operands); + return 0; + case glslang::EOpHitObjectRecordHitWithIndexNV: + builder.createNoResultOp(spv::OpHitObjectRecordHitWithIndexNV, operands); + return 0; + case glslang::EOpHitObjectRecordHitWithIndexMotionNV: + builder.createNoResultOp(spv::OpHitObjectRecordHitWithIndexMotionNV, operands); + return 0; + case glslang::EOpHitObjectRecordMissNV: + builder.createNoResultOp(spv::OpHitObjectRecordMissNV, operands); + return 0; + case glslang::EOpHitObjectRecordMissMotionNV: + builder.createNoResultOp(spv::OpHitObjectRecordMissMotionNV, operands); + return 0; + case glslang::EOpHitObjectExecuteShaderNV: + builder.createNoResultOp(spv::OpHitObjectExecuteShaderNV, operands); + return 0; + case glslang::EOpHitObjectIsEmptyNV: + typeId = builder.makeBoolType(); + opCode = spv::OpHitObjectIsEmptyNV; + break; + case glslang::EOpHitObjectIsMissNV: + typeId = builder.makeBoolType(); + opCode = spv::OpHitObjectIsMissNV; + break; + case glslang::EOpHitObjectIsHitNV: + typeId = builder.makeBoolType(); + opCode = spv::OpHitObjectIsHitNV; + break; + case glslang::EOpHitObjectGetRayTMinNV: + typeId = builder.makeFloatType(32); + opCode = spv::OpHitObjectGetRayTMinNV; + break; + case glslang::EOpHitObjectGetRayTMaxNV: + typeId = builder.makeFloatType(32); + opCode = spv::OpHitObjectGetRayTMaxNV; + break; + case glslang::EOpHitObjectGetObjectRayOriginNV: + typeId = builder.makeVectorType(builder.makeFloatType(32), 3); + opCode = spv::OpHitObjectGetObjectRayOriginNV; + break; + case glslang::EOpHitObjectGetObjectRayDirectionNV: + typeId = builder.makeVectorType(builder.makeFloatType(32), 3); + opCode = spv::OpHitObjectGetObjectRayDirectionNV; + break; + case glslang::EOpHitObjectGetWorldRayOriginNV: + typeId = builder.makeVectorType(builder.makeFloatType(32), 3); + opCode = spv::OpHitObjectGetWorldRayOriginNV; + break; + case glslang::EOpHitObjectGetWorldRayDirectionNV: + typeId = builder.makeVectorType(builder.makeFloatType(32), 3); + opCode = spv::OpHitObjectGetWorldRayDirectionNV; + break; + case glslang::EOpHitObjectGetWorldToObjectNV: + typeId = builder.makeMatrixType(builder.makeFloatType(32), 4, 3); + opCode = spv::OpHitObjectGetWorldToObjectNV; + break; + case glslang::EOpHitObjectGetObjectToWorldNV: + typeId = builder.makeMatrixType(builder.makeFloatType(32), 4, 3); + opCode = spv::OpHitObjectGetObjectToWorldNV; + break; + case glslang::EOpHitObjectGetInstanceCustomIndexNV: + typeId = builder.makeIntegerType(32, 1); + opCode = spv::OpHitObjectGetInstanceCustomIndexNV; + break; + case glslang::EOpHitObjectGetInstanceIdNV: + typeId = builder.makeIntegerType(32, 1); + opCode = spv::OpHitObjectGetInstanceIdNV; + break; + case glslang::EOpHitObjectGetGeometryIndexNV: + typeId = builder.makeIntegerType(32, 1); + opCode = spv::OpHitObjectGetGeometryIndexNV; + break; + case glslang::EOpHitObjectGetPrimitiveIndexNV: + typeId = builder.makeIntegerType(32, 1); + opCode = spv::OpHitObjectGetPrimitiveIndexNV; + break; + case glslang::EOpHitObjectGetHitKindNV: + typeId = builder.makeIntegerType(32, 0); + opCode = spv::OpHitObjectGetHitKindNV; + break; + case glslang::EOpHitObjectGetCurrentTimeNV: + typeId = builder.makeFloatType(32); + opCode = spv::OpHitObjectGetCurrentTimeNV; + break; + case glslang::EOpHitObjectGetShaderBindingTableRecordIndexNV: + typeId = builder.makeIntegerType(32, 0); + opCode = spv::OpHitObjectGetShaderBindingTableRecordIndexNV; + return 0; + case glslang::EOpHitObjectGetAttributesNV: + builder.createNoResultOp(spv::OpHitObjectGetAttributesNV, operands); + return 0; + case glslang::EOpHitObjectGetShaderRecordBufferHandleNV: + typeId = builder.makeVectorType(builder.makeUintType(32), 2); + opCode = spv::OpHitObjectGetShaderRecordBufferHandleNV; + break; + case glslang::EOpReorderThreadNV: { + if (operands.size() == 2) { + builder.createNoResultOp(spv::OpReorderThreadWithHintNV, operands); + } else { + builder.createNoResultOp(spv::OpReorderThreadWithHitObjectNV, operands); + } + return 0; + + } + + case glslang::EOpImageSampleWeightedQCOM: + typeId = builder.makeVectorType(builder.makeFloatType(32), 4); + opCode = spv::OpImageSampleWeightedQCOM; + addImageProcessingQCOMDecoration(operands[2], spv::DecorationWeightTextureQCOM); + break; + case glslang::EOpImageBoxFilterQCOM: + typeId = builder.makeVectorType(builder.makeFloatType(32), 4); + opCode = spv::OpImageBoxFilterQCOM; + break; + case glslang::EOpImageBlockMatchSADQCOM: + typeId = builder.makeVectorType(builder.makeFloatType(32), 4); + opCode = spv::OpImageBlockMatchSADQCOM; + addImageProcessingQCOMDecoration(operands[0], spv::DecorationBlockMatchTextureQCOM); + addImageProcessingQCOMDecoration(operands[2], spv::DecorationBlockMatchTextureQCOM); + break; + case glslang::EOpImageBlockMatchSSDQCOM: + typeId = builder.makeVectorType(builder.makeFloatType(32), 4); + opCode = spv::OpImageBlockMatchSSDQCOM; + addImageProcessingQCOMDecoration(operands[0], spv::DecorationBlockMatchTextureQCOM); + addImageProcessingQCOMDecoration(operands[2], spv::DecorationBlockMatchTextureQCOM); + break; + + case glslang::EOpFetchMicroTriangleVertexBarycentricNV: + typeId = builder.makeVectorType(builder.makeFloatType(32), 2); + opCode = spv::OpFetchMicroTriangleVertexBarycentricNV; + break; + + case glslang::EOpFetchMicroTriangleVertexPositionNV: + typeId = builder.makeVectorType(builder.makeFloatType(32), 3); + opCode = spv::OpFetchMicroTriangleVertexPositionNV; + break; + default: return 0; } @@ -8512,7 +9222,6 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: } } -#ifndef GLSLANG_WEB // Decode the return types that were structures switch (op) { case glslang::EOpAddCarry: @@ -8542,7 +9251,6 @@ spv::Id TGlslangToSpvTraverser::createMiscOperation(glslang::TOperator op, spv:: default: break; } -#endif return builder.setPrecision(id, precision); } @@ -8587,7 +9295,6 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv: builder.createMemoryBarrier(spv::ScopeWorkgroup, spv::MemorySemanticsAllMemory | spv::MemorySemanticsAcquireReleaseMask); return 0; -#ifndef GLSLANG_WEB case glslang::EOpMemoryBarrierAtomicCounter: builder.createMemoryBarrier(memoryBarrierScope, spv::MemorySemanticsAtomicCounterMemoryMask | spv::MemorySemanticsAcquireReleaseMask); @@ -8706,7 +9413,30 @@ spv::Id TGlslangToSpvTraverser::createNoArgOperation(glslang::TOperator op, spv: builder.addCapability(spv::CapabilityShaderClockKHR); return builder.createOp(spv::OpReadClockKHR, typeId, args); } -#endif + case glslang::EOpStencilAttachmentReadEXT: + case glslang::EOpDepthAttachmentReadEXT: + { + builder.addExtension(spv::E_SPV_EXT_shader_tile_image); + + spv::Decoration precision; + spv::Op spv_op; + if (op == glslang::EOpStencilAttachmentReadEXT) + { + precision = spv::DecorationRelaxedPrecision; + spv_op = spv::OpStencilAttachmentReadEXT; + builder.addCapability(spv::CapabilityTileImageStencilReadAccessEXT); + } + else + { + precision = spv::NoPrecision; + spv_op = spv::OpDepthAttachmentReadEXT; + builder.addCapability(spv::CapabilityTileImageDepthReadAccessEXT); + } + + std::vector args; // Dummy args + spv::Id result = builder.createOp(spv_op, typeId, args); + return builder.setPrecision(result, precision); + } default: break; } @@ -8728,7 +9458,32 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol // it was not found, create it spv::BuiltIn builtIn = TranslateBuiltInDecoration(symbol->getQualifier().builtIn, false); auto forcedType = getForcedType(symbol->getQualifier().builtIn, symbol->getType()); + + // There are pairs of symbols that map to the same SPIR-V built-in: + // gl_ObjectToWorldEXT and gl_ObjectToWorld3x4EXT, and gl_WorldToObjectEXT + // and gl_WorldToObject3x4EXT. SPIR-V forbids having two OpVariables + // with the same BuiltIn in the same storage class, so we must re-use one. + const bool mayNeedToReuseBuiltIn = + builtIn == spv::BuiltInObjectToWorldKHR || + builtIn == spv::BuiltInWorldToObjectKHR; + + if (mayNeedToReuseBuiltIn) { + auto iter = builtInVariableIds.find(uint32_t(builtIn)); + if (builtInVariableIds.end() != iter) { + id = iter->second; + symbolValues[symbol->getId()] = id; + if (forcedType.second != spv::NoType) + forceType[id] = forcedType.second; + return id; + } + } + id = createSpvVariable(symbol, forcedType.first); + + if (mayNeedToReuseBuiltIn) { + builtInVariableIds.insert({uint32_t(builtIn), id}); + } + symbolValues[symbol->getId()] = id; if (forcedType.second != spv::NoType) forceType[id] = forcedType.second; @@ -8737,13 +9492,11 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol builder.addDecoration(id, TranslatePrecisionDecoration(symbol->getType())); builder.addDecoration(id, TranslateInterpolationDecoration(symbol->getType().getQualifier())); builder.addDecoration(id, TranslateAuxiliaryStorageDecoration(symbol->getType().getQualifier())); -#ifndef GLSLANG_WEB addMeshNVDecoration(id, /*member*/ -1, symbol->getType().getQualifier()); if (symbol->getQualifier().hasComponent()) builder.addDecoration(id, spv::DecorationComponent, symbol->getQualifier().layoutComponent); if (symbol->getQualifier().hasIndex()) builder.addDecoration(id, spv::DecorationIndex, symbol->getQualifier().layoutIndex); -#endif if (symbol->getType().getQualifier().hasSpecConstantId()) builder.addDecoration(id, spv::DecorationSpecId, symbol->getType().getQualifier().layoutSpecConstantId); // atomic counters use this: @@ -8752,13 +9505,17 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol } if (symbol->getQualifier().hasLocation()) { - if (!(glslangIntermediate->isRayTracingStage() && glslangIntermediate->IsRequestedExtension(glslang::E_GL_EXT_ray_tracing) + if (!(glslangIntermediate->isRayTracingStage() && + (glslangIntermediate->IsRequestedExtension(glslang::E_GL_EXT_ray_tracing) || + glslangIntermediate->IsRequestedExtension(glslang::E_GL_NV_shader_invocation_reorder)) && (builder.getStorageClass(id) == spv::StorageClassRayPayloadKHR || builder.getStorageClass(id) == spv::StorageClassIncomingRayPayloadKHR || builder.getStorageClass(id) == spv::StorageClassCallableDataKHR || - builder.getStorageClass(id) == spv::StorageClassIncomingCallableDataKHR))) { - // Location values are used to link TraceRayKHR and ExecuteCallableKHR to corresponding variables - // but are not valid in SPIRV since they are supported only for Input/Output Storage classes. + builder.getStorageClass(id) == spv::StorageClassIncomingCallableDataKHR || + builder.getStorageClass(id) == spv::StorageClassHitObjectAttributeNV))) { + // Location values are used to link TraceRayKHR/ExecuteCallableKHR/HitObjectGetAttributesNV + // to corresponding variables but are not valid in SPIRV since they are supported only + // for Input/Output Storage classes. builder.addDecoration(id, spv::DecorationLocation, symbol->getQualifier().layoutLocation); } } @@ -8804,11 +9561,11 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol // Add volatile decoration to HelperInvocation for spirv1.6 and beyond if (builtIn == spv::BuiltInHelperInvocation && + !glslangIntermediate->usingVulkanMemoryModel() && glslangIntermediate->getSpv().spv >= glslang::EShTargetSpv_1_6) { builder.addDecoration(id, spv::DecorationVolatile); } -#ifndef GLSLANG_WEB // Subgroup builtins which have input storage class are volatile for ray tracing stages. if (symbol->getType().isImage() || symbol->getQualifier().isPipeInput()) { std::vector memory; @@ -8857,6 +9614,12 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol builder.addExtension(spv::E_SPV_NV_fragment_shader_barycentric); } + if (symbol->getQualifier().pervertexEXT) { + builder.addDecoration(id, spv::DecorationPerVertexKHR); + builder.addCapability(spv::CapabilityFragmentBarycentricKHR); + builder.addExtension(spv::E_SPV_KHR_fragment_shader_barycentric); + } + if (glslangIntermediate->getHlslFunctionality1() && symbol->getType().getQualifier().semanticName != nullptr) { builder.addExtension("SPV_GOOGLE_hlsl_functionality1"); builder.addDecoration(id, (spv::Decoration)spv::DecorationHlslSemanticGOOGLE, @@ -8868,63 +9631,31 @@ spv::Id TGlslangToSpvTraverser::getSymbolId(const glslang::TIntermSymbol* symbol spv::DecorationRestrictPointerEXT : spv::DecorationAliasedPointerEXT); } - // - // Add SPIR-V decorations for structure (GL_EXT_spirv_intrinsics) - // - if (symbol->getType().getQualifier().hasSprivDecorate()) { - const glslang::TSpirvDecorate& spirvDecorate = symbol->getType().getQualifier().getSpirvDecorate(); - - // Add spirv_decorate - for (auto& decorate : spirvDecorate.decorates) { - if (!decorate.second.empty()) { - std::vector literals; - TranslateLiterals(decorate.second, literals); - builder.addDecoration(id, static_cast(decorate.first), literals); - } - else - builder.addDecoration(id, static_cast(decorate.first)); - } - - // Add spirv_decorate_id - for (auto& decorateId : spirvDecorate.decorateIds) { - std::vector operandIds; - assert(!decorateId.second.empty()); - for (auto extraOperand : decorateId.second) { - if (extraOperand->getQualifier().isSpecConstant()) - operandIds.push_back(getSymbolId(extraOperand->getAsSymbolNode())); - else - operandIds.push_back(createSpvConstant(*extraOperand)); - } - builder.addDecorationId(id, static_cast(decorateId.first), operandIds); - } - - // Add spirv_decorate_string - for (auto& decorateString : spirvDecorate.decorateStrings) { - std::vector strings; - assert(!decorateString.second.empty()); - for (auto extraOperand : decorateString.second) { - const char* string = extraOperand->getConstArray()[0].getSConst()->c_str(); - strings.push_back(string); - } - builder.addDecoration(id, static_cast(decorateString.first), strings); - } - } -#endif + // Add SPIR-V decorations (GL_EXT_spirv_intrinsics) + if (symbol->getType().getQualifier().hasSpirvDecorate()) + applySpirvDecorate(symbol->getType(), id, {}); return id; } -#ifndef GLSLANG_WEB // add per-primitive, per-view. per-task decorations to a struct member (member >= 0) or an object void TGlslangToSpvTraverser::addMeshNVDecoration(spv::Id id, int member, const glslang::TQualifier& qualifier) { + bool isMeshShaderExt = (glslangIntermediate->getRequestedExtensions().find(glslang::E_GL_EXT_mesh_shader) != + glslangIntermediate->getRequestedExtensions().end()); + if (member >= 0) { if (qualifier.perPrimitiveNV) { // Need to add capability/extension for fragment shader. // Mesh shader already adds this by default. if (glslangIntermediate->getStage() == EShLangFragment) { - builder.addCapability(spv::CapabilityMeshShadingNV); - builder.addExtension(spv::E_SPV_NV_mesh_shader); + if(isMeshShaderExt) { + builder.addCapability(spv::CapabilityMeshShadingEXT); + builder.addExtension(spv::E_SPV_EXT_mesh_shader); + } else { + builder.addCapability(spv::CapabilityMeshShadingNV); + builder.addExtension(spv::E_SPV_NV_mesh_shader); + } } builder.addMemberDecoration(id, (unsigned)member, spv::DecorationPerPrimitiveNV); } @@ -8937,8 +9668,13 @@ void TGlslangToSpvTraverser::addMeshNVDecoration(spv::Id id, int member, const g // Need to add capability/extension for fragment shader. // Mesh shader already adds this by default. if (glslangIntermediate->getStage() == EShLangFragment) { - builder.addCapability(spv::CapabilityMeshShadingNV); - builder.addExtension(spv::E_SPV_NV_mesh_shader); + if(isMeshShaderExt) { + builder.addCapability(spv::CapabilityMeshShadingEXT); + builder.addExtension(spv::E_SPV_EXT_mesh_shader); + } else { + builder.addCapability(spv::CapabilityMeshShadingNV); + builder.addExtension(spv::E_SPV_NV_mesh_shader); + } } builder.addDecoration(id, spv::DecorationPerPrimitiveNV); } @@ -8948,7 +9684,20 @@ void TGlslangToSpvTraverser::addMeshNVDecoration(spv::Id id, int member, const g builder.addDecoration(id, spv::DecorationPerTaskNV); } } -#endif + +void TGlslangToSpvTraverser::addImageProcessingQCOMDecoration(spv::Id id, spv::Decoration decor) +{ + spv::Op opc = builder.getOpCode(id); + if (opc == spv::OpSampledImage) { + id = builder.getIdOperand(id, 0); + opc = builder.getOpCode(id); + } + + if (opc == spv::OpLoad) { + spv::Id texid = builder.getIdOperand(id, 0); + builder.addDecoration(texid, decor); + } +} // Make a full tree of instructions to build a SPIR-V specialization constant, // or regular constant if possible. @@ -9076,17 +9825,20 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla case glslang::EbtBool: spvConsts.push_back(builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst())); break; -#ifndef GLSLANG_WEB case glslang::EbtInt8: + builder.addCapability(spv::CapabilityInt8); spvConsts.push_back(builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const())); break; case glslang::EbtUint8: + builder.addCapability(spv::CapabilityInt8); spvConsts.push_back(builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const())); break; case glslang::EbtInt16: + builder.addCapability(spv::CapabilityInt16); spvConsts.push_back(builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const())); break; case glslang::EbtUint16: + builder.addCapability(spv::CapabilityInt16); spvConsts.push_back(builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const())); break; case glslang::EbtInt64: @@ -9099,9 +9851,9 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla spvConsts.push_back(builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst())); break; case glslang::EbtFloat16: + builder.addCapability(spv::CapabilityFloat16); spvConsts.push_back(builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst())); break; -#endif default: assert(0); break; @@ -9125,17 +9877,20 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla case glslang::EbtBool: scalar = builder.makeBoolConstant(zero ? false : consts[nextConst].getBConst(), specConstant); break; -#ifndef GLSLANG_WEB case glslang::EbtInt8: + builder.addCapability(spv::CapabilityInt8); scalar = builder.makeInt8Constant(zero ? 0 : consts[nextConst].getI8Const(), specConstant); break; case glslang::EbtUint8: + builder.addCapability(spv::CapabilityInt8); scalar = builder.makeUint8Constant(zero ? 0 : consts[nextConst].getU8Const(), specConstant); break; case glslang::EbtInt16: + builder.addCapability(spv::CapabilityInt16); scalar = builder.makeInt16Constant(zero ? 0 : consts[nextConst].getI16Const(), specConstant); break; case glslang::EbtUint16: + builder.addCapability(spv::CapabilityInt16); scalar = builder.makeUint16Constant(zero ? 0 : consts[nextConst].getU16Const(), specConstant); break; case glslang::EbtInt64: @@ -9148,13 +9903,13 @@ spv::Id TGlslangToSpvTraverser::createSpvConstantFromConstUnionArray(const glsla scalar = builder.makeDoubleConstant(zero ? 0.0 : consts[nextConst].getDConst(), specConstant); break; case glslang::EbtFloat16: + builder.addCapability(spv::CapabilityFloat16); scalar = builder.makeFloat16Constant(zero ? 0.0F : (float)consts[nextConst].getDConst(), specConstant); break; case glslang::EbtReference: scalar = builder.makeUint64Constant(zero ? 0 : consts[nextConst].getU64Const(), specConstant); scalar = builder.createUnaryOp(spv::OpBitcast, typeId, scalar); break; -#endif case glslang::EbtString: scalar = builder.getStringId(consts[nextConst].getSConst()->c_str()); break; @@ -9302,7 +10057,6 @@ spv::Id TGlslangToSpvTraverser::createShortCircuit(glslang::TOperator op, glslan return builder.createOp(spv::OpPhi, boolTypeId, phiOperands); } -#ifndef GLSLANG_WEB // Return type Id of the imported set of extended instructions corresponds to the name. // Import this set if it has not been imported yet. spv::Id TGlslangToSpvTraverser::getExtBuiltins(const char* name) @@ -9316,7 +10070,6 @@ spv::Id TGlslangToSpvTraverser::getExtBuiltins(const char* name) return extBuiltins; } } -#endif }; // end anonymous namespace @@ -9345,31 +10098,36 @@ int GetSpirvGeneratorVersion() // return 7; // GLSL volatile keyword maps to both SPIR-V decorations Volatile and Coherent // return 8; // switch to new dead block eliminator; use OpUnreachable // return 9; // don't include opaque function parameters in OpEntryPoint global's operand list - return 10; // Generate OpFUnordNotEqual for != comparisons + // return 10; // Generate OpFUnordNotEqual for != comparisons + return 11; // Make OpEmitMeshTasksEXT a terminal instruction } // Write SPIR-V out to a binary file -void OutputSpvBin(const std::vector& spirv, const char* baseName) +bool OutputSpvBin(const std::vector& spirv, const char* baseName) { std::ofstream out; out.open(baseName, std::ios::binary | std::ios::out); - if (out.fail()) + if (out.fail()) { printf("ERROR: Failed to open file: %s\n", baseName); + return false; + } for (int i = 0; i < (int)spirv.size(); ++i) { unsigned int word = spirv[i]; out.write((const char*)&word, 4); } out.close(); + return true; } // Write SPIR-V out to a text file with 32-bit hexadecimal words -void OutputSpvHex(const std::vector& spirv, const char* baseName, const char* varName) +bool OutputSpvHex(const std::vector& spirv, const char* baseName, const char* varName) { -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) std::ofstream out; out.open(baseName, std::ios::binary | std::ios::out); - if (out.fail()) + if (out.fail()) { printf("ERROR: Failed to open file: %s\n", baseName); + return false; + } out << "\t// " << GetSpirvGeneratorVersion() << GLSLANG_VERSION_MAJOR << "." << GLSLANG_VERSION_MINOR << "." << GLSLANG_VERSION_PATCH << @@ -9395,7 +10153,7 @@ void OutputSpvHex(const std::vector& spirv, const char* baseName, out << std::endl; } out.close(); -#endif + return true; } // @@ -9412,7 +10170,7 @@ void GlslangToSpv(const TIntermediate& intermediate, std::vector& { TIntermNode* root = intermediate.getTreeRoot(); - if (root == 0) + if (root == nullptr) return; SpvOptions defaultOptions; @@ -9423,7 +10181,7 @@ void GlslangToSpv(const TIntermediate& intermediate, std::vector& TGlslangToSpvTraverser it(intermediate.getSpv().spv, &intermediate, logger, *options); root->traverse(&it); - it.finishSpv(); + it.finishSpv(options->compileOnly); it.dumpSpv(spirv); #if ENABLE_OPT diff --git a/src/libraries/glslang/SPIRV/GlslangToSpv.h b/src/libraries/glslang/SPIRV/GlslangToSpv.h index 86e1c23bf..1b9ef3c51 100644 --- a/src/libraries/glslang/SPIRV/GlslangToSpv.h +++ b/src/libraries/glslang/SPIRV/GlslangToSpv.h @@ -35,19 +35,25 @@ #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 #include #include "Logger.h" namespace glslang { +class TIntermediate; + +struct SpvOptions { + bool generateDebugInfo {false}; + bool stripDebugInfo {false}; + bool disableOptimizer {true}; + bool optimizeSize {false}; + bool disassemble {false}; + bool validate {false}; + bool emitNonSemanticShaderDebugInfo {false}; + bool emitNonSemanticShaderDebugSource{ false }; + bool compileOnly{false}; +}; void GetSpirvVersion(std::string&); int GetSpirvGeneratorVersion(); @@ -55,7 +61,7 @@ void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector& spirv, spv::SpvBuildLogger* logger, SpvOptions* options = nullptr); -void OutputSpvBin(const std::vector& spirv, const char* baseName); -void OutputSpvHex(const std::vector& spirv, const char* baseName, const char* varName); +bool OutputSpvBin(const std::vector& spirv, const char* baseName); +bool OutputSpvHex(const std::vector& spirv, const char* baseName, const char* varName); } diff --git a/src/libraries/glslang/SPIRV/Logger.cpp b/src/libraries/glslang/SPIRV/Logger.cpp index cdc8469c4..48bd4e3ad 100644 --- a/src/libraries/glslang/SPIRV/Logger.cpp +++ b/src/libraries/glslang/SPIRV/Logger.cpp @@ -32,8 +32,6 @@ // 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 @@ -68,5 +66,3 @@ std::string SpvBuildLogger::getAllMessages() const { } } // end spv namespace - -#endif diff --git a/src/libraries/glslang/SPIRV/Logger.h b/src/libraries/glslang/SPIRV/Logger.h index 411367c03..2e4ddaf51 100644 --- a/src/libraries/glslang/SPIRV/Logger.h +++ b/src/libraries/glslang/SPIRV/Logger.h @@ -46,14 +46,6 @@ 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. @@ -67,7 +59,6 @@ class SpvBuildLogger { // Returns all messages accumulated in the order of: // TBD functionalities, missing functionalities, warnings, errors. std::string getAllMessages() const; -#endif private: SpvBuildLogger(const SpvBuildLogger&); diff --git a/src/libraries/glslang/SPIRV/NonSemanticDebugPrintf.h b/src/libraries/glslang/SPIRV/NonSemanticDebugPrintf.h index 83796d75e..3ca7247f2 100644 --- a/src/libraries/glslang/SPIRV/NonSemanticDebugPrintf.h +++ b/src/libraries/glslang/SPIRV/NonSemanticDebugPrintf.h @@ -1,5 +1,5 @@ // Copyright (c) 2020 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 @@ -7,15 +7,15 @@ // 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. @@ -23,7 +23,7 @@ // 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 SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ #define SPIRV_UNIFIED1_NonSemanticDebugPrintf_H_ diff --git a/src/libraries/glslang/SPIRV/NonSemanticShaderDebugInfo100.h b/src/libraries/glslang/SPIRV/NonSemanticShaderDebugInfo100.h new file mode 100644 index 000000000..f74abcb64 --- /dev/null +++ b/src/libraries/glslang/SPIRV/NonSemanticShaderDebugInfo100.h @@ -0,0 +1,171 @@ +// Copyright (c) 2018 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 SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ +#define SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +enum { + NonSemanticShaderDebugInfo100Version = 100, + NonSemanticShaderDebugInfo100Version_BitWidthPadding = 0x7fffffff +}; +enum { + NonSemanticShaderDebugInfo100Revision = 6, + NonSemanticShaderDebugInfo100Revision_BitWidthPadding = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100Instructions { + NonSemanticShaderDebugInfo100DebugInfoNone = 0, + NonSemanticShaderDebugInfo100DebugCompilationUnit = 1, + NonSemanticShaderDebugInfo100DebugTypeBasic = 2, + NonSemanticShaderDebugInfo100DebugTypePointer = 3, + NonSemanticShaderDebugInfo100DebugTypeQualifier = 4, + NonSemanticShaderDebugInfo100DebugTypeArray = 5, + NonSemanticShaderDebugInfo100DebugTypeVector = 6, + NonSemanticShaderDebugInfo100DebugTypedef = 7, + NonSemanticShaderDebugInfo100DebugTypeFunction = 8, + NonSemanticShaderDebugInfo100DebugTypeEnum = 9, + NonSemanticShaderDebugInfo100DebugTypeComposite = 10, + NonSemanticShaderDebugInfo100DebugTypeMember = 11, + NonSemanticShaderDebugInfo100DebugTypeInheritance = 12, + NonSemanticShaderDebugInfo100DebugTypePtrToMember = 13, + NonSemanticShaderDebugInfo100DebugTypeTemplate = 14, + NonSemanticShaderDebugInfo100DebugTypeTemplateParameter = 15, + NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter = 16, + NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack = 17, + NonSemanticShaderDebugInfo100DebugGlobalVariable = 18, + NonSemanticShaderDebugInfo100DebugFunctionDeclaration = 19, + NonSemanticShaderDebugInfo100DebugFunction = 20, + NonSemanticShaderDebugInfo100DebugLexicalBlock = 21, + NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator = 22, + NonSemanticShaderDebugInfo100DebugScope = 23, + NonSemanticShaderDebugInfo100DebugNoScope = 24, + NonSemanticShaderDebugInfo100DebugInlinedAt = 25, + NonSemanticShaderDebugInfo100DebugLocalVariable = 26, + NonSemanticShaderDebugInfo100DebugInlinedVariable = 27, + NonSemanticShaderDebugInfo100DebugDeclare = 28, + NonSemanticShaderDebugInfo100DebugValue = 29, + NonSemanticShaderDebugInfo100DebugOperation = 30, + NonSemanticShaderDebugInfo100DebugExpression = 31, + NonSemanticShaderDebugInfo100DebugMacroDef = 32, + NonSemanticShaderDebugInfo100DebugMacroUndef = 33, + NonSemanticShaderDebugInfo100DebugImportedEntity = 34, + NonSemanticShaderDebugInfo100DebugSource = 35, + NonSemanticShaderDebugInfo100DebugFunctionDefinition = 101, + NonSemanticShaderDebugInfo100DebugSourceContinued = 102, + NonSemanticShaderDebugInfo100DebugLine = 103, + NonSemanticShaderDebugInfo100DebugNoLine = 104, + NonSemanticShaderDebugInfo100DebugBuildIdentifier = 105, + NonSemanticShaderDebugInfo100DebugStoragePath = 106, + NonSemanticShaderDebugInfo100DebugEntryPoint = 107, + NonSemanticShaderDebugInfo100DebugTypeMatrix = 108, + NonSemanticShaderDebugInfo100InstructionsMax = 0x7fffffff +}; + + +enum NonSemanticShaderDebugInfo100DebugInfoFlags { + NonSemanticShaderDebugInfo100None = 0x0000, + NonSemanticShaderDebugInfo100FlagIsProtected = 0x01, + NonSemanticShaderDebugInfo100FlagIsPrivate = 0x02, + NonSemanticShaderDebugInfo100FlagIsPublic = 0x03, + NonSemanticShaderDebugInfo100FlagIsLocal = 0x04, + NonSemanticShaderDebugInfo100FlagIsDefinition = 0x08, + NonSemanticShaderDebugInfo100FlagFwdDecl = 0x10, + NonSemanticShaderDebugInfo100FlagArtificial = 0x20, + NonSemanticShaderDebugInfo100FlagExplicit = 0x40, + NonSemanticShaderDebugInfo100FlagPrototyped = 0x80, + NonSemanticShaderDebugInfo100FlagObjectPointer = 0x100, + NonSemanticShaderDebugInfo100FlagStaticMember = 0x200, + NonSemanticShaderDebugInfo100FlagIndirectVariable = 0x400, + NonSemanticShaderDebugInfo100FlagLValueReference = 0x800, + NonSemanticShaderDebugInfo100FlagRValueReference = 0x1000, + NonSemanticShaderDebugInfo100FlagIsOptimized = 0x2000, + NonSemanticShaderDebugInfo100FlagIsEnumClass = 0x4000, + NonSemanticShaderDebugInfo100FlagTypePassByValue = 0x8000, + NonSemanticShaderDebugInfo100FlagTypePassByReference = 0x10000, + NonSemanticShaderDebugInfo100FlagUnknownPhysicalLayout = 0x20000, + NonSemanticShaderDebugInfo100DebugInfoFlagsMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100BuildIdentifierFlags { + NonSemanticShaderDebugInfo100IdentifierPossibleDuplicates = 0x01, + NonSemanticShaderDebugInfo100BuildIdentifierFlagsMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncoding { + NonSemanticShaderDebugInfo100Unspecified = 0, + NonSemanticShaderDebugInfo100Address = 1, + NonSemanticShaderDebugInfo100Boolean = 2, + NonSemanticShaderDebugInfo100Float = 3, + NonSemanticShaderDebugInfo100Signed = 4, + NonSemanticShaderDebugInfo100SignedChar = 5, + NonSemanticShaderDebugInfo100Unsigned = 6, + NonSemanticShaderDebugInfo100UnsignedChar = 7, + NonSemanticShaderDebugInfo100DebugBaseTypeAttributeEncodingMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugCompositeType { + NonSemanticShaderDebugInfo100Class = 0, + NonSemanticShaderDebugInfo100Structure = 1, + NonSemanticShaderDebugInfo100Union = 2, + NonSemanticShaderDebugInfo100DebugCompositeTypeMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugTypeQualifier { + NonSemanticShaderDebugInfo100ConstType = 0, + NonSemanticShaderDebugInfo100VolatileType = 1, + NonSemanticShaderDebugInfo100RestrictType = 2, + NonSemanticShaderDebugInfo100AtomicType = 3, + NonSemanticShaderDebugInfo100DebugTypeQualifierMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugOperation { + NonSemanticShaderDebugInfo100Deref = 0, + NonSemanticShaderDebugInfo100Plus = 1, + NonSemanticShaderDebugInfo100Minus = 2, + NonSemanticShaderDebugInfo100PlusUconst = 3, + NonSemanticShaderDebugInfo100BitPiece = 4, + NonSemanticShaderDebugInfo100Swap = 5, + NonSemanticShaderDebugInfo100Xderef = 6, + NonSemanticShaderDebugInfo100StackValue = 7, + NonSemanticShaderDebugInfo100Constu = 8, + NonSemanticShaderDebugInfo100Fragment = 9, + NonSemanticShaderDebugInfo100DebugOperationMax = 0x7fffffff +}; + +enum NonSemanticShaderDebugInfo100DebugImportedEntity { + NonSemanticShaderDebugInfo100ImportedModule = 0, + NonSemanticShaderDebugInfo100ImportedDeclaration = 1, + NonSemanticShaderDebugInfo100DebugImportedEntityMax = 0x7fffffff +}; + + +#ifdef __cplusplus +} +#endif + +#endif // SPIRV_UNIFIED1_NonSemanticShaderDebugInfo100_H_ diff --git a/src/libraries/glslang/SPIRV/SPVRemapper.cpp b/src/libraries/glslang/SPIRV/SPVRemapper.cpp index 56d6d5d4a..f8f50a951 100644 --- a/src/libraries/glslang/SPIRV/SPVRemapper.cpp +++ b/src/libraries/glslang/SPIRV/SPVRemapper.cpp @@ -36,10 +36,6 @@ #include "SPVRemapper.h" #include "doc.h" -#if !defined (use_cpp11) -// ... not supported before C++11 -#else // defined (use_cpp11) - #include #include #include "../glslang/Include/Common.h" @@ -160,15 +156,29 @@ namespace spv { } // Is this an opcode we should remove when using --strip? - bool spirvbin_t::isStripOp(spv::Op opCode) const + bool spirvbin_t::isStripOp(spv::Op opCode, unsigned start) const { switch (opCode) { case spv::OpSource: case spv::OpSourceExtension: case spv::OpName: case spv::OpMemberName: - case spv::OpLine: return true; - default: return false; + case spv::OpLine : + { + const std::string name = literalString(start + 2); + + std::vector::const_iterator it; + for (it = stripWhiteList.begin(); it < stripWhiteList.end(); it++) + { + if (name.find(*it) != std::string::npos) { + return false; + } + } + + return true; + } + default : + return false; } } @@ -297,15 +307,21 @@ namespace spv { std::string spirvbin_t::literalString(unsigned word) const { std::string literal; + const spirword_t * pos = spv.data() + word; literal.reserve(16); - const char* bytes = reinterpret_cast(spv.data() + word); - - while (bytes && *bytes) - literal += *bytes++; - - return literal; + do { + spirword_t word = *pos; + for (int i = 0; i < 4; i++) { + char c = word & 0xff; + if (c == '\0') + return literal; + literal += c; + word >>= 8; + } + pos++; + } while (true); } void spirvbin_t::applyMap() @@ -366,7 +382,7 @@ namespace spv { process( [&](spv::Op opCode, unsigned start) { // remember opcodes we want to strip later - if (isStripOp(opCode)) + if (isStripOp(opCode, start)) stripInst(start); return true; }, @@ -664,6 +680,7 @@ namespace spv { case spv::OperandKernelEnqueueFlags: case spv::OperandKernelProfilingInfo: case spv::OperandCapability: + case spv::OperandCooperativeMatrixOperands: ++word; break; @@ -1488,14 +1505,23 @@ namespace spv { } // remap from a memory image - void spirvbin_t::remap(std::vector& in_spv, std::uint32_t opts) + void spirvbin_t::remap(std::vector& in_spv, const std::vector& whiteListStrings, + std::uint32_t opts) { + stripWhiteList = whiteListStrings; spv.swap(in_spv); remap(opts); spv.swap(in_spv); } -} // namespace SPV + // remap from a memory image - legacy interface without white list + void spirvbin_t::remap(std::vector& in_spv, std::uint32_t opts) + { + stripWhiteList.clear(); + spv.swap(in_spv); + remap(opts); + spv.swap(in_spv); + } -#endif // defined (use_cpp11) +} // namespace SPV diff --git a/src/libraries/glslang/SPIRV/SPVRemapper.h b/src/libraries/glslang/SPIRV/SPVRemapper.h index d6b9c346d..33efe331e 100644 --- a/src/libraries/glslang/SPIRV/SPVRemapper.h +++ b/src/libraries/glslang/SPIRV/SPVRemapper.h @@ -43,12 +43,6 @@ 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: @@ -74,27 +68,6 @@ class spirvbin_base_t } // namespace SPV -#if !defined (use_cpp11) -#include -#include - -namespace spv { -class spirvbin_t : public spirvbin_base_t -{ -public: - spirvbin_t(int /*verbose = 0*/) { } - - void remap(std::vector& /*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 #include #include @@ -104,9 +77,9 @@ class spirvbin_t : public spirvbin_base_t #include #include "spirv.hpp" -#include "spvIR.h" namespace spv { +const Id NoResult = 0; // class to hold SPIR-V binary data for remapping, DCE, and debug stripping class spirvbin_t : public spirvbin_base_t @@ -118,6 +91,10 @@ class spirvbin_t : public spirvbin_base_t virtual ~spirvbin_t() { } // remap on an existing binary in memory + void remap(std::vector& spv, const std::vector& whiteListStrings, + std::uint32_t opts = DO_EVERYTHING); + + // remap on an existing binary in memory - legacy interface without white list void remap(std::vector& spv, std::uint32_t opts = DO_EVERYTHING); // Type for error/log handler functions @@ -180,6 +157,8 @@ class spirvbin_t : public spirvbin_base_t unsigned typeSizeInWords(spv::Id id) const; unsigned idTypeSizeInWords(spv::Id id) const; + bool isStripOp(spv::Op opCode, unsigned start) 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]); } @@ -249,6 +228,8 @@ class spirvbin_t : public spirvbin_base_t std::vector spv; // SPIR words + std::vector stripWhiteList; + namemap_t nameMap; // ID names from OpName // Since we want to also do binary ops, we can't use std::vector. we could use @@ -300,5 +281,4 @@ class spirvbin_t : public spirvbin_base_t } // namespace SPV -#endif // defined (use_cpp11) #endif // SPIRVREMAPPER_H diff --git a/src/libraries/glslang/SPIRV/SpvBuilder.cpp b/src/libraries/glslang/SPIRV/SpvBuilder.cpp index 838f916a0..b6752d2d7 100644 --- a/src/libraries/glslang/SPIRV/SpvBuilder.cpp +++ b/src/libraries/glslang/SPIRV/SpvBuilder.cpp @@ -46,10 +46,7 @@ #include #include "SpvBuilder.h" - -#ifndef GLSLANG_WEB #include "hex_float.h" -#endif #ifndef _WIN32 #include @@ -59,18 +56,21 @@ namespace spv { Builder::Builder(unsigned int spvVersion, unsigned int magicNumber, SpvBuildLogger* buildLogger) : spvVersion(spvVersion), - source(SourceLanguageUnknown), + sourceLang(SourceLanguageUnknown), sourceVersion(0), sourceFileStringId(NoResult), currentLine(0), currentFile(nullptr), + currentFileId(NoResult), + lastDebugScopeId(NoResult), emitOpLines(false), + emitNonSemanticShaderDebugInfo(false), addressModel(AddressingModelLogical), memoryModel(MemoryModelGLSL450), builderNumber(magicNumber), - buildPoint(0), + buildPoint(nullptr), uniqueId(0), - entryPointFunction(0), + entryPointFunction(nullptr), generatingOpCodeForSpecConst(false), logger(buildLogger) { @@ -98,8 +98,12 @@ void Builder::setLine(int lineNum) { if (lineNum != 0 && lineNum != currentLine) { currentLine = lineNum; - if (emitOpLines) - addLine(sourceFileStringId, currentLine, 0); + if (emitOpLines) { + if (emitNonSemanticShaderDebugInfo) + addDebugScopeAndLine(currentFileId, currentLine, 0); + else + addLine(sourceFileStringId, currentLine, 0); + } } } @@ -118,7 +122,10 @@ void Builder::setLine(int lineNum, const char* filename) currentFile = filename; if (emitOpLines) { spv::Id strId = getStringId(filename); - addLine(strId, currentLine, 0); + if (emitNonSemanticShaderDebugInfo) + addDebugScopeAndLine(strId, currentLine, 0); + else + addLine(strId, currentLine, 0); } } } @@ -132,15 +139,43 @@ void Builder::addLine(Id fileName, int lineNum, int column) buildPoint->addInstruction(std::unique_ptr(line)); } +void Builder::addDebugScopeAndLine(Id fileName, int lineNum, int column) +{ + assert(!currentDebugScopeId.empty()); + if (currentDebugScopeId.top() != lastDebugScopeId) { + spv::Id resultId = getUniqueId(); + Instruction* scopeInst = new Instruction(resultId, makeVoidType(), OpExtInst); + scopeInst->addIdOperand(nonSemanticShaderDebugInfo); + scopeInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugScope); + scopeInst->addIdOperand(currentDebugScopeId.top()); + buildPoint->addInstruction(std::unique_ptr(scopeInst)); + lastDebugScopeId = currentDebugScopeId.top(); + } + spv::Id resultId = getUniqueId(); + Instruction* lineInst = new Instruction(resultId, makeVoidType(), OpExtInst); + lineInst->addIdOperand(nonSemanticShaderDebugInfo); + lineInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLine); + lineInst->addIdOperand(makeDebugSource(fileName)); + lineInst->addIdOperand(makeUintConstant(lineNum)); + lineInst->addIdOperand(makeUintConstant(lineNum)); + lineInst->addIdOperand(makeUintConstant(column)); + lineInst->addIdOperand(makeUintConstant(column)); + buildPoint->addInstruction(std::unique_ptr(lineInst)); +} + // For creating new groupedTypes (will return old type if the requested one was already made). Id Builder::makeVoidType() { Instruction* type; if (groupedTypes[OpTypeVoid].size() == 0) { - type = new Instruction(getUniqueId(), NoType, OpTypeVoid); + Id typeId = getUniqueId(); + type = new Instruction(typeId, NoType, OpTypeVoid); groupedTypes[OpTypeVoid].push_back(type); constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); + // Core OpTypeVoid used for debug void type + if (emitNonSemanticShaderDebugInfo) + debugId[typeId] = typeId; } else type = groupedTypes[OpTypeVoid].back(); @@ -155,9 +190,16 @@ Id Builder::makeBoolType() groupedTypes[OpTypeBool].push_back(type); constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); + + if (emitNonSemanticShaderDebugInfo) { + auto const debugResultId = makeBoolDebugType(32); + debugId[type->getResultId()] = debugResultId; + } + } else type = groupedTypes[OpTypeBool].back(); + return type->getResultId(); } @@ -172,6 +214,12 @@ Id Builder::makeSamplerType() } else type = groupedTypes[OpTypeSampler].back(); + if (emitNonSemanticShaderDebugInfo) + { + auto const debugResultId = makeCompositeDebugType({}, "type.sampler", NonSemanticShaderDebugInfo100Structure, true); + debugId[type->getResultId()] = debugResultId; + } + return type->getResultId(); } @@ -194,6 +242,11 @@ Id Builder::makePointer(StorageClass storageClass, Id pointee) constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); + if (emitNonSemanticShaderDebugInfo) { + const Id debugResultId = makePointerDebugType(storageClass, pointee); + debugId[type->getResultId()] = debugResultId; + } + return type->getResultId(); } @@ -233,11 +286,6 @@ Id Builder::makePointerFromForwardPointer(StorageClass storageClass, Id forwardP Id Builder::makeIntegerType(int width, bool hasSign) { -#ifdef GLSLANG_WEB - assert(width == 32); - width = 32; -#endif - // try to find it Instruction* type; for (int t = 0; t < (int)groupedTypes[OpTypeInt].size(); ++t) { @@ -268,16 +316,17 @@ Id Builder::makeIntegerType(int width, bool hasSign) break; } + if (emitNonSemanticShaderDebugInfo) + { + auto const debugResultId = makeIntegerDebugType(width, hasSign); + debugId[type->getResultId()] = debugResultId; + } + return type->getResultId(); } Id Builder::makeFloatType(int width) { -#ifdef GLSLANG_WEB - assert(width == 32); - width = 32; -#endif - // try to find it Instruction* type; for (int t = 0; t < (int)groupedTypes[OpTypeFloat].size(); ++t) { @@ -305,6 +354,12 @@ Id Builder::makeFloatType(int width) break; } + if (emitNonSemanticShaderDebugInfo) + { + auto const debugResultId = makeFloatDebugType(width); + debugId[type->getResultId()] = debugResultId; + } + return type->getResultId(); } @@ -312,7 +367,7 @@ Id Builder::makeFloatType(int width) // See makeStructResultType() for non-decorated structs // needed as the result of some instructions, which does // check for duplicates. -Id Builder::makeStructType(const std::vector& members, const char* name) +Id Builder::makeStructType(const std::vector& members, const char* name, bool const compilerGenerated) { // Don't look for previous one, because in the general case, // structs can be duplicated except for decorations. @@ -326,6 +381,12 @@ Id Builder::makeStructType(const std::vector& members, const char* name) module.mapInstruction(type); addName(type->getResultId(), name); + if (emitNonSemanticShaderDebugInfo && !compilerGenerated) + { + auto const debugResultId = makeCompositeDebugType(members, name, NonSemanticShaderDebugInfo100Structure); + debugId[type->getResultId()] = debugResultId; + } + return type->getResultId(); } @@ -372,6 +433,12 @@ Id Builder::makeVectorType(Id component, int size) constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); + if (emitNonSemanticShaderDebugInfo) + { + auto const debugResultId = makeVectorDebugType(component, size); + debugId[type->getResultId()] = debugResultId; + } + return type->getResultId(); } @@ -398,18 +465,50 @@ Id Builder::makeMatrixType(Id component, int cols, int rows) constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); + if (emitNonSemanticShaderDebugInfo) + { + auto const debugResultId = makeMatrixDebugType(column, cols); + debugId[type->getResultId()] = debugResultId; + } + return type->getResultId(); } -Id Builder::makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols) +Id Builder::makeCooperativeMatrixTypeKHR(Id component, Id scope, Id rows, Id cols, Id use) { // try to find it Instruction* type; - for (int t = 0; t < (int)groupedTypes[OpTypeCooperativeMatrixNV].size(); ++t) { - type = groupedTypes[OpTypeCooperativeMatrixNV][t]; + for (int t = 0; t < (int)groupedTypes[OpTypeCooperativeMatrixKHR].size(); ++t) { + type = groupedTypes[OpTypeCooperativeMatrixKHR][t]; if (type->getIdOperand(0) == component && type->getIdOperand(1) == scope && type->getIdOperand(2) == rows && + type->getIdOperand(3) == cols && + type->getIdOperand(4) == use) + return type->getResultId(); + } + + // not found, make it + type = new Instruction(getUniqueId(), NoType, OpTypeCooperativeMatrixKHR); + type->addIdOperand(component); + type->addIdOperand(scope); + type->addIdOperand(rows); + type->addIdOperand(cols); + type->addIdOperand(use); + groupedTypes[OpTypeCooperativeMatrixKHR].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + + return type->getResultId(); +} + +Id Builder::makeCooperativeMatrixTypeNV(Id component, Id scope, Id rows, Id cols) +{ + // try to find it + Instruction* type; + for (int t = 0; t < (int)groupedTypes[OpTypeCooperativeMatrixNV].size(); ++t) { + type = groupedTypes[OpTypeCooperativeMatrixNV][t]; + if (type->getIdOperand(0) == component && type->getIdOperand(1) == scope && type->getIdOperand(2) == rows && type->getIdOperand(3) == cols) return type->getResultId(); } @@ -427,17 +526,28 @@ Id Builder::makeCooperativeMatrixType(Id component, Id scope, Id rows, Id cols) return type->getResultId(); } +Id Builder::makeCooperativeMatrixTypeWithSameShape(Id component, Id otherType) +{ + Instruction* instr = module.getInstruction(otherType); + if (instr->getOpCode() == OpTypeCooperativeMatrixNV) { + return makeCooperativeMatrixTypeNV(component, instr->getIdOperand(1), instr->getIdOperand(2), instr->getIdOperand(3)); + } else { + assert(instr->getOpCode() == OpTypeCooperativeMatrixKHR); + return makeCooperativeMatrixTypeKHR(component, instr->getIdOperand(1), instr->getIdOperand(2), instr->getIdOperand(3), instr->getIdOperand(4)); + } +} + Id Builder::makeGenericType(spv::Op opcode, std::vector& operands) { // try to find it Instruction* type; for (int t = 0; t < (int)groupedTypes[opcode].size(); ++t) { type = groupedTypes[opcode][t]; - if (type->getNumOperands() != operands.size()) + if (static_cast(type->getNumOperands()) != operands.size()) continue; // Number mismatch, find next bool match = true; - for (int op = 0; match && op < operands.size(); ++op) { + for (int op = 0; match && op < (int)operands.size(); ++op) { match = (operands[op].isId ? type->getIdOperand(op) : type->getImmediateOperand(op)) == operands[op].word; } if (match) @@ -446,7 +556,7 @@ Id Builder::makeGenericType(spv::Op opcode, std::vector& opera // not found, make it type = new Instruction(getUniqueId(), NoType, opcode); - for (int op = 0; op < operands.size(); ++op) { + for (size_t op = 0; op < operands.size(); ++op) { if (operands[op].isId) type->addIdOperand(operands[op].word); else @@ -484,6 +594,12 @@ Id Builder::makeArrayType(Id element, Id sizeId, int stride) constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); + if (emitNonSemanticShaderDebugInfo) + { + auto const debugResultId = makeArrayDebugType(element, sizeId); + debugId[type->getResultId()] = debugResultId; + } + return type->getResultId(); } @@ -494,6 +610,12 @@ Id Builder::makeRuntimeArray(Id element) constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); + if (emitNonSemanticShaderDebugInfo) + { + auto const debugResultId = makeArrayDebugType(element, makeUintConstant(0)); + debugId[type->getResultId()] = debugResultId; + } + return type->getResultId(); } @@ -513,11 +635,25 @@ Id Builder::makeFunctionType(Id returnType, const std::vector& paramTypes) } } if (! mismatch) + { + // If compiling HLSL, glslang will create a wrapper function around the entrypoint. Accordingly, a void(void) + // function type is created for the wrapper function. However, nonsemantic shader debug information is disabled + // while creating the HLSL wrapper. Consequently, if we encounter another void(void) function, we need to create + // the associated debug function type if it hasn't been created yet. + if(emitNonSemanticShaderDebugInfo && debugId[type->getResultId()] == 0) { + assert(sourceLang == spv::SourceLanguageHLSL); + assert(getTypeClass(returnType) == OpTypeVoid && paramTypes.size() == 0); + + Id debugTypeId = makeDebugFunctionType(returnType, {}); + debugId[type->getResultId()] = debugTypeId; + } return type->getResultId(); + } } // not found, make it - type = new Instruction(getUniqueId(), NoType, OpTypeFunction); + Id typeId = getUniqueId(); + type = new Instruction(typeId, NoType, OpTypeFunction); type->addIdOperand(returnType); for (int p = 0; p < (int)paramTypes.size(); ++p) type->addIdOperand(paramTypes[p]); @@ -525,9 +661,38 @@ Id Builder::makeFunctionType(Id returnType, const std::vector& paramTypes) constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); + // make debug type and map it + if (emitNonSemanticShaderDebugInfo) { + Id debugTypeId = makeDebugFunctionType(returnType, paramTypes); + debugId[typeId] = debugTypeId; + } + return type->getResultId(); } +Id Builder::makeDebugFunctionType(Id returnType, const std::vector& paramTypes) +{ + assert(debugId[returnType] != 0); + + Id typeId = getUniqueId(); + auto type = new Instruction(typeId, makeVoidType(), OpExtInst); + type->addIdOperand(nonSemanticShaderDebugInfo); + type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeFunction); + type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsPublic)); + type->addIdOperand(debugId[returnType]); + for (auto const paramType : paramTypes) { + if (isPointerType(paramType) || isArrayType(paramType)) { + type->addIdOperand(debugId[getContainedTypeId(paramType)]); + } + else { + type->addIdOperand(debugId[paramType]); + } + } + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + return typeId; +} + Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, bool ms, unsigned sampled, ImageFormat format) { @@ -561,7 +726,6 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); -#ifndef GLSLANG_WEB // deal with capabilities switch (dim) { case DimBuffer: @@ -607,7 +771,22 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo addCapability(CapabilityImageMSArray); } } -#endif + + if (emitNonSemanticShaderDebugInfo) + { + auto TypeName = [&dim]() -> char const* { + switch (dim) { + case Dim1D: return "type.1d.image"; + case Dim2D: return "type.2d.image"; + case Dim3D: return "type.3d.image"; + case DimCube: return "type.cube.image"; + default: return "type.image"; + } + }; + + auto const debugResultId = makeCompositeDebugType({}, TypeName(), NonSemanticShaderDebugInfo100Class, true); + debugId[type->getResultId()] = debugResultId; + } return type->getResultId(); } @@ -630,10 +809,439 @@ Id Builder::makeSampledImageType(Id imageType) constantsTypesGlobals.push_back(std::unique_ptr(type)); module.mapInstruction(type); + if (emitNonSemanticShaderDebugInfo) + { + auto const debugResultId = makeCompositeDebugType({}, "type.sampled.image", NonSemanticShaderDebugInfo100Class, true); + debugId[type->getResultId()] = debugResultId; + } + + return type->getResultId(); +} + +Id Builder::makeDebugInfoNone() +{ + if (debugInfoNone != 0) + return debugInfoNone; + + Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + inst->addIdOperand(nonSemanticShaderDebugInfo); + inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugInfoNone); + + constantsTypesGlobals.push_back(std::unique_ptr(inst)); + module.mapInstruction(inst); + + debugInfoNone = inst->getResultId(); + + return debugInfoNone; +} + +Id Builder::makeBoolDebugType(int const size) +{ + // try to find it + Instruction* type; + for (int t = 0; t < (int)groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].size(); ++t) { + type = groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic][t]; + if (type->getIdOperand(0) == getStringId("bool") && + type->getIdOperand(1) == static_cast(size) && + type->getIdOperand(2) == NonSemanticShaderDebugInfo100Boolean) + return type->getResultId(); + } + + type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->addIdOperand(nonSemanticShaderDebugInfo); + type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeBasic); + + type->addIdOperand(getStringId("bool")); // name id + type->addIdOperand(makeUintConstant(size)); // size id + type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100Boolean)); // encoding id + type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100None)); // flags id + + groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + + return type->getResultId(); +} + +Id Builder::makeIntegerDebugType(int const width, bool const hasSign) +{ + const char* typeName = nullptr; + switch (width) { + case 8: typeName = hasSign ? "int8_t" : "uint8_t"; break; + case 16: typeName = hasSign ? "int16_t" : "uint16_t"; break; + case 64: typeName = hasSign ? "int64_t" : "uint64_t"; break; + default: typeName = hasSign ? "int" : "uint"; + } + auto nameId = getStringId(typeName); + // try to find it + Instruction* type; + for (int t = 0; t < (int)groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].size(); ++t) { + type = groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic][t]; + if (type->getIdOperand(0) == nameId && + type->getIdOperand(1) == static_cast(width) && + type->getIdOperand(2) == (hasSign ? NonSemanticShaderDebugInfo100Signed : NonSemanticShaderDebugInfo100Unsigned)) + return type->getResultId(); + } + + // not found, make it + type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->addIdOperand(nonSemanticShaderDebugInfo); + type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeBasic); + type->addIdOperand(nameId); // name id + type->addIdOperand(makeUintConstant(width)); // size id + if(hasSign == true) { + type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100Signed)); // encoding id + } else { + type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100Unsigned)); // encoding id + } + type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100None)); // flags id + + groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + return type->getResultId(); } -#ifndef GLSLANG_WEB +Id Builder::makeFloatDebugType(int const width) +{ + const char* typeName = nullptr; + switch (width) { + case 16: typeName = "float16_t"; break; + case 64: typeName = "double"; break; + default: typeName = "float"; break; + } + auto nameId = getStringId(typeName); + // try to find it + Instruction* type; + for (int t = 0; t < (int)groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].size(); ++t) { + type = groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic][t]; + if (type->getIdOperand(0) == nameId && + type->getIdOperand(1) == static_cast(width) && + type->getIdOperand(2) == NonSemanticShaderDebugInfo100Float) + return type->getResultId(); + } + + // not found, make it + type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->addIdOperand(nonSemanticShaderDebugInfo); + type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeBasic); + type->addIdOperand(nameId); // name id + type->addIdOperand(makeUintConstant(width)); // size id + type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100Float)); // encoding id + type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100None)); // flags id + + groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeBasic].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + + return type->getResultId(); +} + +Id Builder::makeSequentialDebugType(Id const baseType, Id const componentCount, NonSemanticShaderDebugInfo100Instructions const sequenceType) +{ + assert(sequenceType == NonSemanticShaderDebugInfo100DebugTypeArray || + sequenceType == NonSemanticShaderDebugInfo100DebugTypeVector); + + // try to find it + Instruction* type; + for (int t = 0; t < (int)groupedDebugTypes[sequenceType].size(); ++t) { + type = groupedDebugTypes[sequenceType][t]; + if (type->getIdOperand(0) == baseType && + type->getIdOperand(1) == makeUintConstant(componentCount)) + return type->getResultId(); + } + + // not found, make it + type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->addIdOperand(nonSemanticShaderDebugInfo); + type->addImmediateOperand(sequenceType); + type->addIdOperand(debugId[baseType]); // base type + type->addIdOperand(componentCount); // component count + + groupedDebugTypes[sequenceType].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + + return type->getResultId(); +} + +Id Builder::makeArrayDebugType(Id const baseType, Id const componentCount) +{ + return makeSequentialDebugType(baseType, componentCount, NonSemanticShaderDebugInfo100DebugTypeArray); +} + +Id Builder::makeVectorDebugType(Id const baseType, int const componentCount) +{ + return makeSequentialDebugType(baseType, makeUintConstant(componentCount), NonSemanticShaderDebugInfo100DebugTypeVector); +} + +Id Builder::makeMatrixDebugType(Id const vectorType, int const vectorCount, bool columnMajor) +{ + // try to find it + Instruction* type; + for (int t = 0; t < (int)groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeMatrix].size(); ++t) { + type = groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeMatrix][t]; + if (type->getIdOperand(0) == vectorType && + type->getIdOperand(1) == makeUintConstant(vectorCount)) + return type->getResultId(); + } + + // not found, make it + type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->addIdOperand(nonSemanticShaderDebugInfo); + type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeMatrix); + type->addIdOperand(debugId[vectorType]); // vector type id + type->addIdOperand(makeUintConstant(vectorCount)); // component count id + type->addIdOperand(makeBoolConstant(columnMajor)); // column-major id + + groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeMatrix].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + + return type->getResultId(); +} + +Id Builder::makeMemberDebugType(Id const memberType, DebugTypeLoc const& debugTypeLoc) +{ + assert(debugId[memberType] != 0); + + Instruction* type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->addIdOperand(nonSemanticShaderDebugInfo); + type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeMember); + type->addIdOperand(getStringId(debugTypeLoc.name)); // name id + type->addIdOperand(debugId[memberType]); // type id + type->addIdOperand(makeDebugSource(sourceFileStringId)); // source id TODO: verify this works across include directives + type->addIdOperand(makeUintConstant(debugTypeLoc.line)); // line id TODO: currentLine is always zero + type->addIdOperand(makeUintConstant(debugTypeLoc.column)); // TODO: column id + type->addIdOperand(makeUintConstant(0)); // TODO: offset id + type->addIdOperand(makeUintConstant(0)); // TODO: size id + type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsPublic)); // flags id + + groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeMember].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + + return type->getResultId(); +} + +// Note: To represent a source language opaque type, this instruction must have no Members operands, Size operand must be +// DebugInfoNone, and Name must start with @ to avoid clashes with user defined names. +Id Builder::makeCompositeDebugType(std::vector const& memberTypes, char const*const name, + NonSemanticShaderDebugInfo100DebugCompositeType const tag, bool const isOpaqueType) +{ + // Create the debug member types. + std::vector memberDebugTypes; + for(auto const memberType : memberTypes) { + assert(debugTypeLocs.find(memberType) != debugTypeLocs.end()); + + // There _should_ be debug types for all the member types but currently buffer references + // do not have member debug info generated. + if (debugId[memberType]) + memberDebugTypes.emplace_back(makeMemberDebugType(memberType, debugTypeLocs[memberType])); + + // TODO: Need to rethink this method of passing location information. + // debugTypeLocs.erase(memberType); + } + + // Create The structure debug type. + Instruction* type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->addIdOperand(nonSemanticShaderDebugInfo); + type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypeComposite); + type->addIdOperand(getStringId(name)); // name id + type->addIdOperand(makeUintConstant(tag)); // tag id + type->addIdOperand(makeDebugSource(sourceFileStringId)); // source id TODO: verify this works across include directives + type->addIdOperand(makeUintConstant(currentLine)); // line id TODO: currentLine always zero? + type->addIdOperand(makeUintConstant(0)); // TODO: column id + type->addIdOperand(makeDebugCompilationUnit()); // scope id + if(isOpaqueType == true) { + // Prepend '@' to opaque types. + type->addIdOperand(getStringId('@' + std::string(name))); // linkage name id + type->addIdOperand(makeDebugInfoNone()); // size id + } else { + type->addIdOperand(getStringId(name)); // linkage name id + type->addIdOperand(makeUintConstant(0)); // TODO: size id + } + type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsPublic)); // flags id + assert(isOpaqueType == false || (isOpaqueType == true && memberDebugTypes.empty())); + for(auto const memberDebugType : memberDebugTypes) { + type->addIdOperand(memberDebugType); + } + + groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypeComposite].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + + return type->getResultId(); +} + +Id Builder::makePointerDebugType(StorageClass storageClass, Id const baseType) +{ + const Id debugBaseType = debugId[baseType]; + if (!debugBaseType) { + return makeDebugInfoNone(); + } + const Id scID = makeUintConstant(storageClass); + for (Instruction* otherType : groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypePointer]) { + if (otherType->getIdOperand(2) == debugBaseType && + otherType->getIdOperand(3) == scID) { + return otherType->getResultId(); + } + } + + Instruction* type = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + type->addIdOperand(nonSemanticShaderDebugInfo); + type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugTypePointer); + type->addIdOperand(debugBaseType); + type->addIdOperand(scID); + type->addIdOperand(makeUintConstant(0)); + + groupedDebugTypes[NonSemanticShaderDebugInfo100DebugTypePointer].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + + return type->getResultId(); +} + +Id Builder::makeDebugSource(const Id fileName) { + if (debugSourceId.find(fileName) != debugSourceId.end()) + return debugSourceId[fileName]; + spv::Id resultId = getUniqueId(); + Instruction* sourceInst = new Instruction(resultId, makeVoidType(), OpExtInst); + sourceInst->addIdOperand(nonSemanticShaderDebugInfo); + sourceInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugSource); + sourceInst->addIdOperand(fileName); + if (emitNonSemanticShaderDebugSource) { + spv::Id sourceId = 0; + if (fileName == sourceFileStringId) { + sourceId = getStringId(sourceText); + } else { + auto incItr = includeFiles.find(fileName); + assert(incItr != includeFiles.end()); + sourceId = getStringId(*incItr->second); + } + sourceInst->addIdOperand(sourceId); + } + constantsTypesGlobals.push_back(std::unique_ptr(sourceInst)); + module.mapInstruction(sourceInst); + debugSourceId[fileName] = resultId; + return resultId; +} + +Id Builder::makeDebugCompilationUnit() { + if (nonSemanticShaderCompilationUnitId != 0) + return nonSemanticShaderCompilationUnitId; + spv::Id resultId = getUniqueId(); + Instruction* sourceInst = new Instruction(resultId, makeVoidType(), OpExtInst); + sourceInst->addIdOperand(nonSemanticShaderDebugInfo); + sourceInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugCompilationUnit); + sourceInst->addIdOperand(makeUintConstant(1)); // TODO(greg-lunarg): Get rid of magic number + sourceInst->addIdOperand(makeUintConstant(4)); // TODO(greg-lunarg): Get rid of magic number + sourceInst->addIdOperand(makeDebugSource(sourceFileStringId)); + sourceInst->addIdOperand(makeUintConstant(sourceLang)); + constantsTypesGlobals.push_back(std::unique_ptr(sourceInst)); + module.mapInstruction(sourceInst); + nonSemanticShaderCompilationUnitId = resultId; + + // We can reasonably assume that makeDebugCompilationUnit will be called before any of + // debug-scope stack. Function scopes and lexical scopes will occur afterward. + assert(currentDebugScopeId.empty()); + currentDebugScopeId.push(nonSemanticShaderCompilationUnitId); + + return resultId; +} + +Id Builder::createDebugGlobalVariable(Id const type, char const*const name, Id const variable) +{ + assert(type != 0); + + Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + inst->addIdOperand(nonSemanticShaderDebugInfo); + inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugGlobalVariable); + inst->addIdOperand(getStringId(name)); // name id + inst->addIdOperand(type); // type id + inst->addIdOperand(makeDebugSource(sourceFileStringId)); // source id + inst->addIdOperand(makeUintConstant(currentLine)); // line id TODO: currentLine always zero? + inst->addIdOperand(makeUintConstant(0)); // TODO: column id + inst->addIdOperand(makeDebugCompilationUnit()); // scope id + inst->addIdOperand(getStringId(name)); // linkage name id + inst->addIdOperand(variable); // variable id + inst->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsDefinition)); // flags id + + constantsTypesGlobals.push_back(std::unique_ptr(inst)); + module.mapInstruction(inst); + + return inst->getResultId(); +} + +Id Builder::createDebugLocalVariable(Id type, char const*const name, size_t const argNumber) +{ + assert(name != nullptr); + assert(!currentDebugScopeId.empty()); + + Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + inst->addIdOperand(nonSemanticShaderDebugInfo); + inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLocalVariable); + inst->addIdOperand(getStringId(name)); // name id + inst->addIdOperand(type); // type id + inst->addIdOperand(makeDebugSource(sourceFileStringId)); // source id + inst->addIdOperand(makeUintConstant(currentLine)); // line id + inst->addIdOperand(makeUintConstant(0)); // TODO: column id + inst->addIdOperand(currentDebugScopeId.top()); // scope id + inst->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsLocal)); // flags id + if(argNumber != 0) { + inst->addIdOperand(makeUintConstant(argNumber)); + } + + constantsTypesGlobals.push_back(std::unique_ptr(inst)); + module.mapInstruction(inst); + + return inst->getResultId(); +} + +Id Builder::makeDebugExpression() +{ + if (debugExpression != 0) + return debugExpression; + + Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + inst->addIdOperand(nonSemanticShaderDebugInfo); + inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugExpression); + + constantsTypesGlobals.push_back(std::unique_ptr(inst)); + module.mapInstruction(inst); + + debugExpression = inst->getResultId(); + + return debugExpression; +} + +Id Builder::makeDebugDeclare(Id const debugLocalVariable, Id const pointer) +{ + Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + inst->addIdOperand(nonSemanticShaderDebugInfo); + inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugDeclare); + inst->addIdOperand(debugLocalVariable); // debug local variable id + inst->addIdOperand(pointer); // pointer to local variable id + inst->addIdOperand(makeDebugExpression()); // expression id + buildPoint->addInstruction(std::unique_ptr(inst)); + + return inst->getResultId(); +} + +Id Builder::makeDebugValue(Id const debugLocalVariable, Id const value) +{ + Instruction* inst = new Instruction(getUniqueId(), makeVoidType(), OpExtInst); + inst->addIdOperand(nonSemanticShaderDebugInfo); + inst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugValue); + inst->addIdOperand(debugLocalVariable); // debug local variable id + inst->addIdOperand(value); // value of local variable id + inst->addIdOperand(makeDebugExpression()); // expression id + buildPoint->addInstruction(std::unique_ptr(inst)); + + return inst->getResultId(); +} + Id Builder::makeAccelerationStructureType() { Instruction *type; @@ -663,7 +1271,21 @@ Id Builder::makeRayQueryType() return type->getResultId(); } -#endif + +Id Builder::makeHitObjectNVType() +{ + Instruction *type; + if (groupedTypes[OpTypeHitObjectNV].size() == 0) { + type = new Instruction(getUniqueId(), NoType, OpTypeHitObjectNV); + groupedTypes[OpTypeHitObjectNV].push_back(type); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + } else { + type = groupedTypes[OpTypeHitObjectNV].back(); + } + + return type->getResultId(); +} Id Builder::getDerefTypeId(Id resultId) const { @@ -713,6 +1335,7 @@ int Builder::getNumTypeConstituents(Id typeId) const } case OpTypeStruct: return instr->getNumOperands(); + case OpTypeCooperativeMatrixKHR: case OpTypeCooperativeMatrixNV: // has only one constituent when used with OpCompositeConstruct. return 1; @@ -762,6 +1385,7 @@ Id Builder::getContainedTypeId(Id typeId, int member) const case OpTypeMatrix: case OpTypeArray: case OpTypeRuntimeArray: + case OpTypeCooperativeMatrixKHR: case OpTypeCooperativeMatrixNV: return instr->getIdOperand(0); case OpTypePointer: @@ -832,7 +1456,7 @@ bool Builder::containsType(Id typeId, spv::Op typeOp, unsigned int width) const } // return true if the type is a pointer to PhysicalStorageBufferEXT or an -// array of such pointers. These require restrict/aliased decorations. +// contains such a pointer. These require restrict/aliased decorations. bool Builder::containsPhysicalStorageBufferOrArray(Id typeId) const { const Instruction& instr = *module.getInstruction(typeId); @@ -844,6 +1468,12 @@ bool Builder::containsPhysicalStorageBufferOrArray(Id typeId) const return getTypeStorageClass(typeId) == StorageClassPhysicalStorageBufferEXT; case OpTypeArray: return containsPhysicalStorageBufferOrArray(getContainedTypeId(typeId)); + case OpTypeStruct: + for (int m = 0; m < instr.getNumOperands(); ++m) { + if (containsPhysicalStorageBufferOrArray(instr.getIdOperand(m))) + return true; + } + return false; default: return false; } @@ -920,6 +1550,17 @@ bool Builder::isSpecConstantOpCode(Op opcode) const } } +bool Builder::isRayTracingOpCode(Op opcode) const +{ + switch (opcode) { + case OpTypeAccelerationStructureKHR: + case OpTypeRayQueryKHR: + return true; + default: + return false; + } +} + Id Builder::makeNullConstant(Id typeId) { Instruction* constant; @@ -1046,10 +1687,6 @@ Id Builder::makeFloatConstant(float f, bool specConstant) Id Builder::makeDoubleConstant(double d, bool specConstant) { -#ifdef GLSLANG_WEB - assert(0); - return NoResult; -#else Op opcode = specConstant ? OpSpecConstant : OpConstant; Id typeId = makeFloatType(64); union { double db; unsigned long long ull; } u; @@ -1074,15 +1711,10 @@ Id Builder::makeDoubleConstant(double d, bool specConstant) module.mapInstruction(c); return c->getResultId(); -#endif } Id Builder::makeFloat16Constant(float f16, bool specConstant) { -#ifdef GLSLANG_WEB - assert(0); - return NoResult; -#else Op opcode = specConstant ? OpSpecConstant : OpConstant; Id typeId = makeFloatType(16); @@ -1107,17 +1739,11 @@ Id Builder::makeFloat16Constant(float f16, bool specConstant) module.mapInstruction(c); return c->getResultId(); -#endif } Id Builder::makeFpConstant(Id type, double d, bool specConstant) { -#ifdef GLSLANG_WEB - const int width = 32; - assert(width == getScalarTypeWidth(type)); -#else const int width = getScalarTypeWidth(type); -#endif assert(isFloatType(type)); @@ -1136,9 +1762,22 @@ Id Builder::makeFpConstant(Id type, double d, bool specConstant) return NoResult; } +Id Builder::importNonSemanticShaderDebugInfoInstructions() +{ + assert(emitNonSemanticShaderDebugInfo == true); + + if(nonSemanticShaderDebugInfo == 0) + { + this->addExtension(spv::E_SPV_KHR_non_semantic_info); + nonSemanticShaderDebugInfo = this->import("NonSemantic.Shader.DebugInfo.100"); + } + + return nonSemanticShaderDebugInfo; +} + Id Builder::findCompositeConstant(Op typeClass, Id typeId, const std::vector& comps) { - Instruction* constant = 0; + Instruction* constant = nullptr; bool found = false; for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) { constant = groupedConstants[typeClass][i]; @@ -1165,7 +1804,7 @@ Id Builder::findCompositeConstant(Op typeClass, Id typeId, const std::vector Id Builder::findStructConstant(Id typeId, const std::vector& comps) { - Instruction* constant = 0; + Instruction* constant = nullptr; bool found = false; for (int i = 0; i < (int)groupedStructConstants[typeId].size(); ++i) { constant = groupedStructConstants[typeId][i]; @@ -1198,6 +1837,7 @@ Id Builder::makeCompositeConstant(Id typeId, const std::vector& members, boo case OpTypeVector: case OpTypeArray: case OpTypeMatrix: + case OpTypeCooperativeMatrixKHR: case OpTypeCooperativeMatrixNV: if (! specConstant) { Id existing = findCompositeConstant(typeClass, typeId, members); @@ -1245,6 +1885,10 @@ Instruction* Builder::addEntryPoint(ExecutionModel model, Function* function, co // Currently relying on the fact that all 'value' of interest are small non-negative values. void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int value1, int value2, int value3) { + // entryPoint can be null if we are in compile-only mode + if (!entryPoint) + return; + Instruction* instr = new Instruction(OpExecutionMode); instr->addIdOperand(entryPoint->getId()); instr->addImmediateOperand(mode); @@ -1260,6 +1904,10 @@ void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, int val void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, const std::vector& literals) { + // entryPoint can be null if we are in compile-only mode + if (!entryPoint) + return; + Instruction* instr = new Instruction(OpExecutionMode); instr->addIdOperand(entryPoint->getId()); instr->addImmediateOperand(mode); @@ -1271,6 +1919,10 @@ void Builder::addExecutionMode(Function* entryPoint, ExecutionMode mode, const s void Builder::addExecutionModeId(Function* entryPoint, ExecutionMode mode, const std::vector& operandIds) { + // entryPoint can be null if we are in compile-only mode + if (!entryPoint) + return; + Instruction* instr = new Instruction(OpExecutionModeId); instr->addIdOperand(entryPoint->getId()); instr->addImmediateOperand(mode); @@ -1354,6 +2006,16 @@ void Builder::addDecoration(Id id, Decoration decoration, const std::vector(dec)); } +void Builder::addLinkageDecoration(Id id, const char* name, spv::LinkageType linkType) { + Instruction* dec = new Instruction(OpDecorate); + dec->addIdOperand(id); + dec->addImmediateOperand(spv::DecorationLinkageAttributes); + dec->addStringOperand(name); + dec->addImmediateOperand(linkType); + + decorations.push_back(std::unique_ptr(dec)); +} + void Builder::addDecorationId(Id id, Decoration decoration, Id idDecoration) { if (decoration == spv::DecorationMax) @@ -1446,24 +2108,31 @@ Function* Builder::makeEntryPoint(const char* entryPoint) { assert(! entryPointFunction); - Block* entry; - std::vector params; - std::vector> decorations; + auto const returnType = makeVoidType(); - entryPointFunction = makeFunctionEntry(NoPrecision, makeVoidType(), entryPoint, params, decorations, &entry); + restoreNonSemanticShaderDebugInfo = emitNonSemanticShaderDebugInfo; + if(sourceLang == spv::SourceLanguageHLSL) { + emitNonSemanticShaderDebugInfo = false; + } + + Block* entry = nullptr; + entryPointFunction = makeFunctionEntry(NoPrecision, returnType, entryPoint, LinkageTypeMax, {}, {}, &entry); + + emitNonSemanticShaderDebugInfo = restoreNonSemanticShaderDebugInfo; return entryPointFunction; } // Comments in header -Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name, +Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const char* name, LinkageType linkType, const std::vector& paramTypes, - const std::vector>& decorations, Block **entry) + const std::vector>& decorations, Block** entry) { // Make the function and initial instructions in it Id typeId = makeFunctionType(returnType, paramTypes); Id firstParamId = paramTypes.size() == 0 ? 0 : getUniqueIds((int)paramTypes.size()); - Function* function = new Function(getUniqueId(), returnType, typeId, firstParamId, module); + Id funcId = getUniqueId(); + Function* function = new Function(funcId, returnType, typeId, firstParamId, linkType, name, module); // Set up the precisions setPrecision(function->getId(), precision); @@ -1475,13 +2144,17 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const } } - // CFG - if (entry) { - *entry = new Block(getUniqueId(), *function); - function->addBlock(*entry); - setBuildPoint(*entry); + // reset last debug scope + if (emitNonSemanticShaderDebugInfo) { + lastDebugScopeId = NoResult; } + // CFG + assert(entry != nullptr); + *entry = new Block(getUniqueId(), *function); + function->addBlock(*entry); + setBuildPoint(*entry); + if (name) addName(function->getId(), name); @@ -1490,6 +2163,113 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const return function; } +void Builder::setupDebugFunctionEntry(Function* function, const char* name, int line, const std::vector& paramTypes, + const std::vector& paramNames) +{ + + if (!emitNonSemanticShaderDebugInfo) + return; + + currentLine = line; + Id nameId = getStringId(unmangleFunctionName(name)); + Id funcTypeId = function->getFuncTypeId(); + assert(debugId[funcTypeId] != 0); + Id funcId = function->getId(); + + assert(funcId != 0); + + // Make the debug function instruction + Id debugFuncId = makeDebugFunction(function, nameId, funcTypeId); + debugId[funcId] = debugFuncId; + currentDebugScopeId.push(debugFuncId); + + // DebugScope and DebugLine for parameter DebugDeclares + assert(paramTypes.size() == paramNames.size()); + if ((int)paramTypes.size() > 0) { + addDebugScopeAndLine(currentFileId, currentLine, 0); + + Id firstParamId = function->getParamId(0); + + for (size_t p = 0; p < paramTypes.size(); ++p) { + bool passByRef = false; + Id paramTypeId = paramTypes[p]; + + // For pointer-typed parameters, they are actually passed by reference and we need unwrap the pointer to get the actual parameter type. + if (isPointerType(paramTypeId) || isArrayType(paramTypeId)) { + passByRef = true; + paramTypeId = getContainedTypeId(paramTypeId); + } + + auto const& paramName = paramNames[p]; + auto const debugLocalVariableId = createDebugLocalVariable(debugId[paramTypeId], paramName, p + 1); + auto const paramId = static_cast(firstParamId + p); + debugId[paramId] = debugLocalVariableId; + + if (passByRef) { + makeDebugDeclare(debugLocalVariableId, paramId); + } else { + makeDebugValue(debugLocalVariableId, paramId); + } + } + } + + // Clear debug scope stack + if (emitNonSemanticShaderDebugInfo) + currentDebugScopeId.pop(); +} + +Id Builder::makeDebugFunction([[maybe_unused]] Function* function, Id nameId, Id funcTypeId) +{ + assert(function != nullptr); + assert(nameId != 0); + assert(funcTypeId != 0); + assert(debugId[funcTypeId] != 0); + + Id funcId = getUniqueId(); + auto type = new Instruction(funcId, makeVoidType(), OpExtInst); + type->addIdOperand(nonSemanticShaderDebugInfo); + type->addImmediateOperand(NonSemanticShaderDebugInfo100DebugFunction); + type->addIdOperand(nameId); + type->addIdOperand(debugId[funcTypeId]); + type->addIdOperand(makeDebugSource(currentFileId)); // TODO: This points to file of definition instead of declaration + type->addIdOperand(makeUintConstant(currentLine)); // TODO: This points to line of definition instead of declaration + type->addIdOperand(makeUintConstant(0)); // column + type->addIdOperand(makeDebugCompilationUnit()); // scope + type->addIdOperand(nameId); // linkage name + type->addIdOperand(makeUintConstant(NonSemanticShaderDebugInfo100FlagIsPublic)); + type->addIdOperand(makeUintConstant(currentLine)); + constantsTypesGlobals.push_back(std::unique_ptr(type)); + module.mapInstruction(type); + return funcId; +} + +Id Builder::makeDebugLexicalBlock(uint32_t line) { + assert(!currentDebugScopeId.empty()); + + Id lexId = getUniqueId(); + auto lex = new Instruction(lexId, makeVoidType(), OpExtInst); + lex->addIdOperand(nonSemanticShaderDebugInfo); + lex->addImmediateOperand(NonSemanticShaderDebugInfo100DebugLexicalBlock); + lex->addIdOperand(makeDebugSource(currentFileId)); + lex->addIdOperand(makeUintConstant(line)); + lex->addIdOperand(makeUintConstant(0)); // column + lex->addIdOperand(currentDebugScopeId.top()); // scope + constantsTypesGlobals.push_back(std::unique_ptr(lex)); + module.mapInstruction(lex); + return lexId; +} + +std::string Builder::unmangleFunctionName(std::string const& name) const +{ + assert(name.length() > 0); + + if(name.rfind('(') != std::string::npos) { + return name.substr(0, name.rfind('(')); + } else { + return name; + } +} + // Comments in header void Builder::makeReturn(bool implicit, Id retVal) { @@ -1504,6 +2284,54 @@ void Builder::makeReturn(bool implicit, Id retVal) createAndSetNoPredecessorBlock("post-return"); } +// Comments in header +void Builder::enterScope(uint32_t line) +{ + // Generate new lexical scope debug instruction + Id lexId = makeDebugLexicalBlock(line); + currentDebugScopeId.push(lexId); + lastDebugScopeId = NoResult; +} + +// Comments in header +void Builder::leaveScope() +{ + // Pop current scope from stack and clear current scope + currentDebugScopeId.pop(); + lastDebugScopeId = NoResult; +} + +// Comments in header +void Builder::enterFunction(Function const* function) +{ + // Save and disable debugInfo for HLSL entry point function. It is a wrapper + // function with no user code in it. + restoreNonSemanticShaderDebugInfo = emitNonSemanticShaderDebugInfo; + if (sourceLang == spv::SourceLanguageHLSL && function == entryPointFunction) { + emitNonSemanticShaderDebugInfo = false; + } + + if (emitNonSemanticShaderDebugInfo) { + // Initialize scope state + Id funcId = function->getFuncId(); + currentDebugScopeId.push(debugId[funcId]); + // Create DebugFunctionDefinition + spv::Id resultId = getUniqueId(); + Instruction* defInst = new Instruction(resultId, makeVoidType(), OpExtInst); + defInst->addIdOperand(nonSemanticShaderDebugInfo); + defInst->addImmediateOperand(NonSemanticShaderDebugInfo100DebugFunctionDefinition); + defInst->addIdOperand(debugId[funcId]); + defInst->addIdOperand(funcId); + buildPoint->addInstruction(std::unique_ptr(defInst)); + } + + if (auto linkType = function->getLinkType(); linkType != LinkageTypeMax) { + Id funcId = function->getFuncId(); + addCapability(CapabilityLinkage); + addLinkageDecoration(funcId, function->getExportName(), linkType); + } +} + // Comments in header void Builder::leaveFunction() { @@ -1519,6 +2347,12 @@ void Builder::leaveFunction() makeReturn(true, createUndefined(function.getReturnType())); } } + + // Clear function scope from debug scope stack + if (emitNonSemanticShaderDebugInfo) + currentDebugScopeId.pop(); + + emitNonSemanticShaderDebugInfo = restoreNonSemanticShaderDebugInfo; } // Comments in header @@ -1529,7 +2363,18 @@ void Builder::makeStatementTerminator(spv::Op opcode, const char *name) } // Comments in header -Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name, Id initializer) +void Builder::makeStatementTerminator(spv::Op opcode, const std::vector& operands, const char* name) +{ + // It's assumed that the terminator instruction is always of void return type + // However in future if there is a need for non void return type, new helper + // methods can be created. + createNoResultOp(opcode, operands); + createAndSetNoPredecessorBlock(name); +} + +// Comments in header +Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name, Id initializer, + bool const compilerGenerated) { Id pointerType = makePointer(storageClass, type); Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable); @@ -1541,11 +2386,26 @@ Id Builder::createVariable(Decoration precision, StorageClass storageClass, Id t case StorageClassFunction: // Validation rules require the declaration in the entry block buildPoint->getParent().addLocalVariable(std::unique_ptr(inst)); + + if (emitNonSemanticShaderDebugInfo && !compilerGenerated) + { + auto const debugLocalVariableId = createDebugLocalVariable(debugId[type], name); + debugId[inst->getResultId()] = debugLocalVariableId; + + makeDebugDeclare(debugLocalVariableId, inst->getResultId()); + } + break; default: constantsTypesGlobals.push_back(std::unique_ptr(inst)); module.mapInstruction(inst); + + if (emitNonSemanticShaderDebugInfo && !isRayTracingOpCode(getOpCode(type))) + { + auto const debugResultId = createDebugGlobalVariable(debugId[type], name, inst->getResultId()); + debugId[inst->getResultId()] = debugResultId; + } break; } @@ -1575,7 +2435,7 @@ spv::MemoryAccessMask Builder::sanitizeMemoryAccessForStorageClass(spv::MemoryAc case spv::StorageClassPhysicalStorageBufferEXT: break; default: - memoryAccess = spv::MemoryAccessMask(memoryAccess & + memoryAccess = spv::MemoryAccessMask(memoryAccess & ~(spv::MemoryAccessMakePointerAvailableKHRMask | spv::MemoryAccessMakePointerVisibleKHRMask | spv::MemoryAccessNonPrivatePointerKHRMask)); @@ -1660,7 +2520,24 @@ Id Builder::createArrayLength(Id base, unsigned int member) return length->getResultId(); } -Id Builder::createCooperativeMatrixLength(Id type) +Id Builder::createCooperativeMatrixLengthKHR(Id type) +{ + spv::Id intType = makeUintType(32); + + // Generate code for spec constants if in spec constant operation + // generation mode. + if (generatingOpCodeForSpecConst) { + return createSpecConstantOp(OpCooperativeMatrixLengthKHR, intType, std::vector(1, type), std::vector()); + } + + Instruction* length = new Instruction(getUniqueId(), intType, OpCooperativeMatrixLengthKHR); + length->addIdOperand(type); + buildPoint->addInstruction(std::unique_ptr(length)); + + return length->getResultId(); +} + +Id Builder::createCooperativeMatrixLengthNV(Id type) { spv::Id intType = makeUintType(32); @@ -1897,6 +2774,14 @@ Id Builder::createSpecConstantOp(Op opCode, Id typeId, const std::vector& op module.mapInstruction(op); constantsTypesGlobals.push_back(std::unique_ptr(op)); + // OpSpecConstantOp's using 8 or 16 bit types require the associated capability + if (containsType(typeId, OpTypeInt, 8)) + addCapability(CapabilityInt8); + if (containsType(typeId, OpTypeInt, 16)) + addCapability(CapabilityInt16); + if (containsType(typeId, OpTypeFloat, 16)) + addCapability(CapabilityFloat16); + return op->getResultId(); } @@ -2031,52 +2916,47 @@ Id Builder::createBuiltinCall(Id resultType, Id builtins, int entryPoint, const Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, bool fetch, bool proj, bool gather, bool noImplicitLod, const TextureParameters& parameters, ImageOperandsMask signExtensionMask) { - static const int maxTextureArgs = 10; - Id texArgs[maxTextureArgs] = {}; + std::vector texArgs; // // Set up the fixed arguments // - int numArgs = 0; bool explicitLod = false; - texArgs[numArgs++] = parameters.sampler; - texArgs[numArgs++] = parameters.coords; + texArgs.push_back(parameters.sampler); + texArgs.push_back(parameters.coords); if (parameters.Dref != NoResult) - texArgs[numArgs++] = parameters.Dref; + texArgs.push_back(parameters.Dref); if (parameters.component != NoResult) - texArgs[numArgs++] = parameters.component; + texArgs.push_back(parameters.component); -#ifndef GLSLANG_WEB if (parameters.granularity != NoResult) - texArgs[numArgs++] = parameters.granularity; + texArgs.push_back(parameters.granularity); if (parameters.coarse != NoResult) - texArgs[numArgs++] = parameters.coarse; -#endif + texArgs.push_back(parameters.coarse); // // Set up the optional arguments // - int optArgNum = numArgs; // track which operand, if it exists, is the mask of optional arguments - ++numArgs; // speculatively make room for the mask operand + size_t optArgNum = texArgs.size(); // the position of the mask for the optional arguments, if any. ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand if (parameters.bias) { mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask); - texArgs[numArgs++] = parameters.bias; + texArgs.push_back(parameters.bias); } if (parameters.lod) { mask = (ImageOperandsMask)(mask | ImageOperandsLodMask); - texArgs[numArgs++] = parameters.lod; + texArgs.push_back(parameters.lod); explicitLod = true; } else if (parameters.gradX) { mask = (ImageOperandsMask)(mask | ImageOperandsGradMask); - texArgs[numArgs++] = parameters.gradX; - texArgs[numArgs++] = parameters.gradY; + texArgs.push_back(parameters.gradX); + texArgs.push_back(parameters.gradY); explicitLod = true; } else if (noImplicitLod && ! fetch && ! gather) { // have to explicitly use lod of 0 if not allowed to have them be implicit, and // we would otherwise be about to issue an implicit instruction mask = (ImageOperandsMask)(mask | ImageOperandsLodMask); - texArgs[numArgs++] = makeFloatConstant(0.0); + texArgs.push_back(makeFloatConstant(0.0)); explicitLod = true; } if (parameters.offset) { @@ -2086,24 +2966,23 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, addCapability(CapabilityImageGatherExtended); mask = (ImageOperandsMask)(mask | ImageOperandsOffsetMask); } - texArgs[numArgs++] = parameters.offset; + texArgs.push_back(parameters.offset); } if (parameters.offsets) { addCapability(CapabilityImageGatherExtended); mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask); - texArgs[numArgs++] = parameters.offsets; + texArgs.push_back(parameters.offsets); } -#ifndef GLSLANG_WEB if (parameters.sample) { mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask); - texArgs[numArgs++] = parameters.sample; + texArgs.push_back(parameters.sample); } if (parameters.lodClamp) { // capability if this bit is used addCapability(CapabilityMinLod); mask = (ImageOperandsMask)(mask | ImageOperandsMinLodMask); - texArgs[numArgs++] = parameters.lodClamp; + texArgs.push_back(parameters.lodClamp); } if (parameters.nonprivate) { mask = mask | ImageOperandsNonPrivateTexelKHRMask; @@ -2111,12 +2990,10 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, if (parameters.volatil) { mask = mask | ImageOperandsVolatileTexelKHRMask; } -#endif mask = mask | signExtensionMask; - if (mask == ImageOperandsMaskNone) - --numArgs; // undo speculative reservation for the mask argument - else - texArgs[optArgNum] = mask; + // insert the operand for the mask, if any bits were set. + if (mask != ImageOperandsMaskNone) + texArgs.insert(texArgs.begin() + optArgNum, mask); // // Set up the instruction @@ -2127,7 +3004,6 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, opCode = OpImageSparseFetch; else opCode = OpImageFetch; -#ifndef GLSLANG_WEB } else if (parameters.granularity && parameters.coarse) { opCode = OpImageSampleFootprintNV; } else if (gather) { @@ -2141,7 +3017,6 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, opCode = OpImageSparseGather; else opCode = OpImageGather; -#endif } else if (explicitLod) { if (parameters.Dref) { if (proj) @@ -2220,11 +3095,11 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse, // Build the SPIR-V instruction Instruction* textureInst = new Instruction(getUniqueId(), resultType, opCode); - for (int op = 0; op < optArgNum; ++op) + for (size_t op = 0; op < optArgNum; ++op) textureInst->addIdOperand(texArgs[op]); - if (optArgNum < numArgs) + if (optArgNum < texArgs.size()) textureInst->addImmediateOperand(texArgs[optArgNum]); - for (int op = optArgNum + 1; op < numArgs; ++op) + for (size_t op = optArgNum + 1; op < texArgs.size(); ++op) textureInst->addIdOperand(texArgs[op]); setPrecision(textureInst->getResultId(), precision); buildPoint->addInstruction(std::unique_ptr(textureInst)); @@ -2504,12 +3379,7 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector& int numRows = getTypeNumRows(resultTypeId); Instruction* instr = module.getInstruction(componentTypeId); -#ifdef GLSLANG_WEB - const unsigned bitCount = 32; - assert(bitCount == instr->getImmediateOperand(0)); -#else const unsigned bitCount = instr->getImmediateOperand(0); -#endif // Optimize matrix constructed from a bigger matrix if (isMatrix(sources[0]) && getNumColumns(sources[0]) >= numCols && getNumRows(sources[0]) >= numRows) { @@ -2629,7 +3499,7 @@ Builder::If::If(Id cond, unsigned int ctrl, Builder& gb) : builder(gb), condition(cond), control(ctrl), - elseBlock(0) + elseBlock(nullptr) { function = &builder.getBuildPoint()->getParent(); @@ -3271,10 +4141,10 @@ void Builder::dumpSourceInstructions(const spv::Id fileId, const std::string& te const int opSourceWordCount = 4; const int nonNullBytesPerInstruction = 4 * (maxWordCount - opSourceWordCount) - 1; - if (source != SourceLanguageUnknown) { + if (sourceLang != SourceLanguageUnknown) { // OpSource Language Version File Source Instruction sourceInst(NoResult, NoType, OpSource); - sourceInst.addImmediateOperand(source); + sourceInst.addImmediateOperand(sourceLang); sourceInst.addImmediateOperand(sourceVersion); // File operand if (fileId != NoResult) { @@ -3307,6 +4177,7 @@ void Builder::dumpSourceInstructions(const spv::Id fileId, const std::string& te // Dump an OpSource[Continued] sequence for the source and every include file void Builder::dumpSourceInstructions(std::vector& out) const { + if (emitNonSemanticShaderDebugInfo) return; dumpSourceInstructions(sourceFileStringId, sourceText, out); for (auto iItr = includeFiles.begin(); iItr != includeFiles.end(); ++iItr) dumpSourceInstructions(iItr->first, *iItr->second, out); @@ -3329,4 +4200,4 @@ void Builder::dumpModuleProcesses(std::vector& out) const } } -}; // end spv namespace +} // end spv namespace diff --git a/src/libraries/glslang/SPIRV/SpvBuilder.h b/src/libraries/glslang/SPIRV/SpvBuilder.h index c72d9b287..dac5881b5 100644 --- a/src/libraries/glslang/SPIRV/SpvBuilder.h +++ b/src/libraries/glslang/SPIRV/SpvBuilder.h @@ -50,6 +50,10 @@ #include "Logger.h" #include "spirv.hpp" #include "spvIR.h" +namespace spv { + #include "GLSL.ext.KHR.h" + #include "NonSemanticShaderDebugInfo100.h" +} #include #include @@ -82,7 +86,7 @@ class Builder { void setSource(spv::SourceLanguage lang, int version) { - source = lang; + sourceLang = lang; sourceVersion = version; } spv::Id getStringId(const std::string& str) @@ -99,14 +103,32 @@ class Builder { stringIds[file_c_str] = strId; return strId; } + spv::Id getSourceFile() const + { + return sourceFileStringId; + } void setSourceFile(const std::string& file) { sourceFileStringId = getStringId(file); + currentFileId = sourceFileStringId; } 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 setEmitNonSemanticShaderDebugInfo(bool const emit) + { + emitNonSemanticShaderDebugInfo = emit; + + if(emit) + { + importNonSemanticShaderDebugInfoInstructions(); + } + } + void setEmitNonSemanticShaderDebugSource(bool const src) + { + emitNonSemanticShaderDebugSource = src; + } void addExtension(const char* ext) { extensions.insert(ext); } void removeExtension(const char* ext) { @@ -159,6 +181,7 @@ class Builder { void setLine(int line, const char* filename); // Low-level OpLine. See setLine() for a layered helper. void addLine(Id fileName, int line, int column); + void addDebugScopeAndLine(Id fileName, int line, int column); // For creating new types (will return old type if the requested one was already made). Id makeVoidType(); @@ -170,7 +193,7 @@ class Builder { 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& members, const char*); + Id makeStructType(const std::vector& members, const char* name, bool const compilerGenerated = true); Id makeStructResultType(Id type0, Id type1); Id makeVectorType(Id component, int size); Id makeMatrixType(Id component, int cols, int rows); @@ -180,13 +203,51 @@ class Builder { 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); + Id makeCooperativeMatrixTypeKHR(Id component, Id scope, Id rows, Id cols, Id use); + Id makeCooperativeMatrixTypeNV(Id component, Id scope, Id rows, Id cols); + Id makeCooperativeMatrixTypeWithSameShape(Id component, Id otherType); Id makeGenericType(spv::Op opcode, std::vector& operands); + // SPIR-V NonSemantic Shader DebugInfo Instructions + struct DebugTypeLoc { + std::string name {}; + int line {0}; + int column {0}; + }; + std::unordered_map debugTypeLocs; + Id makeDebugInfoNone(); + Id makeBoolDebugType(int const size); + Id makeIntegerDebugType(int const width, bool const hasSign); + Id makeFloatDebugType(int const width); + Id makeSequentialDebugType(Id const baseType, Id const componentCount, NonSemanticShaderDebugInfo100Instructions const sequenceType); + Id makeArrayDebugType(Id const baseType, Id const componentCount); + Id makeVectorDebugType(Id const baseType, int const componentCount); + Id makeMatrixDebugType(Id const vectorType, int const vectorCount, bool columnMajor = true); + Id makeMemberDebugType(Id const memberType, DebugTypeLoc const& debugTypeLoc); + Id makeCompositeDebugType(std::vector const& memberTypes, char const*const name, + NonSemanticShaderDebugInfo100DebugCompositeType const tag, bool const isOpaqueType = false); + Id makePointerDebugType(StorageClass storageClass, Id const baseType); + Id makeDebugSource(const Id fileName); + Id makeDebugCompilationUnit(); + Id createDebugGlobalVariable(Id const type, char const*const name, Id const variable); + Id createDebugLocalVariable(Id type, char const*const name, size_t const argNumber = 0); + Id makeDebugExpression(); + Id makeDebugDeclare(Id const debugLocalVariable, Id const pointer); + Id makeDebugValue(Id const debugLocalVariable, Id const value); + Id makeDebugFunctionType(Id returnType, const std::vector& paramTypes); + Id makeDebugFunction(Function* function, Id nameId, Id funcTypeId); + Id makeDebugLexicalBlock(uint32_t line); + std::string unmangleFunctionName(std::string const& name) const; + void setupDebugFunctionEntry(Function* function, const char* name, int line, + const std::vector& paramTypes, + const std::vector& paramNames); + // accelerationStructureNV type Id makeAccelerationStructureType(); // rayQueryEXT type Id makeRayQueryType(); + // hitObjectNV type + Id makeHitObjectNVType(); // For querying about types. Id getTypeId(Id resultId) const { return module.getTypeId(resultId); } @@ -204,6 +265,7 @@ class Builder { ImageFormat getImageTypeFormat(Id typeId) const { return (ImageFormat)module.getInstruction(typeId)->getImmediateOperand(6); } Id getResultingAccessChainType() const; + Id getIdOperand(Id resultId, int idx) { return module.getInstruction(resultId)->getIdOperand(idx); } bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); } bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); } @@ -228,11 +290,10 @@ class Builder { 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 isCooperativeMatrixType(Id typeId)const + { + return getTypeClass(typeId) == OpTypeCooperativeMatrixKHR || getTypeClass(typeId) == OpTypeCooperativeMatrixNV; + } bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId) || isCooperativeMatrixType(typeId); } bool isImageType(Id typeId) const { return getTypeClass(typeId) == OpTypeImage; } @@ -257,6 +318,8 @@ class Builder { // See if a resultId is valid for use as an initializer. bool isValidInitializer(Id resultId) const { return isConstant(resultId) || isGlobalVariable(resultId); } + bool isRayTracingOpCode(Op opcode) const; + int getScalarTypeWidth(Id typeId) const { Id scalarTypeId = getScalarTypeId(typeId); @@ -318,6 +381,8 @@ class Builder { Id makeFloat16Constant(float f16, bool specConstant = false); Id makeFpConstant(Id type, double d, bool specConstant = false); + Id importNonSemanticShaderDebugInfoInstructions(); + // Turn the array of constants into a proper spv constant of the requested type. Id makeCompositeConstant(Id type, const std::vector& comps, bool specConst = false); @@ -332,6 +397,7 @@ class Builder { void addDecoration(Id, Decoration, const char*); void addDecoration(Id, Decoration, const std::vector& literals); void addDecoration(Id, Decoration, const std::vector& strings); + void addLinkageDecoration(Id id, const char* name, spv::LinkageType linkType); void addDecorationId(Id id, Decoration, Id idDecoration); void addDecorationId(Id id, Decoration, const std::vector& operandIds); void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1); @@ -340,7 +406,12 @@ class Builder { void addMemberDecoration(Id, unsigned int member, Decoration, const std::vector& strings); // At the end of what block do the next create*() instructions go? - void setBuildPoint(Block* bp) { buildPoint = bp; } + // Also reset current last DebugScope and current source line to unknown + void setBuildPoint(Block* bp) { + buildPoint = bp; + lastDebugScopeId = NoResult; + currentLine = 0; + } Block* getBuildPoint() const { return buildPoint; } // Make the entry-point function. The returned pointer is only valid @@ -350,13 +421,23 @@ class Builder { // 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& paramTypes, const std::vector>& precisions, Block **entry = 0); + Function* makeFunctionEntry(Decoration precision, Id returnType, const char* name, LinkageType linkType, + const std::vector& paramTypes, + const std::vector>& precisions, Block** entry = nullptr); // 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); + // Initialize state and generate instructions for new lexical scope + void enterScope(uint32_t line); + + // Set state and generate instructions to exit current lexical scope + void leaveScope(); + + // Prepare builder for generation of instructions for a function. + void enterFunction(Function const* function); + // Generate all the code needed to finish up a function. void leaveFunction(); @@ -364,9 +445,13 @@ class Builder { // discard, terminate-invocation, terminateRayEXT, or ignoreIntersectionEXT void makeStatementTerminator(spv::Op opcode, const char *name); + // Create block terminator instruction for statements that have input operands + // such as OpEmitMeshTasksEXT + void makeStatementTerminator(spv::Op opcode, const std::vector& operands, const char* name); + // Create a global or function local or IO variable. - Id createVariable(Decoration precision, StorageClass, Id type, const char* name = nullptr, - Id initializer = NoResult); + Id createVariable(Decoration precision, StorageClass storageClass, Id type, const char* name = nullptr, + Id initializer = NoResult, bool const compilerGenerated = true); // Create an intermediate with an undefined value. Id createUndefined(Id type); @@ -386,8 +471,10 @@ class Builder { // Create an OpArrayLength instruction Id createArrayLength(Id base, unsigned int member); + // Create an OpCooperativeMatrixLengthKHR instruction + Id createCooperativeMatrixLengthKHR(Id type); // Create an OpCooperativeMatrixLengthNV instruction - Id createCooperativeMatrixLength(Id type); + Id createCooperativeMatrixLengthNV(Id type); // Create an OpCompositeExtract instruction Id createCompositeExtract(Id composite, Id typeId, unsigned index); @@ -622,11 +709,6 @@ class Builder { // 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; } bool isNonUniform() const { return nonUniform; } bool anyCoherent() const { @@ -671,7 +753,6 @@ class Builder { nonUniform |= other.nonUniform; return *this; } -#endif }; CoherentFlags coherentFlags; }; @@ -752,19 +833,17 @@ class Builder { // Add capabilities, extensions, remove unneeded decorations, etc., // based on the resulting SPIR-V. - void postProcess(); + void postProcess(bool compileOnly); // 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&) const; @@ -801,13 +880,23 @@ class Builder { const; unsigned int spvVersion; // the version of SPIR-V to emit in the header - SourceLanguage source; + SourceLanguage sourceLang; int sourceVersion; spv::Id sourceFileStringId; + spv::Id nonSemanticShaderCompilationUnitId {0}; + spv::Id nonSemanticShaderDebugInfo {0}; + spv::Id debugInfoNone {0}; + spv::Id debugExpression {0}; // Debug expression with zero operations. std::string sourceText; int currentLine; const char* currentFile; + spv::Id currentFileId; + std::stack currentDebugScopeId; + spv::Id lastDebugScopeId; bool emitOpLines; + bool emitNonSemanticShaderDebugInfo; + bool restoreNonSemanticShaderDebugInfo; + bool emitNonSemanticShaderDebugSource; std::set extensions; std::vector sourceExtensions; std::vector moduleProcesses; @@ -841,6 +930,8 @@ class Builder { std::unordered_map> groupedStructConstants; // map type opcodes to type instructions std::unordered_map> groupedTypes; + // map type opcodes to debug type instructions + std::unordered_map> groupedDebugTypes; // list of OpConstantNull instructions std::vector nullConstants; @@ -856,6 +947,12 @@ class Builder { // map from include file name ids to their contents std::map includeFiles; + // map from core id to debug id + std::map debugId; + + // map from file name string id to DebugSource id + std::unordered_map debugSourceId; + // The stream for outputting warnings and errors. SpvBuildLogger* logger; }; // end Builder class diff --git a/src/libraries/glslang/SPIRV/SpvPostProcess.cpp b/src/libraries/glslang/SPIRV/SpvPostProcess.cpp index dd6dabce0..13001a67a 100644 --- a/src/libraries/glslang/SPIRV/SpvPostProcess.cpp +++ b/src/libraries/glslang/SPIRV/SpvPostProcess.cpp @@ -52,11 +52,12 @@ namespace spv { #include "GLSL.ext.EXT.h" #include "GLSL.ext.AMD.h" #include "GLSL.ext.NV.h" + #include "GLSL.ext.ARM.h" + #include "GLSL.ext.QCOM.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. @@ -333,7 +334,6 @@ void Builder::postProcess(Instruction& inst) } } } -#endif // comment in header void Builder::postProcessCFG() @@ -394,7 +394,6 @@ void Builder::postProcessCFG() decorations.end()); } -#ifndef GLSLANG_WEB // comment in header void Builder::postProcessFeatures() { // Add per-instruction capabilities, extensions, etc., @@ -482,14 +481,15 @@ void Builder::postProcessFeatures() { } } } -#endif // comment in header -void Builder::postProcess() { - postProcessCFG(); -#ifndef GLSLANG_WEB - postProcessFeatures(); -#endif +void Builder::postProcess(bool compileOnly) +{ + // postProcessCFG needs an entrypoint to determine what is reachable, but if we are not creating an "executable" shader, we don't have an entrypoint + if (!compileOnly) + postProcessCFG(); + + postProcessFeatures(); } }; // end spv namespace diff --git a/src/libraries/glslang/SPIRV/SpvTools.cpp b/src/libraries/glslang/SPIRV/SpvTools.cpp index f78a79177..ff04f4f96 100644 --- a/src/libraries/glslang/SPIRV/SpvTools.cpp +++ b/src/libraries/glslang/SPIRV/SpvTools.cpp @@ -68,26 +68,8 @@ spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLog } case glslang::EShTargetVulkan_1_2: return spv_target_env::SPV_ENV_VULKAN_1_2; - case glslang::EShTargetUniversal: - switch (spvVersion.spv) { - case EShTargetSpv_1_0: - return spv_target_env::SPV_ENV_UNIVERSAL_1_0; - case EShTargetSpv_1_1: - return spv_target_env::SPV_ENV_UNIVERSAL_1_1; - case EShTargetSpv_1_2: - return spv_target_env::SPV_ENV_UNIVERSAL_1_2; - case EShTargetSpv_1_3: - return spv_target_env::SPV_ENV_UNIVERSAL_1_3; - case EShTargetSpv_1_4: - return spv_target_env::SPV_ENV_UNIVERSAL_1_4; - case EShTargetSpv_1_5: - return spv_target_env::SPV_ENV_UNIVERSAL_1_5; - case EShTargetSpv_1_6: - return spv_target_env::SPV_ENV_UNIVERSAL_1_6; - default: - logger->missingFunctionality("Target version for SPIRV-Tools validator"); - return spv_target_env::SPV_ENV_UNIVERSAL_1_6; - } + case glslang::EShTargetVulkan_1_3: + return spv_target_env::SPV_ENV_VULKAN_1_3; default: break; } @@ -230,6 +212,7 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector optimizer.RegisterPass(spvtools::CreateInterpolateFixupPass()); if (options->optimizeSize) { optimizer.RegisterPass(spvtools::CreateRedundancyEliminationPass()); + optimizer.RegisterPass(spvtools::CreateEliminateDeadInputComponentsSafePass()); } optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); optimizer.RegisterPass(spvtools::CreateCFGCleanupPass()); @@ -240,6 +223,56 @@ void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); } +bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector& spirv, + std::unordered_set* live_locs, + std::unordered_set* live_builtins, + spv::SpvBuildLogger*) +{ + spvtools::Optimizer optimizer(target_env); + optimizer.SetMessageConsumer(OptimizerMesssageConsumer); + + optimizer.RegisterPass(spvtools::CreateAnalyzeLiveInputPass(live_locs, live_builtins)); + + spvtools::OptimizerOptions spvOptOptions; + optimizer.SetTargetEnv(target_env); + spvOptOptions.set_run_validator(false); + return optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); +} + +void SpirvToolsEliminateDeadOutputStores(spv_target_env target_env, std::vector& spirv, + std::unordered_set* live_locs, + std::unordered_set* live_builtins, + spv::SpvBuildLogger*) +{ + spvtools::Optimizer optimizer(target_env); + optimizer.SetMessageConsumer(OptimizerMesssageConsumer); + + optimizer.RegisterPass(spvtools::CreateEliminateDeadOutputStoresPass(live_locs, live_builtins)); + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass(false, true)); + optimizer.RegisterPass(spvtools::CreateEliminateDeadOutputComponentsPass()); + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass(false, true)); + + spvtools::OptimizerOptions spvOptOptions; + optimizer.SetTargetEnv(target_env); + spvOptOptions.set_run_validator(false); + optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); +} + +void SpirvToolsEliminateDeadInputComponents(spv_target_env target_env, std::vector& spirv, + spv::SpvBuildLogger*) +{ + spvtools::Optimizer optimizer(target_env); + optimizer.SetMessageConsumer(OptimizerMesssageConsumer); + + optimizer.RegisterPass(spvtools::CreateEliminateDeadInputComponentsPass()); + optimizer.RegisterPass(spvtools::CreateAggressiveDCEPass()); + + spvtools::OptimizerOptions spvOptOptions; + optimizer.SetTargetEnv(target_env); + spvOptOptions.set_run_validator(false); + optimizer.Run(spirv.data(), spirv.size(), &spirv, spvOptOptions); +} + // Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by // SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if // optimization is disabled. diff --git a/src/libraries/glslang/SPIRV/SpvTools.h b/src/libraries/glslang/SPIRV/SpvTools.h index d856c5236..3ef053d73 100644 --- a/src/libraries/glslang/SPIRV/SpvTools.h +++ b/src/libraries/glslang/SPIRV/SpvTools.h @@ -48,23 +48,16 @@ #endif #include "../glslang/MachineIndependent/localintermediate.h" +#include "GlslangToSpv.h" #include "Logger.h" namespace glslang { -struct SpvOptions { - SpvOptions() : generateDebugInfo(false), stripDebugInfo(false), disableOptimizer(true), - optimizeSize(false), disassemble(false), validate(false) { } - bool generateDebugInfo; - bool stripDebugInfo; - bool disableOptimizer; - bool optimizeSize; - bool disassemble; - bool validate; -}; - #if ENABLE_OPT +// Translate glslang's view of target versioning to what SPIRV-Tools uses. +spv_target_env MapToSpirvToolsEnv(const SpvVersion& spvVersion, spv::SpvBuildLogger* logger); + // Use the SPIRV-Tools disassembler to print SPIR-V using a SPV_ENV_UNIVERSAL_1_3 environment. void SpirvToolsDisassemble(std::ostream& out, const std::vector& spirv); @@ -80,6 +73,22 @@ void SpirvToolsValidate(const glslang::TIntermediate& intermediate, std::vector< void SpirvToolsTransform(const glslang::TIntermediate& intermediate, std::vector& spirv, spv::SpvBuildLogger*, const SpvOptions*); +// Apply the SPIRV-Tools EliminateDeadInputComponents pass to generated SPIR-V. Put result in |spirv|. +void SpirvToolsEliminateDeadInputComponents(spv_target_env target_env, std::vector& spirv, + spv::SpvBuildLogger*); + +// Apply the SPIRV-Tools AnalyzeDeadOutputStores pass to generated SPIR-V. Put result in |live_locs|. +// Return true if the result is valid. +bool SpirvToolsAnalyzeDeadOutputStores(spv_target_env target_env, std::vector& spirv, + std::unordered_set* live_locs, + std::unordered_set* live_builtins, spv::SpvBuildLogger*); + +// Apply the SPIRV-Tools EliminateDeadOutputStores and AggressiveDeadCodeElimination passes to generated SPIR-V using +// |live_locs|. Put result in |spirv|. +void SpirvToolsEliminateDeadOutputStores(spv_target_env target_env, std::vector& spirv, + std::unordered_set* live_locs, + std::unordered_set* live_builtins, spv::SpvBuildLogger*); + // Apply the SPIRV-Tools optimizer to strip debug info from SPIR-V. This is implicitly done by // SpirvToolsTransform if spvOptions->stripDebugInfo is set, but can be called separately if // optimization is disabled. diff --git a/src/libraries/glslang/SPIRV/disassemble.cpp b/src/libraries/glslang/SPIRV/disassemble.cpp index 73c988c5b..c5e961cf0 100644 --- a/src/libraries/glslang/SPIRV/disassemble.cpp +++ b/src/libraries/glslang/SPIRV/disassemble.cpp @@ -43,6 +43,7 @@ #include #include #include +#include #include "disassemble.h" #include "doc.h" @@ -53,6 +54,9 @@ namespace spv { #include "GLSL.std.450.h" #include "GLSL.ext.AMD.h" #include "GLSL.ext.NV.h" + #include "GLSL.ext.ARM.h" + #include "NonSemanticShaderDebugInfo100.h" + #include "GLSL.ext.QCOM.h" } } const char* GlslStd450DebugNames[spv::GLSLstd450Count]; @@ -61,6 +65,7 @@ namespace spv { static const char* GLSLextAMDGetDebugNames(const char*, unsigned); static const char* GLSLextNVGetDebugNames(const char*, unsigned); +static const char* NonSemanticShaderDebugInfo100GetDebugNames(unsigned); static void Kill(std::ostream& out, const char* message) { @@ -75,6 +80,7 @@ enum ExtInstSet { GLSLextNVInst, OpenCLExtInst, NonSemanticDebugPrintfExtInst, + NonSemanticShaderDebugInfo100 }; // Container class for a single instance of a SPIR-V stream, with methods for disassembly. @@ -100,6 +106,7 @@ class SpirvStream { void outputMask(OperandClass operandClass, unsigned mask); void disassembleImmediates(int numOperands); void disassembleIds(int numOperands); + std::pair decodeString(); int disassembleString(); void disassembleInstruction(Id resultId, Id typeId, Op opCode, int numOperands); @@ -290,31 +297,44 @@ void SpirvStream::disassembleIds(int numOperands) } } -// return the number of operands consumed by the string -int SpirvStream::disassembleString() +// decode string from words at current position (non-consuming) +std::pair SpirvStream::decodeString() { - int startWord = word; - - out << " \""; - - const char* wordString; + std::string res; + int wordPos = word; + char c; bool done = false; + do { - unsigned int content = stream[word]; - wordString = (const char*)&content; + unsigned int content = stream[wordPos]; for (int charCount = 0; charCount < 4; ++charCount) { - if (*wordString == 0) { + c = content & 0xff; + content >>= 8; + if (c == '\0') { done = true; break; } - out << *(wordString++); + res += c; } - ++word; - } while (! done); + ++wordPos; + } while(! done); + + return std::make_pair(wordPos - word, res); +} + +// return the number of operands consumed by the string +int SpirvStream::disassembleString() +{ + out << " \""; + std::pair decoderes = decodeString(); + + out << decoderes.second; out << "\""; - return word - startWord; + word += decoderes.first; + + return decoderes.first; } void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, int numOperands) @@ -331,7 +351,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, nextNestedControl = 0; } } else if (opCode == OpExtInstImport) { - idDescriptor[resultId] = (const char*)(&stream[word]); + idDescriptor[resultId] = decodeString().second; } else { if (resultId != 0 && idDescriptor[resultId].size() == 0) { @@ -428,7 +448,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, --numOperands; // Get names for printing "(XXX)" for readability, *after* this id if (opCode == OpName) - idDescriptor[stream[word - 1]] = (const char*)(&stream[word]); + idDescriptor[stream[word - 1]] = decodeString().second; break; case OperandVariableIds: disassembleIds(numOperands); @@ -486,6 +506,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, extInstSet = OpenCLExtInst; } else if (strcmp("NonSemantic.DebugPrintf", name) == 0) { extInstSet = NonSemanticDebugPrintfExtInst; + } else if (strcmp("NonSemantic.Shader.DebugInfo.100", name) == 0) { + extInstSet = NonSemanticShaderDebugInfo100; } 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 || @@ -494,7 +516,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, } 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_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; @@ -511,6 +533,8 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, out << "(" << GLSLextNVGetDebugNames(name, entrypoint) << ")"; } else if (extInstSet == NonSemanticDebugPrintfExtInst) { out << "(DebugPrintf)"; + } else if (extInstSet == NonSemanticShaderDebugInfo100) { + out << "(" << NonSemanticShaderDebugInfo100GetDebugNames(entrypoint) << ")"; } } break; @@ -734,6 +758,59 @@ static const char* GLSLextNVGetDebugNames(const char* name, unsigned entrypoint) return "Bad"; } +static const char* NonSemanticShaderDebugInfo100GetDebugNames(unsigned entrypoint) +{ + switch (entrypoint) { + case NonSemanticShaderDebugInfo100DebugInfoNone: return "DebugInfoNone"; + case NonSemanticShaderDebugInfo100DebugCompilationUnit: return "DebugCompilationUnit"; + case NonSemanticShaderDebugInfo100DebugTypeBasic: return "DebugTypeBasic"; + case NonSemanticShaderDebugInfo100DebugTypePointer: return "DebugTypePointer"; + case NonSemanticShaderDebugInfo100DebugTypeQualifier: return "DebugTypeQualifier"; + case NonSemanticShaderDebugInfo100DebugTypeArray: return "DebugTypeArray"; + case NonSemanticShaderDebugInfo100DebugTypeVector: return "DebugTypeVector"; + case NonSemanticShaderDebugInfo100DebugTypedef: return "DebugTypedef"; + case NonSemanticShaderDebugInfo100DebugTypeFunction: return "DebugTypeFunction"; + case NonSemanticShaderDebugInfo100DebugTypeEnum: return "DebugTypeEnum"; + case NonSemanticShaderDebugInfo100DebugTypeComposite: return "DebugTypeComposite"; + case NonSemanticShaderDebugInfo100DebugTypeMember: return "DebugTypeMember"; + case NonSemanticShaderDebugInfo100DebugTypeInheritance: return "DebugTypeInheritance"; + case NonSemanticShaderDebugInfo100DebugTypePtrToMember: return "DebugTypePtrToMember"; + case NonSemanticShaderDebugInfo100DebugTypeTemplate: return "DebugTypeTemplate"; + case NonSemanticShaderDebugInfo100DebugTypeTemplateParameter: return "DebugTypeTemplateParameter"; + case NonSemanticShaderDebugInfo100DebugTypeTemplateTemplateParameter: return "DebugTypeTemplateTemplateParameter"; + case NonSemanticShaderDebugInfo100DebugTypeTemplateParameterPack: return "DebugTypeTemplateParameterPack"; + case NonSemanticShaderDebugInfo100DebugGlobalVariable: return "DebugGlobalVariable"; + case NonSemanticShaderDebugInfo100DebugFunctionDeclaration: return "DebugFunctionDeclaration"; + case NonSemanticShaderDebugInfo100DebugFunction: return "DebugFunction"; + case NonSemanticShaderDebugInfo100DebugLexicalBlock: return "DebugLexicalBlock"; + case NonSemanticShaderDebugInfo100DebugLexicalBlockDiscriminator: return "DebugLexicalBlockDiscriminator"; + case NonSemanticShaderDebugInfo100DebugScope: return "DebugScope"; + case NonSemanticShaderDebugInfo100DebugNoScope: return "DebugNoScope"; + case NonSemanticShaderDebugInfo100DebugInlinedAt: return "DebugInlinedAt"; + case NonSemanticShaderDebugInfo100DebugLocalVariable: return "DebugLocalVariable"; + case NonSemanticShaderDebugInfo100DebugInlinedVariable: return "DebugInlinedVariable"; + case NonSemanticShaderDebugInfo100DebugDeclare: return "DebugDeclare"; + case NonSemanticShaderDebugInfo100DebugValue: return "DebugValue"; + case NonSemanticShaderDebugInfo100DebugOperation: return "DebugOperation"; + case NonSemanticShaderDebugInfo100DebugExpression: return "DebugExpression"; + case NonSemanticShaderDebugInfo100DebugMacroDef: return "DebugMacroDef"; + case NonSemanticShaderDebugInfo100DebugMacroUndef: return "DebugMacroUndef"; + case NonSemanticShaderDebugInfo100DebugImportedEntity: return "DebugImportedEntity"; + case NonSemanticShaderDebugInfo100DebugSource: return "DebugSource"; + case NonSemanticShaderDebugInfo100DebugFunctionDefinition: return "DebugFunctionDefinition"; + case NonSemanticShaderDebugInfo100DebugSourceContinued: return "DebugSourceContinued"; + case NonSemanticShaderDebugInfo100DebugLine: return "DebugLine"; + case NonSemanticShaderDebugInfo100DebugNoLine: return "DebugNoLine"; + case NonSemanticShaderDebugInfo100DebugBuildIdentifier: return "DebugBuildIdentifier"; + case NonSemanticShaderDebugInfo100DebugStoragePath: return "DebugStoragePath"; + case NonSemanticShaderDebugInfo100DebugEntryPoint: return "DebugEntryPoint"; + case NonSemanticShaderDebugInfo100DebugTypeMatrix: return "DebugTypeMatrix"; + default: return "Bad"; + } + + return "Bad"; +} + void Disassemble(std::ostream& out, const std::vector& stream) { SpirvStream SpirvStream(out, stream); diff --git a/src/libraries/glslang/SPIRV/doc.cpp b/src/libraries/glslang/SPIRV/doc.cpp old mode 100644 new mode 100755 index 9a569e0d7..1a05c6736 --- a/src/libraries/glslang/SPIRV/doc.cpp +++ b/src/libraries/glslang/SPIRV/doc.cpp @@ -45,6 +45,7 @@ #include #include #include +#include namespace spv { extern "C" { @@ -53,6 +54,8 @@ namespace spv { #include "GLSL.ext.EXT.h" #include "GLSL.ext.AMD.h" #include "GLSL.ext.NV.h" + #include "GLSL.ext.ARM.h" + #include "GLSL.ext.QCOM.h" } } @@ -97,6 +100,8 @@ const char* ExecutionModelString(int model) case 6: return "Kernel"; case ExecutionModelTaskNV: return "TaskNV"; case ExecutionModelMeshNV: return "MeshNV"; + case ExecutionModelTaskEXT: return "TaskEXT"; + case ExecutionModelMeshEXT: return "MeshEXT"; default: return "Bad"; @@ -173,28 +178,32 @@ const char* ExecutionModeString(int mode) case 31: return "ContractionOff"; case 32: return "Bad"; - case ExecutionModeInitializer: return "Initializer"; - case ExecutionModeFinalizer: return "Finalizer"; - case ExecutionModeSubgroupSize: return "SubgroupSize"; - case ExecutionModeSubgroupsPerWorkgroup: return "SubgroupsPerWorkgroup"; - case ExecutionModeSubgroupsPerWorkgroupId: return "SubgroupsPerWorkgroupId"; - case ExecutionModeLocalSizeId: return "LocalSizeId"; - case ExecutionModeLocalSizeHintId: return "LocalSizeHintId"; - - case ExecutionModePostDepthCoverage: return "PostDepthCoverage"; - case ExecutionModeDenormPreserve: return "DenormPreserve"; - case ExecutionModeDenormFlushToZero: return "DenormFlushToZero"; - case ExecutionModeSignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; - case ExecutionModeRoundingModeRTE: return "RoundingModeRTE"; - case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ"; - case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT"; + case ExecutionModeInitializer: return "Initializer"; + case ExecutionModeFinalizer: return "Finalizer"; + case ExecutionModeSubgroupSize: return "SubgroupSize"; + case ExecutionModeSubgroupsPerWorkgroup: return "SubgroupsPerWorkgroup"; + case ExecutionModeSubgroupsPerWorkgroupId: return "SubgroupsPerWorkgroupId"; + case ExecutionModeLocalSizeId: return "LocalSizeId"; + case ExecutionModeLocalSizeHintId: return "LocalSizeHintId"; + + case ExecutionModePostDepthCoverage: return "PostDepthCoverage"; + case ExecutionModeDenormPreserve: return "DenormPreserve"; + case ExecutionModeDenormFlushToZero: return "DenormFlushToZero"; + case ExecutionModeSignedZeroInfNanPreserve: return "SignedZeroInfNanPreserve"; + case ExecutionModeRoundingModeRTE: return "RoundingModeRTE"; + case ExecutionModeRoundingModeRTZ: return "RoundingModeRTZ"; + case ExecutionModeEarlyAndLateFragmentTestsAMD: return "EarlyAndLateFragmentTestsAMD"; + case ExecutionModeStencilRefUnchangedFrontAMD: return "StencilRefUnchangedFrontAMD"; + case ExecutionModeStencilRefLessFrontAMD: return "StencilRefLessFrontAMD"; + case ExecutionModeStencilRefGreaterBackAMD: return "StencilRefGreaterBackAMD"; + case ExecutionModeStencilRefReplacingEXT: return "StencilRefReplacingEXT"; case ExecutionModeSubgroupUniformControlFlowKHR: return "SubgroupUniformControlFlow"; - case ExecutionModeOutputLinesNV: return "OutputLinesNV"; - case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV"; - case ExecutionModeOutputTrianglesNV: return "OutputTrianglesNV"; - case ExecutionModeDerivativeGroupQuadsNV: return "DerivativeGroupQuadsNV"; - case ExecutionModeDerivativeGroupLinearNV: return "DerivativeGroupLinearNV"; + case ExecutionModeOutputLinesNV: return "OutputLinesNV"; + case ExecutionModeOutputPrimitivesNV: return "OutputPrimitivesNV"; + case ExecutionModeOutputTrianglesNV: return "OutputTrianglesNV"; + case ExecutionModeDerivativeGroupQuadsNV: return "DerivativeGroupQuadsNV"; + case ExecutionModeDerivativeGroupLinearNV: return "DerivativeGroupLinearNV"; case ExecutionModePixelInterlockOrderedEXT: return "PixelInterlockOrderedEXT"; case ExecutionModePixelInterlockUnorderedEXT: return "PixelInterlockUnorderedEXT"; @@ -208,6 +217,10 @@ const char* ExecutionModeString(int mode) case ExecutionModeNoGlobalOffsetINTEL: return "NoGlobalOffsetINTEL"; case ExecutionModeNumSIMDWorkitemsINTEL: return "NumSIMDWorkitemsINTEL"; + case ExecutionModeNonCoherentColorAttachmentReadEXT: return "NonCoherentColorAttachmentReadEXT"; + case ExecutionModeNonCoherentDepthAttachmentReadEXT: return "NonCoherentDepthAttachmentReadEXT"; + case ExecutionModeNonCoherentStencilAttachmentReadEXT: return "NonCoherentStencilAttachmentReadEXT"; + case ExecutionModeCeiling: default: return "Bad"; } @@ -238,7 +251,9 @@ const char* StorageClassString(int StorageClass) case StorageClassIncomingCallableDataKHR: return "IncomingCallableDataKHR"; case StorageClassPhysicalStorageBufferEXT: return "PhysicalStorageBufferEXT"; - + case StorageClassTaskPayloadWorkgroupEXT: return "TaskPayloadWorkgroupEXT"; + case StorageClassHitObjectAttributeNV: return "HitObjectAttributeNV"; + case StorageClassTileImageEXT: return "TileImageEXT"; default: return "Bad"; } } @@ -297,7 +312,9 @@ const char* DecorationString(int decoration) case DecorationCeiling: default: return "Bad"; - case DecorationExplicitInterpAMD: return "ExplicitInterpAMD"; + case DecorationWeightTextureQCOM: return "DecorationWeightTextureQCOM"; + case DecorationBlockMatchTextureQCOM: return "DecorationBlockMatchTextureQCOM"; + case DecorationExplicitInterpAMD: return "ExplicitInterpAMD"; case DecorationOverrideCoverageNV: return "OverrideCoverageNV"; case DecorationPassthroughNV: return "PassthroughNV"; case DecorationViewportRelativeNV: return "ViewportRelativeNV"; @@ -305,13 +322,16 @@ const char* DecorationString(int decoration) case DecorationPerPrimitiveNV: return "PerPrimitiveNV"; case DecorationPerViewNV: return "PerViewNV"; case DecorationPerTaskNV: return "PerTaskNV"; - case DecorationPerVertexNV: return "PerVertexNV"; + + case DecorationPerVertexKHR: return "PerVertexKHR"; case DecorationNonUniformEXT: return "DecorationNonUniformEXT"; case DecorationHlslCounterBufferGOOGLE: return "DecorationHlslCounterBufferGOOGLE"; case DecorationHlslSemanticGOOGLE: return "DecorationHlslSemanticGOOGLE"; case DecorationRestrictPointerEXT: return "DecorationRestrictPointerEXT"; case DecorationAliasedPointerEXT: return "DecorationAliasedPointerEXT"; + + case DecorationHitObjectShaderRecordBufferNV: return "DecorationHitObjectShaderRecordBufferNV"; } } @@ -392,6 +412,12 @@ const char* BuiltInString(int builtIn) case BuiltInObjectRayDirectionKHR: return "ObjectRayDirectionKHR"; case BuiltInRayTminKHR: return "RayTminKHR"; case BuiltInRayTmaxKHR: return "RayTmaxKHR"; + case BuiltInCullMaskKHR: return "CullMaskKHR"; + case BuiltInHitTriangleVertexPositionsKHR: return "HitTriangleVertexPositionsKHR"; + case BuiltInHitMicroTriangleVertexPositionsNV: return "HitMicroTriangleVertexPositionsNV"; + case BuiltInHitMicroTriangleVertexBarycentricsNV: return "HitMicroTriangleVertexBarycentricsNV"; + case BuiltInHitKindFrontFacingMicroTriangleNV: return "HitKindFrontFacingMicroTriangleNV"; + case BuiltInHitKindBackFacingMicroTriangleNV: return "HitKindBackFacingMicroTriangleNV"; case BuiltInInstanceCustomIndexKHR: return "InstanceCustomIndexKHR"; case BuiltInRayGeometryIndexKHR: return "RayGeometryIndexKHR"; case BuiltInObjectToWorldKHR: return "ObjectToWorldKHR"; @@ -406,8 +432,8 @@ const char* BuiltInString(int builtIn) case BuiltInViewportMaskPerViewNV: return "ViewportMaskPerViewNV"; // case BuiltInFragmentSizeNV: return "FragmentSizeNV"; // superseded by BuiltInFragSizeEXT // case BuiltInInvocationsPerPixelNV: return "InvocationsPerPixelNV"; // superseded by BuiltInFragInvocationCountEXT - case BuiltInBaryCoordNV: return "BaryCoordNV"; - case BuiltInBaryCoordNoPerspNV: return "BaryCoordNoPerspNV"; + case BuiltInBaryCoordKHR: return "BaryCoordKHR"; + case BuiltInBaryCoordNoPerspKHR: return "BaryCoordNoPerspKHR"; case BuiltInFragSizeEXT: return "FragSizeEXT"; case BuiltInFragInvocationCountEXT: return "FragInvocationCountEXT"; @@ -427,6 +453,15 @@ const char* BuiltInString(int builtIn) case BuiltInWarpIDNV: return "WarpIDNV"; case BuiltInSMIDNV: return "SMIDNV"; case BuiltInCurrentRayTimeNV: return "CurrentRayTimeNV"; + case BuiltInPrimitivePointIndicesEXT: return "PrimitivePointIndicesEXT"; + case BuiltInPrimitiveLineIndicesEXT: return "PrimitiveLineIndicesEXT"; + case BuiltInPrimitiveTriangleIndicesEXT: return "PrimitiveTriangleIndicesEXT"; + case BuiltInCullPrimitiveEXT: return "CullPrimitiveEXT"; + case BuiltInCoreCountARM: return "CoreCountARM"; + case BuiltInCoreIDARM: return "CoreIDARM"; + case BuiltInCoreMaxIDARM: return "CoreMaxIDARM"; + case BuiltInWarpIDARM: return "WarpIDARM"; + case BuiltInWarpMaxIDARM: return "BuiltInWarpMaxIDARM"; default: return "Bad"; } @@ -442,6 +477,7 @@ const char* DimensionString(int dim) case 4: return "Rect"; case 5: return "Buffer"; case 6: return "SubpassData"; + case DimTileImageDataEXT: return "TileImageDataEXT"; default: return "Bad"; } @@ -556,7 +592,7 @@ const char* ImageChannelOrderString(int format) case 17: return "sRGBA"; case 18: return "sBGRA"; - default: + default: return "Bad"; } } @@ -761,6 +797,21 @@ const char* MemoryAccessString(int mem) } } +const int CooperativeMatrixOperandsCeiling = 6; + +const char* CooperativeMatrixOperandsString(int op) +{ + switch (op) { + case CooperativeMatrixOperandsMatrixASignedComponentsKHRShift: return "ASignedComponentsKHR"; + case CooperativeMatrixOperandsMatrixBSignedComponentsKHRShift: return "BSignedComponentsKHR"; + case CooperativeMatrixOperandsMatrixCSignedComponentsKHRShift: return "CSignedComponentsKHR"; + case CooperativeMatrixOperandsMatrixResultSignedComponentsKHRShift: return "ResultSignedComponentsKHR"; + case CooperativeMatrixOperandsSaturatingAccumulationKHRShift: return "SaturatingAccumulationKHR"; + + default: return "Bad"; + } +} + const char* ScopeString(int mem) { switch (mem) { @@ -842,7 +893,7 @@ const char* CapabilityString(int info) case 22: return "Int16"; case 23: return "TessellationPointSize"; case 24: return "GeometryPointSize"; - case 25: return "ImageGatherExtended"; + case 25: return "ImageGatherExtended"; case 26: return "Bad"; case 27: return "StorageImageMultisample"; case 28: return "UniformBufferArrayDynamicIndexing"; @@ -925,14 +976,20 @@ const char* CapabilityString(int info) case CapabilityRayTracingNV: return "RayTracingNV"; case CapabilityRayTracingMotionBlurNV: return "RayTracingMotionBlurNV"; case CapabilityRayTracingKHR: return "RayTracingKHR"; + case CapabilityRayCullMaskKHR: return "RayCullMaskKHR"; case CapabilityRayQueryKHR: return "RayQueryKHR"; case CapabilityRayTracingProvisionalKHR: return "RayTracingProvisionalKHR"; case CapabilityRayTraversalPrimitiveCullingKHR: return "RayTraversalPrimitiveCullingKHR"; + case CapabilityRayTracingPositionFetchKHR: return "RayTracingPositionFetchKHR"; + case CapabilityDisplacementMicromapNV: return "DisplacementMicromapNV"; + case CapabilityRayTracingDisplacementMicromapNV: return "CapabilityRayTracingDisplacementMicromapNV"; + case CapabilityRayQueryPositionFetchKHR: return "RayQueryPositionFetchKHR"; case CapabilityComputeDerivativeGroupQuadsNV: return "ComputeDerivativeGroupQuadsNV"; case CapabilityComputeDerivativeGroupLinearNV: return "ComputeDerivativeGroupLinearNV"; - case CapabilityFragmentBarycentricNV: return "FragmentBarycentricNV"; + case CapabilityFragmentBarycentricKHR: return "FragmentBarycentricKHR"; case CapabilityMeshShadingNV: return "MeshShadingNV"; case CapabilityImageFootprintNV: return "ImageFootprintNV"; + case CapabilityMeshShadingEXT: return "MeshShadingEXT"; // case CapabilityShadingRateNV: return "ShadingRateNV"; // superseded by FragmentDensityEXT case CapabilitySampleMaskOverrideCoverageNV: return "SampleMaskOverrideCoverageNV"; case CapabilityFragmentDensityEXT: return "FragmentDensityEXT"; @@ -960,12 +1017,17 @@ const char* CapabilityString(int info) case CapabilityVariablePointers: return "VariablePointers"; case CapabilityCooperativeMatrixNV: return "CooperativeMatrixNV"; + case CapabilityCooperativeMatrixKHR: return "CooperativeMatrixKHR"; case CapabilityShaderSMBuiltinsNV: return "ShaderSMBuiltinsNV"; case CapabilityFragmentShaderSampleInterlockEXT: return "CapabilityFragmentShaderSampleInterlockEXT"; case CapabilityFragmentShaderPixelInterlockEXT: return "CapabilityFragmentShaderPixelInterlockEXT"; case CapabilityFragmentShaderShadingRateInterlockEXT: return "CapabilityFragmentShaderShadingRateInterlockEXT"; + case CapabilityTileImageColorReadAccessEXT: return "TileImageColorReadAccessEXT"; + case CapabilityTileImageDepthReadAccessEXT: return "TileImageDepthReadAccessEXT"; + case CapabilityTileImageStencilReadAccessEXT: return "TileImageStencilReadAccessEXT"; + case CapabilityFragmentShadingRateKHR: return "FragmentShadingRateKHR"; case CapabilityDemoteToHelperInvocationEXT: return "DemoteToHelperInvocationEXT"; @@ -984,6 +1046,13 @@ const char* CapabilityString(int info) case CapabilityWorkgroupMemoryExplicitLayoutKHR: return "CapabilityWorkgroupMemoryExplicitLayoutKHR"; case CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR"; case CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR: return "CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR"; + case CapabilityCoreBuiltinsARM: return "CoreBuiltinsARM"; + + case CapabilityShaderInvocationReorderNV: return "ShaderInvocationReorderNV"; + + case CapabilityTextureSampleWeightedQCOM: return "TextureSampleWeightedQCOM"; + case CapabilityTextureBoxFilterQCOM: return "TextureBoxFilterQCOM"; + case CapabilityTextureBlockMatchQCOM: return "TextureBlockMatchQCOM"; default: return "Bad"; } @@ -1400,6 +1469,8 @@ const char* OpcodeString(int op) case OpGroupNonUniformPartitionNV: return "OpGroupNonUniformPartitionNV"; case OpImageSampleFootprintNV: return "OpImageSampleFootprintNV"; case OpWritePackedPrimitiveIndices4x8NV: return "OpWritePackedPrimitiveIndices4x8NV"; + case OpEmitMeshTasksEXT: return "OpEmitMeshTasksEXT"; + case OpSetMeshOutputsEXT: return "OpSetMeshOutputsEXT"; case OpTypeRayQueryKHR: return "OpTypeRayQueryKHR"; case OpRayQueryInitializeKHR: return "OpRayQueryInitializeKHR"; @@ -1425,18 +1496,70 @@ const char* OpcodeString(int op) case OpRayQueryGetWorldRayOriginKHR: return "OpRayQueryGetWorldRayOriginKHR"; case OpRayQueryGetIntersectionObjectToWorldKHR: return "OpRayQueryGetIntersectionObjectToWorldKHR"; case OpRayQueryGetIntersectionWorldToObjectKHR: return "OpRayQueryGetIntersectionWorldToObjectKHR"; + case OpRayQueryGetIntersectionTriangleVertexPositionsKHR: return "OpRayQueryGetIntersectionTriangleVertexPositionsKHR"; case OpTypeCooperativeMatrixNV: return "OpTypeCooperativeMatrixNV"; case OpCooperativeMatrixLoadNV: return "OpCooperativeMatrixLoadNV"; case OpCooperativeMatrixStoreNV: return "OpCooperativeMatrixStoreNV"; case OpCooperativeMatrixMulAddNV: return "OpCooperativeMatrixMulAddNV"; case OpCooperativeMatrixLengthNV: return "OpCooperativeMatrixLengthNV"; + case OpTypeCooperativeMatrixKHR: return "OpTypeCooperativeMatrixKHR"; + case OpCooperativeMatrixLoadKHR: return "OpCooperativeMatrixLoadKHR"; + case OpCooperativeMatrixStoreKHR: return "OpCooperativeMatrixStoreKHR"; + case OpCooperativeMatrixMulAddKHR: return "OpCooperativeMatrixMulAddKHR"; + case OpCooperativeMatrixLengthKHR: return "OpCooperativeMatrixLengthKHR"; case OpDemoteToHelperInvocationEXT: return "OpDemoteToHelperInvocationEXT"; case OpIsHelperInvocationEXT: return "OpIsHelperInvocationEXT"; case OpBeginInvocationInterlockEXT: return "OpBeginInvocationInterlockEXT"; case OpEndInvocationInterlockEXT: return "OpEndInvocationInterlockEXT"; + case OpTypeHitObjectNV: return "OpTypeHitObjectNV"; + case OpHitObjectTraceRayNV: return "OpHitObjectTraceRayNV"; + case OpHitObjectTraceRayMotionNV: return "OpHitObjectTraceRayMotionNV"; + case OpHitObjectRecordHitNV: return "OpHitObjectRecordHitNV"; + case OpHitObjectRecordHitMotionNV: return "OpHitObjectRecordHitMotionNV"; + case OpHitObjectRecordHitWithIndexNV: return "OpHitObjectRecordHitWithIndexNV"; + case OpHitObjectRecordHitWithIndexMotionNV: return "OpHitObjectRecordHitWithIndexMotionNV"; + case OpHitObjectRecordMissNV: return "OpHitObjectRecordMissNV"; + case OpHitObjectRecordMissMotionNV: return "OpHitObjectRecordMissMotionNV"; + case OpHitObjectRecordEmptyNV: return "OpHitObjectRecordEmptyNV"; + case OpHitObjectExecuteShaderNV: return "OpHitObjectExecuteShaderNV"; + case OpReorderThreadWithHintNV: return "OpReorderThreadWithHintNV"; + case OpReorderThreadWithHitObjectNV: return "OpReorderThreadWithHitObjectNV"; + case OpHitObjectGetCurrentTimeNV: return "OpHitObjectGetCurrentTimeNV"; + case OpHitObjectGetAttributesNV: return "OpHitObjectGetAttributesNV"; + case OpHitObjectGetHitKindNV: return "OpHitObjectGetFrontFaceNV"; + case OpHitObjectGetPrimitiveIndexNV: return "OpHitObjectGetPrimitiveIndexNV"; + case OpHitObjectGetGeometryIndexNV: return "OpHitObjectGetGeometryIndexNV"; + case OpHitObjectGetInstanceIdNV: return "OpHitObjectGetInstanceIdNV"; + case OpHitObjectGetInstanceCustomIndexNV: return "OpHitObjectGetInstanceCustomIndexNV"; + case OpHitObjectGetObjectRayDirectionNV: return "OpHitObjectGetObjectRayDirectionNV"; + case OpHitObjectGetObjectRayOriginNV: return "OpHitObjectGetObjectRayOriginNV"; + case OpHitObjectGetWorldRayDirectionNV: return "OpHitObjectGetWorldRayDirectionNV"; + case OpHitObjectGetWorldRayOriginNV: return "OpHitObjectGetWorldRayOriginNV"; + case OpHitObjectGetWorldToObjectNV: return "OpHitObjectGetWorldToObjectNV"; + case OpHitObjectGetObjectToWorldNV: return "OpHitObjectGetObjectToWorldNV"; + case OpHitObjectGetRayTMaxNV: return "OpHitObjectGetRayTMaxNV"; + case OpHitObjectGetRayTMinNV: return "OpHitObjectGetRayTMinNV"; + case OpHitObjectIsEmptyNV: return "OpHitObjectIsEmptyNV"; + case OpHitObjectIsHitNV: return "OpHitObjectIsHitNV"; + case OpHitObjectIsMissNV: return "OpHitObjectIsMissNV"; + case OpHitObjectGetShaderBindingTableRecordIndexNV: return "OpHitObjectGetShaderBindingTableRecordIndexNV"; + case OpHitObjectGetShaderRecordBufferHandleNV: return "OpHitObjectGetShaderRecordBufferHandleNV"; + + case OpFetchMicroTriangleVertexBarycentricNV: return "OpFetchMicroTriangleVertexBarycentricNV"; + case OpFetchMicroTriangleVertexPositionNV: return "OpFetchMicroTriangleVertexPositionNV"; + + case OpColorAttachmentReadEXT: return "OpColorAttachmentReadEXT"; + case OpDepthAttachmentReadEXT: return "OpDepthAttachmentReadEXT"; + case OpStencilAttachmentReadEXT: return "OpStencilAttachmentReadEXT"; + + case OpImageSampleWeightedQCOM: return "OpImageSampleWeightedQCOM"; + case OpImageBoxFilterQCOM: return "OpImageBoxFilterQCOM"; + case OpImageBlockMatchSADQCOM: return "OpImageBlockMatchSADQCOM"; + case OpImageBlockMatchSSDQCOM: return "OpImageBlockMatchSSDQCOM"; + default: return "Bad"; } @@ -1456,1553 +1579,1831 @@ EnumParameters LoopControlParams[FunctionControlCeiling]; EnumParameters SelectionControlParams[SelectControlCeiling]; EnumParameters FunctionControlParams[FunctionControlCeiling]; EnumParameters MemoryAccessParams[MemoryAccessCeiling]; +EnumParameters CooperativeMatrixOperandsParams[CooperativeMatrixOperandsCeiling]; // Set up all the parameterizing descriptions of the opcodes, operands, etc. void Parameterize() { // only do this once. - static bool initialized = false; - if (initialized) - return; - initialized = true; - - // Exceptions to having a result and a resulting type . - // (Everything is initialized to have both). - - InstructionDesc[OpNop].setResultAndType(false, false); - InstructionDesc[OpSource].setResultAndType(false, false); - InstructionDesc[OpSourceContinued].setResultAndType(false, false); - InstructionDesc[OpSourceExtension].setResultAndType(false, false); - InstructionDesc[OpExtension].setResultAndType(false, false); - InstructionDesc[OpExtInstImport].setResultAndType(true, false); - InstructionDesc[OpCapability].setResultAndType(false, false); - InstructionDesc[OpMemoryModel].setResultAndType(false, false); - InstructionDesc[OpEntryPoint].setResultAndType(false, false); - InstructionDesc[OpExecutionMode].setResultAndType(false, false); - InstructionDesc[OpExecutionModeId].setResultAndType(false, false); - InstructionDesc[OpTypeVoid].setResultAndType(true, false); - InstructionDesc[OpTypeBool].setResultAndType(true, false); - InstructionDesc[OpTypeInt].setResultAndType(true, false); - InstructionDesc[OpTypeFloat].setResultAndType(true, false); - InstructionDesc[OpTypeVector].setResultAndType(true, false); - InstructionDesc[OpTypeMatrix].setResultAndType(true, false); - InstructionDesc[OpTypeImage].setResultAndType(true, false); - InstructionDesc[OpTypeSampler].setResultAndType(true, false); - InstructionDesc[OpTypeSampledImage].setResultAndType(true, false); - InstructionDesc[OpTypeArray].setResultAndType(true, false); - InstructionDesc[OpTypeRuntimeArray].setResultAndType(true, false); - InstructionDesc[OpTypeStruct].setResultAndType(true, false); - InstructionDesc[OpTypeOpaque].setResultAndType(true, false); - InstructionDesc[OpTypePointer].setResultAndType(true, false); - InstructionDesc[OpTypeForwardPointer].setResultAndType(false, false); - InstructionDesc[OpTypeFunction].setResultAndType(true, false); - InstructionDesc[OpTypeEvent].setResultAndType(true, false); - InstructionDesc[OpTypeDeviceEvent].setResultAndType(true, false); - InstructionDesc[OpTypeReserveId].setResultAndType(true, false); - InstructionDesc[OpTypeQueue].setResultAndType(true, false); - InstructionDesc[OpTypePipe].setResultAndType(true, false); - InstructionDesc[OpFunctionEnd].setResultAndType(false, false); - InstructionDesc[OpStore].setResultAndType(false, false); - InstructionDesc[OpImageWrite].setResultAndType(false, false); - InstructionDesc[OpDecorationGroup].setResultAndType(true, false); - InstructionDesc[OpDecorate].setResultAndType(false, false); - InstructionDesc[OpDecorateId].setResultAndType(false, false); - InstructionDesc[OpDecorateStringGOOGLE].setResultAndType(false, false); - InstructionDesc[OpMemberDecorate].setResultAndType(false, false); - InstructionDesc[OpMemberDecorateStringGOOGLE].setResultAndType(false, false); - InstructionDesc[OpGroupDecorate].setResultAndType(false, false); - InstructionDesc[OpGroupMemberDecorate].setResultAndType(false, false); - InstructionDesc[OpName].setResultAndType(false, false); - InstructionDesc[OpMemberName].setResultAndType(false, false); - InstructionDesc[OpString].setResultAndType(true, false); - InstructionDesc[OpLine].setResultAndType(false, false); - InstructionDesc[OpNoLine].setResultAndType(false, false); - InstructionDesc[OpCopyMemory].setResultAndType(false, false); - InstructionDesc[OpCopyMemorySized].setResultAndType(false, false); - InstructionDesc[OpEmitVertex].setResultAndType(false, false); - InstructionDesc[OpEndPrimitive].setResultAndType(false, false); - InstructionDesc[OpEmitStreamVertex].setResultAndType(false, false); - InstructionDesc[OpEndStreamPrimitive].setResultAndType(false, false); - InstructionDesc[OpControlBarrier].setResultAndType(false, false); - InstructionDesc[OpMemoryBarrier].setResultAndType(false, false); - InstructionDesc[OpAtomicStore].setResultAndType(false, false); - InstructionDesc[OpLoopMerge].setResultAndType(false, false); - InstructionDesc[OpSelectionMerge].setResultAndType(false, false); - InstructionDesc[OpLabel].setResultAndType(true, false); - InstructionDesc[OpBranch].setResultAndType(false, false); - InstructionDesc[OpBranchConditional].setResultAndType(false, false); - InstructionDesc[OpSwitch].setResultAndType(false, false); - InstructionDesc[OpKill].setResultAndType(false, false); - InstructionDesc[OpTerminateInvocation].setResultAndType(false, false); - InstructionDesc[OpReturn].setResultAndType(false, false); - InstructionDesc[OpReturnValue].setResultAndType(false, false); - InstructionDesc[OpUnreachable].setResultAndType(false, false); - InstructionDesc[OpLifetimeStart].setResultAndType(false, false); - InstructionDesc[OpLifetimeStop].setResultAndType(false, false); - InstructionDesc[OpCommitReadPipe].setResultAndType(false, false); - InstructionDesc[OpCommitWritePipe].setResultAndType(false, false); - InstructionDesc[OpGroupCommitWritePipe].setResultAndType(false, false); - InstructionDesc[OpGroupCommitReadPipe].setResultAndType(false, false); - InstructionDesc[OpCaptureEventProfilingInfo].setResultAndType(false, false); - InstructionDesc[OpSetUserEventStatus].setResultAndType(false, false); - InstructionDesc[OpRetainEvent].setResultAndType(false, false); - InstructionDesc[OpReleaseEvent].setResultAndType(false, false); - InstructionDesc[OpGroupWaitEvents].setResultAndType(false, false); - InstructionDesc[OpAtomicFlagClear].setResultAndType(false, false); - InstructionDesc[OpModuleProcessed].setResultAndType(false, false); - InstructionDesc[OpTypeCooperativeMatrixNV].setResultAndType(true, false); - InstructionDesc[OpCooperativeMatrixStoreNV].setResultAndType(false, false); - InstructionDesc[OpBeginInvocationInterlockEXT].setResultAndType(false, false); - InstructionDesc[OpEndInvocationInterlockEXT].setResultAndType(false, false); - - // Specific additional context-dependent operands - - ExecutionModeOperands[ExecutionModeInvocations].push(OperandLiteralNumber, "'Number of <>'"); - - ExecutionModeOperands[ExecutionModeLocalSize].push(OperandLiteralNumber, "'x size'"); - ExecutionModeOperands[ExecutionModeLocalSize].push(OperandLiteralNumber, "'y size'"); - ExecutionModeOperands[ExecutionModeLocalSize].push(OperandLiteralNumber, "'z size'"); - - ExecutionModeOperands[ExecutionModeLocalSizeHint].push(OperandLiteralNumber, "'x size'"); - ExecutionModeOperands[ExecutionModeLocalSizeHint].push(OperandLiteralNumber, "'y size'"); - ExecutionModeOperands[ExecutionModeLocalSizeHint].push(OperandLiteralNumber, "'z size'"); - - ExecutionModeOperands[ExecutionModeOutputVertices].push(OperandLiteralNumber, "'Vertex count'"); - ExecutionModeOperands[ExecutionModeVecTypeHint].push(OperandLiteralNumber, "'Vector type'"); - - DecorationOperands[DecorationStream].push(OperandLiteralNumber, "'Stream Number'"); - DecorationOperands[DecorationLocation].push(OperandLiteralNumber, "'Location'"); - DecorationOperands[DecorationComponent].push(OperandLiteralNumber, "'Component'"); - DecorationOperands[DecorationIndex].push(OperandLiteralNumber, "'Index'"); - DecorationOperands[DecorationBinding].push(OperandLiteralNumber, "'Binding Point'"); - DecorationOperands[DecorationDescriptorSet].push(OperandLiteralNumber, "'Descriptor Set'"); - DecorationOperands[DecorationOffset].push(OperandLiteralNumber, "'Byte Offset'"); - DecorationOperands[DecorationXfbBuffer].push(OperandLiteralNumber, "'XFB Buffer Number'"); - DecorationOperands[DecorationXfbStride].push(OperandLiteralNumber, "'XFB Stride'"); - DecorationOperands[DecorationArrayStride].push(OperandLiteralNumber, "'Array Stride'"); - DecorationOperands[DecorationMatrixStride].push(OperandLiteralNumber, "'Matrix Stride'"); - DecorationOperands[DecorationBuiltIn].push(OperandLiteralNumber, "See <>"); - DecorationOperands[DecorationFPRoundingMode].push(OperandFPRoundingMode, "'Floating-Point Rounding Mode'"); - DecorationOperands[DecorationFPFastMathMode].push(OperandFPFastMath, "'Fast-Math Mode'"); - DecorationOperands[DecorationLinkageAttributes].push(OperandLiteralString, "'Name'"); - DecorationOperands[DecorationLinkageAttributes].push(OperandLinkageType, "'Linkage Type'"); - DecorationOperands[DecorationFuncParamAttr].push(OperandFuncParamAttr, "'Function Parameter Attribute'"); - DecorationOperands[DecorationSpecId].push(OperandLiteralNumber, "'Specialization Constant ID'"); - DecorationOperands[DecorationInputAttachmentIndex].push(OperandLiteralNumber, "'Attachment Index'"); - DecorationOperands[DecorationAlignment].push(OperandLiteralNumber, "'Alignment'"); - - OperandClassParams[OperandSource].set(0, SourceString, 0); - OperandClassParams[OperandExecutionModel].set(0, ExecutionModelString, nullptr); - OperandClassParams[OperandAddressing].set(0, AddressingString, nullptr); - OperandClassParams[OperandMemory].set(0, MemoryString, nullptr); - OperandClassParams[OperandExecutionMode].set(ExecutionModeCeiling, ExecutionModeString, ExecutionModeParams); - OperandClassParams[OperandExecutionMode].setOperands(ExecutionModeOperands); - OperandClassParams[OperandStorage].set(0, StorageClassString, nullptr); - OperandClassParams[OperandDimensionality].set(0, DimensionString, nullptr); - OperandClassParams[OperandSamplerAddressingMode].set(0, SamplerAddressingModeString, nullptr); - OperandClassParams[OperandSamplerFilterMode].set(0, SamplerFilterModeString, nullptr); - OperandClassParams[OperandSamplerImageFormat].set(0, ImageFormatString, nullptr); - OperandClassParams[OperandImageChannelOrder].set(0, ImageChannelOrderString, nullptr); - OperandClassParams[OperandImageChannelDataType].set(0, ImageChannelDataTypeString, nullptr); - OperandClassParams[OperandImageOperands].set(ImageOperandsCeiling, ImageOperandsString, ImageOperandsParams, true); - OperandClassParams[OperandFPFastMath].set(0, FPFastMathString, nullptr, true); - OperandClassParams[OperandFPRoundingMode].set(0, FPRoundingModeString, nullptr); - OperandClassParams[OperandLinkageType].set(0, LinkageTypeString, nullptr); - OperandClassParams[OperandFuncParamAttr].set(0, FuncParamAttrString, nullptr); - OperandClassParams[OperandAccessQualifier].set(0, AccessQualifierString, nullptr); - OperandClassParams[OperandDecoration].set(DecorationCeiling, DecorationString, DecorationParams); - OperandClassParams[OperandDecoration].setOperands(DecorationOperands); - OperandClassParams[OperandBuiltIn].set(0, BuiltInString, nullptr); - OperandClassParams[OperandSelect].set(SelectControlCeiling, SelectControlString, SelectionControlParams, true); - OperandClassParams[OperandLoop].set(LoopControlCeiling, LoopControlString, LoopControlParams, true); - OperandClassParams[OperandFunction].set(FunctionControlCeiling, FunctionControlString, FunctionControlParams, true); - OperandClassParams[OperandMemorySemantics].set(0, MemorySemanticsString, nullptr, true); - OperandClassParams[OperandMemoryAccess].set(MemoryAccessCeiling, MemoryAccessString, MemoryAccessParams, true); - OperandClassParams[OperandScope].set(0, ScopeString, nullptr); - OperandClassParams[OperandGroupOperation].set(0, GroupOperationString, nullptr); - OperandClassParams[OperandKernelEnqueueFlags].set(0, KernelEnqueueFlagsString, nullptr); - OperandClassParams[OperandKernelProfilingInfo].set(0, KernelProfilingInfoString, nullptr, true); - OperandClassParams[OperandCapability].set(0, CapabilityString, nullptr); - OperandClassParams[OperandOpcode].set(OpCodeMask + 1, OpcodeString, 0); - - // set name of operator, an initial set of style operands, and the description - - InstructionDesc[OpSource].operands.push(OperandSource, ""); - InstructionDesc[OpSource].operands.push(OperandLiteralNumber, "'Version'"); - InstructionDesc[OpSource].operands.push(OperandId, "'File'", true); - InstructionDesc[OpSource].operands.push(OperandLiteralString, "'Source'", true); - - InstructionDesc[OpSourceContinued].operands.push(OperandLiteralString, "'Continued Source'"); - - InstructionDesc[OpSourceExtension].operands.push(OperandLiteralString, "'Extension'"); - - InstructionDesc[OpName].operands.push(OperandId, "'Target'"); - InstructionDesc[OpName].operands.push(OperandLiteralString, "'Name'"); - - InstructionDesc[OpMemberName].operands.push(OperandId, "'Type'"); - InstructionDesc[OpMemberName].operands.push(OperandLiteralNumber, "'Member'"); - InstructionDesc[OpMemberName].operands.push(OperandLiteralString, "'Name'"); - - InstructionDesc[OpString].operands.push(OperandLiteralString, "'String'"); - - InstructionDesc[OpLine].operands.push(OperandId, "'File'"); - InstructionDesc[OpLine].operands.push(OperandLiteralNumber, "'Line'"); - InstructionDesc[OpLine].operands.push(OperandLiteralNumber, "'Column'"); - - InstructionDesc[OpExtension].operands.push(OperandLiteralString, "'Name'"); - - InstructionDesc[OpExtInstImport].operands.push(OperandLiteralString, "'Name'"); - - InstructionDesc[OpCapability].operands.push(OperandCapability, "'Capability'"); + static std::once_flag initialized; + std::call_once(initialized, [](){ + + // Exceptions to having a result and a resulting type . + // (Everything is initialized to have both). + + InstructionDesc[OpNop].setResultAndType(false, false); + InstructionDesc[OpSource].setResultAndType(false, false); + InstructionDesc[OpSourceContinued].setResultAndType(false, false); + InstructionDesc[OpSourceExtension].setResultAndType(false, false); + InstructionDesc[OpExtension].setResultAndType(false, false); + InstructionDesc[OpExtInstImport].setResultAndType(true, false); + InstructionDesc[OpCapability].setResultAndType(false, false); + InstructionDesc[OpMemoryModel].setResultAndType(false, false); + InstructionDesc[OpEntryPoint].setResultAndType(false, false); + InstructionDesc[OpExecutionMode].setResultAndType(false, false); + InstructionDesc[OpExecutionModeId].setResultAndType(false, false); + InstructionDesc[OpTypeVoid].setResultAndType(true, false); + InstructionDesc[OpTypeBool].setResultAndType(true, false); + InstructionDesc[OpTypeInt].setResultAndType(true, false); + InstructionDesc[OpTypeFloat].setResultAndType(true, false); + InstructionDesc[OpTypeVector].setResultAndType(true, false); + InstructionDesc[OpTypeMatrix].setResultAndType(true, false); + InstructionDesc[OpTypeImage].setResultAndType(true, false); + InstructionDesc[OpTypeSampler].setResultAndType(true, false); + InstructionDesc[OpTypeSampledImage].setResultAndType(true, false); + InstructionDesc[OpTypeArray].setResultAndType(true, false); + InstructionDesc[OpTypeRuntimeArray].setResultAndType(true, false); + InstructionDesc[OpTypeStruct].setResultAndType(true, false); + InstructionDesc[OpTypeOpaque].setResultAndType(true, false); + InstructionDesc[OpTypePointer].setResultAndType(true, false); + InstructionDesc[OpTypeForwardPointer].setResultAndType(false, false); + InstructionDesc[OpTypeFunction].setResultAndType(true, false); + InstructionDesc[OpTypeEvent].setResultAndType(true, false); + InstructionDesc[OpTypeDeviceEvent].setResultAndType(true, false); + InstructionDesc[OpTypeReserveId].setResultAndType(true, false); + InstructionDesc[OpTypeQueue].setResultAndType(true, false); + InstructionDesc[OpTypePipe].setResultAndType(true, false); + InstructionDesc[OpFunctionEnd].setResultAndType(false, false); + InstructionDesc[OpStore].setResultAndType(false, false); + InstructionDesc[OpImageWrite].setResultAndType(false, false); + InstructionDesc[OpDecorationGroup].setResultAndType(true, false); + InstructionDesc[OpDecorate].setResultAndType(false, false); + InstructionDesc[OpDecorateId].setResultAndType(false, false); + InstructionDesc[OpDecorateStringGOOGLE].setResultAndType(false, false); + InstructionDesc[OpMemberDecorate].setResultAndType(false, false); + InstructionDesc[OpMemberDecorateStringGOOGLE].setResultAndType(false, false); + InstructionDesc[OpGroupDecorate].setResultAndType(false, false); + InstructionDesc[OpGroupMemberDecorate].setResultAndType(false, false); + InstructionDesc[OpName].setResultAndType(false, false); + InstructionDesc[OpMemberName].setResultAndType(false, false); + InstructionDesc[OpString].setResultAndType(true, false); + InstructionDesc[OpLine].setResultAndType(false, false); + InstructionDesc[OpNoLine].setResultAndType(false, false); + InstructionDesc[OpCopyMemory].setResultAndType(false, false); + InstructionDesc[OpCopyMemorySized].setResultAndType(false, false); + InstructionDesc[OpEmitVertex].setResultAndType(false, false); + InstructionDesc[OpEndPrimitive].setResultAndType(false, false); + InstructionDesc[OpEmitStreamVertex].setResultAndType(false, false); + InstructionDesc[OpEndStreamPrimitive].setResultAndType(false, false); + InstructionDesc[OpControlBarrier].setResultAndType(false, false); + InstructionDesc[OpMemoryBarrier].setResultAndType(false, false); + InstructionDesc[OpAtomicStore].setResultAndType(false, false); + InstructionDesc[OpLoopMerge].setResultAndType(false, false); + InstructionDesc[OpSelectionMerge].setResultAndType(false, false); + InstructionDesc[OpLabel].setResultAndType(true, false); + InstructionDesc[OpBranch].setResultAndType(false, false); + InstructionDesc[OpBranchConditional].setResultAndType(false, false); + InstructionDesc[OpSwitch].setResultAndType(false, false); + InstructionDesc[OpKill].setResultAndType(false, false); + InstructionDesc[OpTerminateInvocation].setResultAndType(false, false); + InstructionDesc[OpReturn].setResultAndType(false, false); + InstructionDesc[OpReturnValue].setResultAndType(false, false); + InstructionDesc[OpUnreachable].setResultAndType(false, false); + InstructionDesc[OpLifetimeStart].setResultAndType(false, false); + InstructionDesc[OpLifetimeStop].setResultAndType(false, false); + InstructionDesc[OpCommitReadPipe].setResultAndType(false, false); + InstructionDesc[OpCommitWritePipe].setResultAndType(false, false); + InstructionDesc[OpGroupCommitWritePipe].setResultAndType(false, false); + InstructionDesc[OpGroupCommitReadPipe].setResultAndType(false, false); + InstructionDesc[OpCaptureEventProfilingInfo].setResultAndType(false, false); + InstructionDesc[OpSetUserEventStatus].setResultAndType(false, false); + InstructionDesc[OpRetainEvent].setResultAndType(false, false); + InstructionDesc[OpReleaseEvent].setResultAndType(false, false); + InstructionDesc[OpGroupWaitEvents].setResultAndType(false, false); + InstructionDesc[OpAtomicFlagClear].setResultAndType(false, false); + InstructionDesc[OpModuleProcessed].setResultAndType(false, false); + InstructionDesc[OpTypeCooperativeMatrixNV].setResultAndType(true, false); + InstructionDesc[OpCooperativeMatrixStoreNV].setResultAndType(false, false); + InstructionDesc[OpTypeCooperativeMatrixKHR].setResultAndType(true, false); + InstructionDesc[OpCooperativeMatrixStoreKHR].setResultAndType(false, false); + InstructionDesc[OpBeginInvocationInterlockEXT].setResultAndType(false, false); + InstructionDesc[OpEndInvocationInterlockEXT].setResultAndType(false, false); + + // Specific additional context-dependent operands + + ExecutionModeOperands[ExecutionModeInvocations].push(OperandLiteralNumber, "'Number of <>'"); + + ExecutionModeOperands[ExecutionModeLocalSize].push(OperandLiteralNumber, "'x size'"); + ExecutionModeOperands[ExecutionModeLocalSize].push(OperandLiteralNumber, "'y size'"); + ExecutionModeOperands[ExecutionModeLocalSize].push(OperandLiteralNumber, "'z size'"); + + ExecutionModeOperands[ExecutionModeLocalSizeHint].push(OperandLiteralNumber, "'x size'"); + ExecutionModeOperands[ExecutionModeLocalSizeHint].push(OperandLiteralNumber, "'y size'"); + ExecutionModeOperands[ExecutionModeLocalSizeHint].push(OperandLiteralNumber, "'z size'"); + + ExecutionModeOperands[ExecutionModeOutputVertices].push(OperandLiteralNumber, "'Vertex count'"); + ExecutionModeOperands[ExecutionModeVecTypeHint].push(OperandLiteralNumber, "'Vector type'"); + + DecorationOperands[DecorationStream].push(OperandLiteralNumber, "'Stream Number'"); + DecorationOperands[DecorationLocation].push(OperandLiteralNumber, "'Location'"); + DecorationOperands[DecorationComponent].push(OperandLiteralNumber, "'Component'"); + DecorationOperands[DecorationIndex].push(OperandLiteralNumber, "'Index'"); + DecorationOperands[DecorationBinding].push(OperandLiteralNumber, "'Binding Point'"); + DecorationOperands[DecorationDescriptorSet].push(OperandLiteralNumber, "'Descriptor Set'"); + DecorationOperands[DecorationOffset].push(OperandLiteralNumber, "'Byte Offset'"); + DecorationOperands[DecorationXfbBuffer].push(OperandLiteralNumber, "'XFB Buffer Number'"); + DecorationOperands[DecorationXfbStride].push(OperandLiteralNumber, "'XFB Stride'"); + DecorationOperands[DecorationArrayStride].push(OperandLiteralNumber, "'Array Stride'"); + DecorationOperands[DecorationMatrixStride].push(OperandLiteralNumber, "'Matrix Stride'"); + DecorationOperands[DecorationBuiltIn].push(OperandLiteralNumber, "See <>"); + DecorationOperands[DecorationFPRoundingMode].push(OperandFPRoundingMode, "'Floating-Point Rounding Mode'"); + DecorationOperands[DecorationFPFastMathMode].push(OperandFPFastMath, "'Fast-Math Mode'"); + DecorationOperands[DecorationLinkageAttributes].push(OperandLiteralString, "'Name'"); + DecorationOperands[DecorationLinkageAttributes].push(OperandLinkageType, "'Linkage Type'"); + DecorationOperands[DecorationFuncParamAttr].push(OperandFuncParamAttr, "'Function Parameter Attribute'"); + DecorationOperands[DecorationSpecId].push(OperandLiteralNumber, "'Specialization Constant ID'"); + DecorationOperands[DecorationInputAttachmentIndex].push(OperandLiteralNumber, "'Attachment Index'"); + DecorationOperands[DecorationAlignment].push(OperandLiteralNumber, "'Alignment'"); + + OperandClassParams[OperandSource].set(0, SourceString, nullptr); + OperandClassParams[OperandExecutionModel].set(0, ExecutionModelString, nullptr); + OperandClassParams[OperandAddressing].set(0, AddressingString, nullptr); + OperandClassParams[OperandMemory].set(0, MemoryString, nullptr); + OperandClassParams[OperandExecutionMode].set(ExecutionModeCeiling, ExecutionModeString, ExecutionModeParams); + OperandClassParams[OperandExecutionMode].setOperands(ExecutionModeOperands); + OperandClassParams[OperandStorage].set(0, StorageClassString, nullptr); + OperandClassParams[OperandDimensionality].set(0, DimensionString, nullptr); + OperandClassParams[OperandSamplerAddressingMode].set(0, SamplerAddressingModeString, nullptr); + OperandClassParams[OperandSamplerFilterMode].set(0, SamplerFilterModeString, nullptr); + OperandClassParams[OperandSamplerImageFormat].set(0, ImageFormatString, nullptr); + OperandClassParams[OperandImageChannelOrder].set(0, ImageChannelOrderString, nullptr); + OperandClassParams[OperandImageChannelDataType].set(0, ImageChannelDataTypeString, nullptr); + OperandClassParams[OperandImageOperands].set(ImageOperandsCeiling, ImageOperandsString, ImageOperandsParams, true); + OperandClassParams[OperandFPFastMath].set(0, FPFastMathString, nullptr, true); + OperandClassParams[OperandFPRoundingMode].set(0, FPRoundingModeString, nullptr); + OperandClassParams[OperandLinkageType].set(0, LinkageTypeString, nullptr); + OperandClassParams[OperandFuncParamAttr].set(0, FuncParamAttrString, nullptr); + OperandClassParams[OperandAccessQualifier].set(0, AccessQualifierString, nullptr); + OperandClassParams[OperandDecoration].set(DecorationCeiling, DecorationString, DecorationParams); + OperandClassParams[OperandDecoration].setOperands(DecorationOperands); + OperandClassParams[OperandBuiltIn].set(0, BuiltInString, nullptr); + OperandClassParams[OperandSelect].set(SelectControlCeiling, SelectControlString, SelectionControlParams, true); + OperandClassParams[OperandLoop].set(LoopControlCeiling, LoopControlString, LoopControlParams, true); + OperandClassParams[OperandFunction].set(FunctionControlCeiling, FunctionControlString, FunctionControlParams, true); + OperandClassParams[OperandMemorySemantics].set(0, MemorySemanticsString, nullptr, true); + OperandClassParams[OperandMemoryAccess].set(MemoryAccessCeiling, MemoryAccessString, MemoryAccessParams, true); + OperandClassParams[OperandScope].set(0, ScopeString, nullptr); + OperandClassParams[OperandGroupOperation].set(0, GroupOperationString, nullptr); + OperandClassParams[OperandKernelEnqueueFlags].set(0, KernelEnqueueFlagsString, nullptr); + OperandClassParams[OperandKernelProfilingInfo].set(0, KernelProfilingInfoString, nullptr, true); + OperandClassParams[OperandCapability].set(0, CapabilityString, nullptr); + OperandClassParams[OperandCooperativeMatrixOperands].set(CooperativeMatrixOperandsCeiling, CooperativeMatrixOperandsString, CooperativeMatrixOperandsParams, true); + OperandClassParams[OperandOpcode].set(OpCodeMask + 1, OpcodeString, nullptr); + + // set name of operator, an initial set of style operands, and the description + + InstructionDesc[OpSource].operands.push(OperandSource, ""); + InstructionDesc[OpSource].operands.push(OperandLiteralNumber, "'Version'"); + InstructionDesc[OpSource].operands.push(OperandId, "'File'", true); + InstructionDesc[OpSource].operands.push(OperandLiteralString, "'Source'", true); + + InstructionDesc[OpSourceContinued].operands.push(OperandLiteralString, "'Continued Source'"); + + InstructionDesc[OpSourceExtension].operands.push(OperandLiteralString, "'Extension'"); + + InstructionDesc[OpName].operands.push(OperandId, "'Target'"); + InstructionDesc[OpName].operands.push(OperandLiteralString, "'Name'"); + + InstructionDesc[OpMemberName].operands.push(OperandId, "'Type'"); + InstructionDesc[OpMemberName].operands.push(OperandLiteralNumber, "'Member'"); + InstructionDesc[OpMemberName].operands.push(OperandLiteralString, "'Name'"); + + InstructionDesc[OpString].operands.push(OperandLiteralString, "'String'"); + + InstructionDesc[OpLine].operands.push(OperandId, "'File'"); + InstructionDesc[OpLine].operands.push(OperandLiteralNumber, "'Line'"); + InstructionDesc[OpLine].operands.push(OperandLiteralNumber, "'Column'"); + + InstructionDesc[OpExtension].operands.push(OperandLiteralString, "'Name'"); + + InstructionDesc[OpExtInstImport].operands.push(OperandLiteralString, "'Name'"); + + InstructionDesc[OpCapability].operands.push(OperandCapability, "'Capability'"); + + InstructionDesc[OpMemoryModel].operands.push(OperandAddressing, ""); + InstructionDesc[OpMemoryModel].operands.push(OperandMemory, ""); + + InstructionDesc[OpEntryPoint].operands.push(OperandExecutionModel, ""); + InstructionDesc[OpEntryPoint].operands.push(OperandId, "'Entry Point'"); + InstructionDesc[OpEntryPoint].operands.push(OperandLiteralString, "'Name'"); + InstructionDesc[OpEntryPoint].operands.push(OperandVariableIds, "'Interface'"); + + InstructionDesc[OpExecutionMode].operands.push(OperandId, "'Entry Point'"); + InstructionDesc[OpExecutionMode].operands.push(OperandExecutionMode, "'Mode'"); + InstructionDesc[OpExecutionMode].operands.push(OperandOptionalLiteral, "See <>"); + + InstructionDesc[OpExecutionModeId].operands.push(OperandId, "'Entry Point'"); + InstructionDesc[OpExecutionModeId].operands.push(OperandExecutionMode, "'Mode'"); + InstructionDesc[OpExecutionModeId].operands.push(OperandVariableIds, "See <>"); + + InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Width'"); + InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Signedness'"); + + InstructionDesc[OpTypeFloat].operands.push(OperandLiteralNumber, "'Width'"); + + InstructionDesc[OpTypeVector].operands.push(OperandId, "'Component Type'"); + InstructionDesc[OpTypeVector].operands.push(OperandLiteralNumber, "'Component Count'"); + + InstructionDesc[OpTypeMatrix].operands.push(OperandId, "'Column Type'"); + InstructionDesc[OpTypeMatrix].operands.push(OperandLiteralNumber, "'Column Count'"); + + InstructionDesc[OpTypeImage].operands.push(OperandId, "'Sampled Type'"); + InstructionDesc[OpTypeImage].operands.push(OperandDimensionality, ""); + InstructionDesc[OpTypeImage].operands.push(OperandLiteralNumber, "'Depth'"); + InstructionDesc[OpTypeImage].operands.push(OperandLiteralNumber, "'Arrayed'"); + InstructionDesc[OpTypeImage].operands.push(OperandLiteralNumber, "'MS'"); + InstructionDesc[OpTypeImage].operands.push(OperandLiteralNumber, "'Sampled'"); + InstructionDesc[OpTypeImage].operands.push(OperandSamplerImageFormat, ""); + InstructionDesc[OpTypeImage].operands.push(OperandAccessQualifier, "", true); + + InstructionDesc[OpTypeSampledImage].operands.push(OperandId, "'Image Type'"); + + InstructionDesc[OpTypeArray].operands.push(OperandId, "'Element Type'"); + InstructionDesc[OpTypeArray].operands.push(OperandId, "'Length'"); + + InstructionDesc[OpTypeRuntimeArray].operands.push(OperandId, "'Element Type'"); + + InstructionDesc[OpTypeStruct].operands.push(OperandVariableIds, "'Member 0 type', +\n'member 1 type', +\n..."); + + InstructionDesc[OpTypeOpaque].operands.push(OperandLiteralString, "The name of the opaque type."); + + InstructionDesc[OpTypePointer].operands.push(OperandStorage, ""); + InstructionDesc[OpTypePointer].operands.push(OperandId, "'Type'"); + + InstructionDesc[OpTypeForwardPointer].operands.push(OperandId, "'Pointer Type'"); + InstructionDesc[OpTypeForwardPointer].operands.push(OperandStorage, ""); + + InstructionDesc[OpTypePipe].operands.push(OperandAccessQualifier, "'Qualifier'"); + + InstructionDesc[OpTypeFunction].operands.push(OperandId, "'Return Type'"); + InstructionDesc[OpTypeFunction].operands.push(OperandVariableIds, "'Parameter 0 Type', +\n'Parameter 1 Type', +\n..."); + + InstructionDesc[OpConstant].operands.push(OperandVariableLiterals, "'Value'"); + + InstructionDesc[OpConstantComposite].operands.push(OperandVariableIds, "'Constituents'"); - InstructionDesc[OpMemoryModel].operands.push(OperandAddressing, ""); - InstructionDesc[OpMemoryModel].operands.push(OperandMemory, ""); - - InstructionDesc[OpEntryPoint].operands.push(OperandExecutionModel, ""); - InstructionDesc[OpEntryPoint].operands.push(OperandId, "'Entry Point'"); - InstructionDesc[OpEntryPoint].operands.push(OperandLiteralString, "'Name'"); - InstructionDesc[OpEntryPoint].operands.push(OperandVariableIds, "'Interface'"); - - InstructionDesc[OpExecutionMode].operands.push(OperandId, "'Entry Point'"); - InstructionDesc[OpExecutionMode].operands.push(OperandExecutionMode, "'Mode'"); - InstructionDesc[OpExecutionMode].operands.push(OperandOptionalLiteral, "See <>"); - - InstructionDesc[OpExecutionModeId].operands.push(OperandId, "'Entry Point'"); - InstructionDesc[OpExecutionModeId].operands.push(OperandExecutionMode, "'Mode'"); - InstructionDesc[OpExecutionModeId].operands.push(OperandVariableIds, "See <>"); - - InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Width'"); - InstructionDesc[OpTypeInt].operands.push(OperandLiteralNumber, "'Signedness'"); - - InstructionDesc[OpTypeFloat].operands.push(OperandLiteralNumber, "'Width'"); - - InstructionDesc[OpTypeVector].operands.push(OperandId, "'Component Type'"); - InstructionDesc[OpTypeVector].operands.push(OperandLiteralNumber, "'Component Count'"); + InstructionDesc[OpConstantSampler].operands.push(OperandSamplerAddressingMode, ""); + InstructionDesc[OpConstantSampler].operands.push(OperandLiteralNumber, "'Param'"); + InstructionDesc[OpConstantSampler].operands.push(OperandSamplerFilterMode, ""); - InstructionDesc[OpTypeMatrix].operands.push(OperandId, "'Column Type'"); - InstructionDesc[OpTypeMatrix].operands.push(OperandLiteralNumber, "'Column Count'"); + InstructionDesc[OpSpecConstant].operands.push(OperandVariableLiterals, "'Value'"); - InstructionDesc[OpTypeImage].operands.push(OperandId, "'Sampled Type'"); - InstructionDesc[OpTypeImage].operands.push(OperandDimensionality, ""); - InstructionDesc[OpTypeImage].operands.push(OperandLiteralNumber, "'Depth'"); - InstructionDesc[OpTypeImage].operands.push(OperandLiteralNumber, "'Arrayed'"); - InstructionDesc[OpTypeImage].operands.push(OperandLiteralNumber, "'MS'"); - InstructionDesc[OpTypeImage].operands.push(OperandLiteralNumber, "'Sampled'"); - InstructionDesc[OpTypeImage].operands.push(OperandSamplerImageFormat, ""); - InstructionDesc[OpTypeImage].operands.push(OperandAccessQualifier, "", true); + InstructionDesc[OpSpecConstantComposite].operands.push(OperandVariableIds, "'Constituents'"); - InstructionDesc[OpTypeSampledImage].operands.push(OperandId, "'Image Type'"); + InstructionDesc[OpSpecConstantOp].operands.push(OperandLiteralNumber, "'Opcode'"); + InstructionDesc[OpSpecConstantOp].operands.push(OperandVariableIds, "'Operands'"); - InstructionDesc[OpTypeArray].operands.push(OperandId, "'Element Type'"); - InstructionDesc[OpTypeArray].operands.push(OperandId, "'Length'"); + InstructionDesc[OpVariable].operands.push(OperandStorage, ""); + InstructionDesc[OpVariable].operands.push(OperandId, "'Initializer'", true); - InstructionDesc[OpTypeRuntimeArray].operands.push(OperandId, "'Element Type'"); + InstructionDesc[OpFunction].operands.push(OperandFunction, ""); + InstructionDesc[OpFunction].operands.push(OperandId, "'Function Type'"); - InstructionDesc[OpTypeStruct].operands.push(OperandVariableIds, "'Member 0 type', +\n'member 1 type', +\n..."); + InstructionDesc[OpFunctionCall].operands.push(OperandId, "'Function'"); + InstructionDesc[OpFunctionCall].operands.push(OperandVariableIds, "'Argument 0', +\n'Argument 1', +\n..."); - InstructionDesc[OpTypeOpaque].operands.push(OperandLiteralString, "The name of the opaque type."); + InstructionDesc[OpExtInst].operands.push(OperandId, "'Set'"); + InstructionDesc[OpExtInst].operands.push(OperandLiteralNumber, "'Instruction'"); + InstructionDesc[OpExtInst].operands.push(OperandVariableIds, "'Operand 1', +\n'Operand 2', +\n..."); - InstructionDesc[OpTypePointer].operands.push(OperandStorage, ""); - InstructionDesc[OpTypePointer].operands.push(OperandId, "'Type'"); + InstructionDesc[OpLoad].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpLoad].operands.push(OperandMemoryAccess, "", true); + InstructionDesc[OpLoad].operands.push(OperandLiteralNumber, "", true); + InstructionDesc[OpLoad].operands.push(OperandId, "", true); - InstructionDesc[OpTypeForwardPointer].operands.push(OperandId, "'Pointer Type'"); - InstructionDesc[OpTypeForwardPointer].operands.push(OperandStorage, ""); + InstructionDesc[OpStore].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpStore].operands.push(OperandId, "'Object'"); + InstructionDesc[OpStore].operands.push(OperandMemoryAccess, "", true); + InstructionDesc[OpStore].operands.push(OperandLiteralNumber, "", true); + InstructionDesc[OpStore].operands.push(OperandId, "", true); - InstructionDesc[OpTypePipe].operands.push(OperandAccessQualifier, "'Qualifier'"); + InstructionDesc[OpPhi].operands.push(OperandVariableIds, "'Variable, Parent, ...'"); - InstructionDesc[OpTypeFunction].operands.push(OperandId, "'Return Type'"); - InstructionDesc[OpTypeFunction].operands.push(OperandVariableIds, "'Parameter 0 Type', +\n'Parameter 1 Type', +\n..."); + InstructionDesc[OpDecorate].operands.push(OperandId, "'Target'"); + InstructionDesc[OpDecorate].operands.push(OperandDecoration, ""); + InstructionDesc[OpDecorate].operands.push(OperandVariableLiterals, "See <>."); - InstructionDesc[OpConstant].operands.push(OperandVariableLiterals, "'Value'"); + InstructionDesc[OpDecorateId].operands.push(OperandId, "'Target'"); + InstructionDesc[OpDecorateId].operands.push(OperandDecoration, ""); + InstructionDesc[OpDecorateId].operands.push(OperandVariableIds, "See <>."); - InstructionDesc[OpConstantComposite].operands.push(OperandVariableIds, "'Constituents'"); + InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandId, "'Target'"); + InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandDecoration, ""); + InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandVariableLiteralStrings, "'Literal Strings'"); - InstructionDesc[OpConstantSampler].operands.push(OperandSamplerAddressingMode, ""); - InstructionDesc[OpConstantSampler].operands.push(OperandLiteralNumber, "'Param'"); - InstructionDesc[OpConstantSampler].operands.push(OperandSamplerFilterMode, ""); + InstructionDesc[OpMemberDecorate].operands.push(OperandId, "'Structure Type'"); + InstructionDesc[OpMemberDecorate].operands.push(OperandLiteralNumber, "'Member'"); + InstructionDesc[OpMemberDecorate].operands.push(OperandDecoration, ""); + InstructionDesc[OpMemberDecorate].operands.push(OperandVariableLiterals, "See <>."); - InstructionDesc[OpSpecConstant].operands.push(OperandVariableLiterals, "'Value'"); + InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandId, "'Structure Type'"); + InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralNumber, "'Member'"); + InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandDecoration, ""); + InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandVariableLiteralStrings, "'Literal Strings'"); - InstructionDesc[OpSpecConstantComposite].operands.push(OperandVariableIds, "'Constituents'"); + InstructionDesc[OpGroupDecorate].operands.push(OperandId, "'Decoration Group'"); + InstructionDesc[OpGroupDecorate].operands.push(OperandVariableIds, "'Targets'"); - InstructionDesc[OpSpecConstantOp].operands.push(OperandLiteralNumber, "'Opcode'"); - InstructionDesc[OpSpecConstantOp].operands.push(OperandVariableIds, "'Operands'"); + InstructionDesc[OpGroupMemberDecorate].operands.push(OperandId, "'Decoration Group'"); + InstructionDesc[OpGroupMemberDecorate].operands.push(OperandVariableIdLiteral, "'Targets'"); - InstructionDesc[OpVariable].operands.push(OperandStorage, ""); - InstructionDesc[OpVariable].operands.push(OperandId, "'Initializer'", true); + InstructionDesc[OpVectorExtractDynamic].operands.push(OperandId, "'Vector'"); + InstructionDesc[OpVectorExtractDynamic].operands.push(OperandId, "'Index'"); - InstructionDesc[OpFunction].operands.push(OperandFunction, ""); - InstructionDesc[OpFunction].operands.push(OperandId, "'Function Type'"); + InstructionDesc[OpVectorInsertDynamic].operands.push(OperandId, "'Vector'"); + InstructionDesc[OpVectorInsertDynamic].operands.push(OperandId, "'Component'"); + InstructionDesc[OpVectorInsertDynamic].operands.push(OperandId, "'Index'"); - InstructionDesc[OpFunctionCall].operands.push(OperandId, "'Function'"); - InstructionDesc[OpFunctionCall].operands.push(OperandVariableIds, "'Argument 0', +\n'Argument 1', +\n..."); + InstructionDesc[OpVectorShuffle].operands.push(OperandId, "'Vector 1'"); + InstructionDesc[OpVectorShuffle].operands.push(OperandId, "'Vector 2'"); + InstructionDesc[OpVectorShuffle].operands.push(OperandVariableLiterals, "'Components'"); - InstructionDesc[OpExtInst].operands.push(OperandId, "'Set'"); - InstructionDesc[OpExtInst].operands.push(OperandLiteralNumber, "'Instruction'"); - InstructionDesc[OpExtInst].operands.push(OperandVariableIds, "'Operand 1', +\n'Operand 2', +\n..."); + InstructionDesc[OpCompositeConstruct].operands.push(OperandVariableIds, "'Constituents'"); - InstructionDesc[OpLoad].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpLoad].operands.push(OperandMemoryAccess, "", true); - InstructionDesc[OpLoad].operands.push(OperandLiteralNumber, "", true); - InstructionDesc[OpLoad].operands.push(OperandId, "", true); + InstructionDesc[OpCompositeExtract].operands.push(OperandId, "'Composite'"); + InstructionDesc[OpCompositeExtract].operands.push(OperandVariableLiterals, "'Indexes'"); - InstructionDesc[OpStore].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpStore].operands.push(OperandId, "'Object'"); - InstructionDesc[OpStore].operands.push(OperandMemoryAccess, "", true); - InstructionDesc[OpStore].operands.push(OperandLiteralNumber, "", true); - InstructionDesc[OpStore].operands.push(OperandId, "", true); + InstructionDesc[OpCompositeInsert].operands.push(OperandId, "'Object'"); + InstructionDesc[OpCompositeInsert].operands.push(OperandId, "'Composite'"); + InstructionDesc[OpCompositeInsert].operands.push(OperandVariableLiterals, "'Indexes'"); - InstructionDesc[OpPhi].operands.push(OperandVariableIds, "'Variable, Parent, ...'"); + InstructionDesc[OpCopyObject].operands.push(OperandId, "'Operand'"); - InstructionDesc[OpDecorate].operands.push(OperandId, "'Target'"); - InstructionDesc[OpDecorate].operands.push(OperandDecoration, ""); - InstructionDesc[OpDecorate].operands.push(OperandVariableLiterals, "See <>."); + InstructionDesc[OpCopyMemory].operands.push(OperandId, "'Target'"); + InstructionDesc[OpCopyMemory].operands.push(OperandId, "'Source'"); + InstructionDesc[OpCopyMemory].operands.push(OperandMemoryAccess, "", true); - InstructionDesc[OpDecorateId].operands.push(OperandId, "'Target'"); - InstructionDesc[OpDecorateId].operands.push(OperandDecoration, ""); - InstructionDesc[OpDecorateId].operands.push(OperandVariableIds, "See <>."); + InstructionDesc[OpCopyMemorySized].operands.push(OperandId, "'Target'"); + InstructionDesc[OpCopyMemorySized].operands.push(OperandId, "'Source'"); + InstructionDesc[OpCopyMemorySized].operands.push(OperandId, "'Size'"); + InstructionDesc[OpCopyMemorySized].operands.push(OperandMemoryAccess, "", true); + + InstructionDesc[OpSampledImage].operands.push(OperandId, "'Image'"); + InstructionDesc[OpSampledImage].operands.push(OperandId, "'Sampler'"); + + InstructionDesc[OpImage].operands.push(OperandId, "'Sampled Image'"); + + InstructionDesc[OpImageRead].operands.push(OperandId, "'Image'"); + InstructionDesc[OpImageRead].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageRead].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageRead].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageWrite].operands.push(OperandId, "'Image'"); + InstructionDesc[OpImageWrite].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageWrite].operands.push(OperandId, "'Texel'"); + InstructionDesc[OpImageWrite].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageWrite].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandId, "'D~ref~'"); + InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandId, "'D~ref~'"); + InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandId, "'D~ref~'"); + InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandId, "'D~ref~'"); + InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageFetch].operands.push(OperandId, "'Image'"); + InstructionDesc[OpImageFetch].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageFetch].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageFetch].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageGather].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageGather].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageGather].operands.push(OperandId, "'Component'"); + InstructionDesc[OpImageGather].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageGather].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageDrefGather].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageDrefGather].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageDrefGather].operands.push(OperandId, "'D~ref~'"); + InstructionDesc[OpImageDrefGather].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageDrefGather].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandId, "'D~ref~'"); + InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandVariableIds, "", true); - InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandId, "'Target'"); - InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandDecoration, ""); - InstructionDesc[OpDecorateStringGOOGLE].operands.push(OperandVariableLiteralStrings, "'Literal Strings'"); + InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandId, "'D~ref~'"); + InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandVariableIds, "", true); - InstructionDesc[OpMemberDecorate].operands.push(OperandId, "'Structure Type'"); - InstructionDesc[OpMemberDecorate].operands.push(OperandLiteralNumber, "'Member'"); - InstructionDesc[OpMemberDecorate].operands.push(OperandDecoration, ""); - InstructionDesc[OpMemberDecorate].operands.push(OperandVariableLiterals, "See <>."); + InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandVariableIds, "", true); - InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandId, "'Structure Type'"); - InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandLiteralNumber, "'Member'"); - InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandDecoration, ""); - InstructionDesc[OpMemberDecorateStringGOOGLE].operands.push(OperandVariableLiteralStrings, "'Literal Strings'"); + InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandVariableIds, "", true); - InstructionDesc[OpGroupDecorate].operands.push(OperandId, "'Decoration Group'"); - InstructionDesc[OpGroupDecorate].operands.push(OperandVariableIds, "'Targets'"); + InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandId, "'D~ref~'"); + InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandVariableIds, "", true); - InstructionDesc[OpGroupMemberDecorate].operands.push(OperandId, "'Decoration Group'"); - InstructionDesc[OpGroupMemberDecorate].operands.push(OperandVariableIdLiteral, "'Targets'"); + InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandId, "'D~ref~'"); + InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandVariableIds, "", true); - InstructionDesc[OpVectorExtractDynamic].operands.push(OperandId, "'Vector'"); - InstructionDesc[OpVectorExtractDynamic].operands.push(OperandId, "'Index'"); + InstructionDesc[OpImageSparseFetch].operands.push(OperandId, "'Image'"); + InstructionDesc[OpImageSparseFetch].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSparseFetch].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSparseFetch].operands.push(OperandVariableIds, "", true); - InstructionDesc[OpVectorInsertDynamic].operands.push(OperandId, "'Vector'"); - InstructionDesc[OpVectorInsertDynamic].operands.push(OperandId, "'Component'"); - InstructionDesc[OpVectorInsertDynamic].operands.push(OperandId, "'Index'"); + InstructionDesc[OpImageSparseGather].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSparseGather].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSparseGather].operands.push(OperandId, "'Component'"); + InstructionDesc[OpImageSparseGather].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSparseGather].operands.push(OperandVariableIds, "", true); - InstructionDesc[OpVectorShuffle].operands.push(OperandId, "'Vector 1'"); - InstructionDesc[OpVectorShuffle].operands.push(OperandId, "'Vector 2'"); - InstructionDesc[OpVectorShuffle].operands.push(OperandVariableLiterals, "'Components'"); + InstructionDesc[OpImageSparseDrefGather].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSparseDrefGather].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSparseDrefGather].operands.push(OperandId, "'D~ref~'"); + InstructionDesc[OpImageSparseDrefGather].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSparseDrefGather].operands.push(OperandVariableIds, "", true); - InstructionDesc[OpCompositeConstruct].operands.push(OperandVariableIds, "'Constituents'"); + InstructionDesc[OpImageSparseRead].operands.push(OperandId, "'Image'"); + InstructionDesc[OpImageSparseRead].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSparseRead].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSparseRead].operands.push(OperandVariableIds, "", true); - InstructionDesc[OpCompositeExtract].operands.push(OperandId, "'Composite'"); - InstructionDesc[OpCompositeExtract].operands.push(OperandVariableLiterals, "'Indexes'"); + InstructionDesc[OpImageSparseTexelsResident].operands.push(OperandId, "'Resident Code'"); - InstructionDesc[OpCompositeInsert].operands.push(OperandId, "'Object'"); - InstructionDesc[OpCompositeInsert].operands.push(OperandId, "'Composite'"); - InstructionDesc[OpCompositeInsert].operands.push(OperandVariableLiterals, "'Indexes'"); + InstructionDesc[OpImageQuerySizeLod].operands.push(OperandId, "'Image'"); + InstructionDesc[OpImageQuerySizeLod].operands.push(OperandId, "'Level of Detail'"); - InstructionDesc[OpCopyObject].operands.push(OperandId, "'Operand'"); + InstructionDesc[OpImageQuerySize].operands.push(OperandId, "'Image'"); - InstructionDesc[OpCopyMemory].operands.push(OperandId, "'Target'"); - InstructionDesc[OpCopyMemory].operands.push(OperandId, "'Source'"); - InstructionDesc[OpCopyMemory].operands.push(OperandMemoryAccess, "", true); + InstructionDesc[OpImageQueryLod].operands.push(OperandId, "'Image'"); + InstructionDesc[OpImageQueryLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpCopyMemorySized].operands.push(OperandId, "'Target'"); - InstructionDesc[OpCopyMemorySized].operands.push(OperandId, "'Source'"); - InstructionDesc[OpCopyMemorySized].operands.push(OperandId, "'Size'"); - InstructionDesc[OpCopyMemorySized].operands.push(OperandMemoryAccess, "", true); - - InstructionDesc[OpSampledImage].operands.push(OperandId, "'Image'"); - InstructionDesc[OpSampledImage].operands.push(OperandId, "'Sampler'"); - - InstructionDesc[OpImage].operands.push(OperandId, "'Sampled Image'"); - - InstructionDesc[OpImageRead].operands.push(OperandId, "'Image'"); - InstructionDesc[OpImageRead].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageRead].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageRead].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageWrite].operands.push(OperandId, "'Image'"); - InstructionDesc[OpImageWrite].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageWrite].operands.push(OperandId, "'Texel'"); - InstructionDesc[OpImageWrite].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageWrite].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSampleImplicitLod].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSampleExplicitLod].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandId, "'D~ref~'"); - InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSampleDrefImplicitLod].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandId, "'D~ref~'"); - InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSampleDrefExplicitLod].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSampleProjImplicitLod].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSampleProjExplicitLod].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandId, "'D~ref~'"); - InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSampleProjDrefImplicitLod].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandId, "'D~ref~'"); - InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSampleProjDrefExplicitLod].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageFetch].operands.push(OperandId, "'Image'"); - InstructionDesc[OpImageFetch].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageFetch].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageFetch].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageGather].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageGather].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageGather].operands.push(OperandId, "'Component'"); - InstructionDesc[OpImageGather].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageGather].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageDrefGather].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageDrefGather].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageDrefGather].operands.push(OperandId, "'D~ref~'"); - InstructionDesc[OpImageDrefGather].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageDrefGather].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSparseSampleImplicitLod].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSparseSampleExplicitLod].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandId, "'D~ref~'"); - InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSparseSampleDrefImplicitLod].operands.push(OperandVariableIds, "", true); + InstructionDesc[OpImageQueryLevels].operands.push(OperandId, "'Image'"); - InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandId, "'D~ref~'"); - InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSparseSampleDrefExplicitLod].operands.push(OperandVariableIds, "", true); + InstructionDesc[OpImageQuerySamples].operands.push(OperandId, "'Image'"); - InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSparseSampleProjImplicitLod].operands.push(OperandVariableIds, "", true); + InstructionDesc[OpImageQueryFormat].operands.push(OperandId, "'Image'"); - InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSparseSampleProjExplicitLod].operands.push(OperandVariableIds, "", true); + InstructionDesc[OpImageQueryOrder].operands.push(OperandId, "'Image'"); - InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandId, "'D~ref~'"); - InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSparseSampleProjDrefImplicitLod].operands.push(OperandVariableIds, "", true); + InstructionDesc[OpAccessChain].operands.push(OperandId, "'Base'"); + InstructionDesc[OpAccessChain].operands.push(OperandVariableIds, "'Indexes'"); - InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandId, "'D~ref~'"); - InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSparseSampleProjDrefExplicitLod].operands.push(OperandVariableIds, "", true); + InstructionDesc[OpInBoundsAccessChain].operands.push(OperandId, "'Base'"); + InstructionDesc[OpInBoundsAccessChain].operands.push(OperandVariableIds, "'Indexes'"); - InstructionDesc[OpImageSparseFetch].operands.push(OperandId, "'Image'"); - InstructionDesc[OpImageSparseFetch].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSparseFetch].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSparseFetch].operands.push(OperandVariableIds, "", true); + InstructionDesc[OpPtrAccessChain].operands.push(OperandId, "'Base'"); + InstructionDesc[OpPtrAccessChain].operands.push(OperandId, "'Element'"); + InstructionDesc[OpPtrAccessChain].operands.push(OperandVariableIds, "'Indexes'"); - InstructionDesc[OpImageSparseGather].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSparseGather].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSparseGather].operands.push(OperandId, "'Component'"); - InstructionDesc[OpImageSparseGather].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSparseGather].operands.push(OperandVariableIds, "", true); + InstructionDesc[OpInBoundsPtrAccessChain].operands.push(OperandId, "'Base'"); + InstructionDesc[OpInBoundsPtrAccessChain].operands.push(OperandId, "'Element'"); + InstructionDesc[OpInBoundsPtrAccessChain].operands.push(OperandVariableIds, "'Indexes'"); - InstructionDesc[OpImageSparseDrefGather].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSparseDrefGather].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSparseDrefGather].operands.push(OperandId, "'D~ref~'"); - InstructionDesc[OpImageSparseDrefGather].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSparseDrefGather].operands.push(OperandVariableIds, "", true); + InstructionDesc[OpSNegate].operands.push(OperandId, "'Operand'"); - InstructionDesc[OpImageSparseRead].operands.push(OperandId, "'Image'"); - InstructionDesc[OpImageSparseRead].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSparseRead].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSparseRead].operands.push(OperandVariableIds, "", true); + InstructionDesc[OpFNegate].operands.push(OperandId, "'Operand'"); - InstructionDesc[OpImageSparseTexelsResident].operands.push(OperandId, "'Resident Code'"); + InstructionDesc[OpNot].operands.push(OperandId, "'Operand'"); - InstructionDesc[OpImageQuerySizeLod].operands.push(OperandId, "'Image'"); - InstructionDesc[OpImageQuerySizeLod].operands.push(OperandId, "'Level of Detail'"); + InstructionDesc[OpAny].operands.push(OperandId, "'Vector'"); - InstructionDesc[OpImageQuerySize].operands.push(OperandId, "'Image'"); + InstructionDesc[OpAll].operands.push(OperandId, "'Vector'"); - InstructionDesc[OpImageQueryLod].operands.push(OperandId, "'Image'"); - InstructionDesc[OpImageQueryLod].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpConvertFToU].operands.push(OperandId, "'Float Value'"); - InstructionDesc[OpImageQueryLevels].operands.push(OperandId, "'Image'"); + InstructionDesc[OpConvertFToS].operands.push(OperandId, "'Float Value'"); - InstructionDesc[OpImageQuerySamples].operands.push(OperandId, "'Image'"); + InstructionDesc[OpConvertSToF].operands.push(OperandId, "'Signed Value'"); - InstructionDesc[OpImageQueryFormat].operands.push(OperandId, "'Image'"); + InstructionDesc[OpConvertUToF].operands.push(OperandId, "'Unsigned Value'"); - InstructionDesc[OpImageQueryOrder].operands.push(OperandId, "'Image'"); + InstructionDesc[OpUConvert].operands.push(OperandId, "'Unsigned Value'"); - InstructionDesc[OpAccessChain].operands.push(OperandId, "'Base'"); - InstructionDesc[OpAccessChain].operands.push(OperandVariableIds, "'Indexes'"); + InstructionDesc[OpSConvert].operands.push(OperandId, "'Signed Value'"); - InstructionDesc[OpInBoundsAccessChain].operands.push(OperandId, "'Base'"); - InstructionDesc[OpInBoundsAccessChain].operands.push(OperandVariableIds, "'Indexes'"); + InstructionDesc[OpFConvert].operands.push(OperandId, "'Float Value'"); - InstructionDesc[OpPtrAccessChain].operands.push(OperandId, "'Base'"); - InstructionDesc[OpPtrAccessChain].operands.push(OperandId, "'Element'"); - InstructionDesc[OpPtrAccessChain].operands.push(OperandVariableIds, "'Indexes'"); + InstructionDesc[OpSatConvertSToU].operands.push(OperandId, "'Signed Value'"); - InstructionDesc[OpInBoundsPtrAccessChain].operands.push(OperandId, "'Base'"); - InstructionDesc[OpInBoundsPtrAccessChain].operands.push(OperandId, "'Element'"); - InstructionDesc[OpInBoundsPtrAccessChain].operands.push(OperandVariableIds, "'Indexes'"); + InstructionDesc[OpSatConvertUToS].operands.push(OperandId, "'Unsigned Value'"); - InstructionDesc[OpSNegate].operands.push(OperandId, "'Operand'"); + InstructionDesc[OpConvertPtrToU].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpFNegate].operands.push(OperandId, "'Operand'"); + InstructionDesc[OpConvertUToPtr].operands.push(OperandId, "'Integer Value'"); - InstructionDesc[OpNot].operands.push(OperandId, "'Operand'"); + InstructionDesc[OpPtrCastToGeneric].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAny].operands.push(OperandId, "'Vector'"); + InstructionDesc[OpGenericCastToPtr].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAll].operands.push(OperandId, "'Vector'"); + InstructionDesc[OpGenericCastToPtrExplicit].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpGenericCastToPtrExplicit].operands.push(OperandStorage, "'Storage'"); - InstructionDesc[OpConvertFToU].operands.push(OperandId, "'Float Value'"); + InstructionDesc[OpGenericPtrMemSemantics].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpConvertFToS].operands.push(OperandId, "'Float Value'"); + InstructionDesc[OpBitcast].operands.push(OperandId, "'Operand'"); - InstructionDesc[OpConvertSToF].operands.push(OperandId, "'Signed Value'"); + InstructionDesc[OpQuantizeToF16].operands.push(OperandId, "'Value'"); - InstructionDesc[OpConvertUToF].operands.push(OperandId, "'Unsigned Value'"); + InstructionDesc[OpTranspose].operands.push(OperandId, "'Matrix'"); - InstructionDesc[OpUConvert].operands.push(OperandId, "'Unsigned Value'"); + InstructionDesc[OpCopyLogical].operands.push(OperandId, "'Operand'"); - InstructionDesc[OpSConvert].operands.push(OperandId, "'Signed Value'"); + InstructionDesc[OpIsNan].operands.push(OperandId, "'x'"); - InstructionDesc[OpFConvert].operands.push(OperandId, "'Float Value'"); + InstructionDesc[OpIsInf].operands.push(OperandId, "'x'"); - InstructionDesc[OpSatConvertSToU].operands.push(OperandId, "'Signed Value'"); + InstructionDesc[OpIsFinite].operands.push(OperandId, "'x'"); - InstructionDesc[OpSatConvertUToS].operands.push(OperandId, "'Unsigned Value'"); + InstructionDesc[OpIsNormal].operands.push(OperandId, "'x'"); - InstructionDesc[OpConvertPtrToU].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpSignBitSet].operands.push(OperandId, "'x'"); - InstructionDesc[OpConvertUToPtr].operands.push(OperandId, "'Integer Value'"); + InstructionDesc[OpLessOrGreater].operands.push(OperandId, "'x'"); + InstructionDesc[OpLessOrGreater].operands.push(OperandId, "'y'"); - InstructionDesc[OpPtrCastToGeneric].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpOrdered].operands.push(OperandId, "'x'"); + InstructionDesc[OpOrdered].operands.push(OperandId, "'y'"); - InstructionDesc[OpGenericCastToPtr].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpUnordered].operands.push(OperandId, "'x'"); + InstructionDesc[OpUnordered].operands.push(OperandId, "'y'"); - InstructionDesc[OpGenericCastToPtrExplicit].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpGenericCastToPtrExplicit].operands.push(OperandStorage, "'Storage'"); + InstructionDesc[OpArrayLength].operands.push(OperandId, "'Structure'"); + InstructionDesc[OpArrayLength].operands.push(OperandLiteralNumber, "'Array member'"); - InstructionDesc[OpGenericPtrMemSemantics].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpIAdd].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpIAdd].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpBitcast].operands.push(OperandId, "'Operand'"); + InstructionDesc[OpFAdd].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFAdd].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpQuantizeToF16].operands.push(OperandId, "'Value'"); + InstructionDesc[OpISub].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpISub].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpTranspose].operands.push(OperandId, "'Matrix'"); + InstructionDesc[OpFSub].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFSub].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpCopyLogical].operands.push(OperandId, "'Operand'"); + InstructionDesc[OpIMul].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpIMul].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpIsNan].operands.push(OperandId, "'x'"); + InstructionDesc[OpFMul].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFMul].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpIsInf].operands.push(OperandId, "'x'"); + InstructionDesc[OpUDiv].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpUDiv].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpIsFinite].operands.push(OperandId, "'x'"); + InstructionDesc[OpSDiv].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpSDiv].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpIsNormal].operands.push(OperandId, "'x'"); + InstructionDesc[OpFDiv].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFDiv].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpSignBitSet].operands.push(OperandId, "'x'"); + InstructionDesc[OpUMod].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpUMod].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpLessOrGreater].operands.push(OperandId, "'x'"); - InstructionDesc[OpLessOrGreater].operands.push(OperandId, "'y'"); + InstructionDesc[OpSRem].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpSRem].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpOrdered].operands.push(OperandId, "'x'"); - InstructionDesc[OpOrdered].operands.push(OperandId, "'y'"); + InstructionDesc[OpSMod].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpSMod].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpUnordered].operands.push(OperandId, "'x'"); - InstructionDesc[OpUnordered].operands.push(OperandId, "'y'"); + InstructionDesc[OpFRem].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFRem].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpArrayLength].operands.push(OperandId, "'Structure'"); - InstructionDesc[OpArrayLength].operands.push(OperandLiteralNumber, "'Array member'"); + InstructionDesc[OpFMod].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFMod].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpIAdd].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpIAdd].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpVectorTimesScalar].operands.push(OperandId, "'Vector'"); + InstructionDesc[OpVectorTimesScalar].operands.push(OperandId, "'Scalar'"); - InstructionDesc[OpFAdd].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFAdd].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpMatrixTimesScalar].operands.push(OperandId, "'Matrix'"); + InstructionDesc[OpMatrixTimesScalar].operands.push(OperandId, "'Scalar'"); - InstructionDesc[OpISub].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpISub].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpVectorTimesMatrix].operands.push(OperandId, "'Vector'"); + InstructionDesc[OpVectorTimesMatrix].operands.push(OperandId, "'Matrix'"); - InstructionDesc[OpFSub].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFSub].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpMatrixTimesVector].operands.push(OperandId, "'Matrix'"); + InstructionDesc[OpMatrixTimesVector].operands.push(OperandId, "'Vector'"); - InstructionDesc[OpIMul].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpIMul].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpMatrixTimesMatrix].operands.push(OperandId, "'LeftMatrix'"); + InstructionDesc[OpMatrixTimesMatrix].operands.push(OperandId, "'RightMatrix'"); - InstructionDesc[OpFMul].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFMul].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpOuterProduct].operands.push(OperandId, "'Vector 1'"); + InstructionDesc[OpOuterProduct].operands.push(OperandId, "'Vector 2'"); - InstructionDesc[OpUDiv].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpUDiv].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpDot].operands.push(OperandId, "'Vector 1'"); + InstructionDesc[OpDot].operands.push(OperandId, "'Vector 2'"); - InstructionDesc[OpSDiv].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpSDiv].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpIAddCarry].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpIAddCarry].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpFDiv].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFDiv].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpISubBorrow].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpISubBorrow].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpUMod].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpUMod].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpUMulExtended].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpUMulExtended].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpSRem].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpSRem].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpSMulExtended].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpSMulExtended].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpSMod].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpSMod].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpShiftRightLogical].operands.push(OperandId, "'Base'"); + InstructionDesc[OpShiftRightLogical].operands.push(OperandId, "'Shift'"); - InstructionDesc[OpFRem].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFRem].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpShiftRightArithmetic].operands.push(OperandId, "'Base'"); + InstructionDesc[OpShiftRightArithmetic].operands.push(OperandId, "'Shift'"); - InstructionDesc[OpFMod].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFMod].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpShiftLeftLogical].operands.push(OperandId, "'Base'"); + InstructionDesc[OpShiftLeftLogical].operands.push(OperandId, "'Shift'"); - InstructionDesc[OpVectorTimesScalar].operands.push(OperandId, "'Vector'"); - InstructionDesc[OpVectorTimesScalar].operands.push(OperandId, "'Scalar'"); + InstructionDesc[OpLogicalOr].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpLogicalOr].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpMatrixTimesScalar].operands.push(OperandId, "'Matrix'"); - InstructionDesc[OpMatrixTimesScalar].operands.push(OperandId, "'Scalar'"); + InstructionDesc[OpLogicalAnd].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpLogicalAnd].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpVectorTimesMatrix].operands.push(OperandId, "'Vector'"); - InstructionDesc[OpVectorTimesMatrix].operands.push(OperandId, "'Matrix'"); + InstructionDesc[OpLogicalEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpLogicalEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpMatrixTimesVector].operands.push(OperandId, "'Matrix'"); - InstructionDesc[OpMatrixTimesVector].operands.push(OperandId, "'Vector'"); + InstructionDesc[OpLogicalNotEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpLogicalNotEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpMatrixTimesMatrix].operands.push(OperandId, "'LeftMatrix'"); - InstructionDesc[OpMatrixTimesMatrix].operands.push(OperandId, "'RightMatrix'"); + InstructionDesc[OpLogicalNot].operands.push(OperandId, "'Operand'"); - InstructionDesc[OpOuterProduct].operands.push(OperandId, "'Vector 1'"); - InstructionDesc[OpOuterProduct].operands.push(OperandId, "'Vector 2'"); + InstructionDesc[OpBitwiseOr].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpBitwiseOr].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpDot].operands.push(OperandId, "'Vector 1'"); - InstructionDesc[OpDot].operands.push(OperandId, "'Vector 2'"); + InstructionDesc[OpBitwiseXor].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpBitwiseXor].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpIAddCarry].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpIAddCarry].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpBitwiseAnd].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpBitwiseAnd].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpISubBorrow].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpISubBorrow].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpBitFieldInsert].operands.push(OperandId, "'Base'"); + InstructionDesc[OpBitFieldInsert].operands.push(OperandId, "'Insert'"); + InstructionDesc[OpBitFieldInsert].operands.push(OperandId, "'Offset'"); + InstructionDesc[OpBitFieldInsert].operands.push(OperandId, "'Count'"); - InstructionDesc[OpUMulExtended].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpUMulExtended].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpBitFieldSExtract].operands.push(OperandId, "'Base'"); + InstructionDesc[OpBitFieldSExtract].operands.push(OperandId, "'Offset'"); + InstructionDesc[OpBitFieldSExtract].operands.push(OperandId, "'Count'"); - InstructionDesc[OpSMulExtended].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpSMulExtended].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpBitFieldUExtract].operands.push(OperandId, "'Base'"); + InstructionDesc[OpBitFieldUExtract].operands.push(OperandId, "'Offset'"); + InstructionDesc[OpBitFieldUExtract].operands.push(OperandId, "'Count'"); - InstructionDesc[OpShiftRightLogical].operands.push(OperandId, "'Base'"); - InstructionDesc[OpShiftRightLogical].operands.push(OperandId, "'Shift'"); + InstructionDesc[OpBitReverse].operands.push(OperandId, "'Base'"); - InstructionDesc[OpShiftRightArithmetic].operands.push(OperandId, "'Base'"); - InstructionDesc[OpShiftRightArithmetic].operands.push(OperandId, "'Shift'"); + InstructionDesc[OpBitCount].operands.push(OperandId, "'Base'"); - InstructionDesc[OpShiftLeftLogical].operands.push(OperandId, "'Base'"); - InstructionDesc[OpShiftLeftLogical].operands.push(OperandId, "'Shift'"); + InstructionDesc[OpSelect].operands.push(OperandId, "'Condition'"); + InstructionDesc[OpSelect].operands.push(OperandId, "'Object 1'"); + InstructionDesc[OpSelect].operands.push(OperandId, "'Object 2'"); - InstructionDesc[OpLogicalOr].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpLogicalOr].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpIEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpIEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpLogicalAnd].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpLogicalAnd].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpFOrdEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFOrdEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpLogicalEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpLogicalEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpFUnordEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFUnordEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpLogicalNotEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpLogicalNotEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpINotEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpINotEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpLogicalNot].operands.push(OperandId, "'Operand'"); + InstructionDesc[OpFOrdNotEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFOrdNotEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpBitwiseOr].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpBitwiseOr].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpFUnordNotEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFUnordNotEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpBitwiseXor].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpBitwiseXor].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpULessThan].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpULessThan].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpBitwiseAnd].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpBitwiseAnd].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpSLessThan].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpSLessThan].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpBitFieldInsert].operands.push(OperandId, "'Base'"); - InstructionDesc[OpBitFieldInsert].operands.push(OperandId, "'Insert'"); - InstructionDesc[OpBitFieldInsert].operands.push(OperandId, "'Offset'"); - InstructionDesc[OpBitFieldInsert].operands.push(OperandId, "'Count'"); + InstructionDesc[OpFOrdLessThan].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFOrdLessThan].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpBitFieldSExtract].operands.push(OperandId, "'Base'"); - InstructionDesc[OpBitFieldSExtract].operands.push(OperandId, "'Offset'"); - InstructionDesc[OpBitFieldSExtract].operands.push(OperandId, "'Count'"); - - InstructionDesc[OpBitFieldUExtract].operands.push(OperandId, "'Base'"); - InstructionDesc[OpBitFieldUExtract].operands.push(OperandId, "'Offset'"); - InstructionDesc[OpBitFieldUExtract].operands.push(OperandId, "'Count'"); - - InstructionDesc[OpBitReverse].operands.push(OperandId, "'Base'"); + InstructionDesc[OpFUnordLessThan].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFUnordLessThan].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpBitCount].operands.push(OperandId, "'Base'"); + InstructionDesc[OpUGreaterThan].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpUGreaterThan].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpSelect].operands.push(OperandId, "'Condition'"); - InstructionDesc[OpSelect].operands.push(OperandId, "'Object 1'"); - InstructionDesc[OpSelect].operands.push(OperandId, "'Object 2'"); + InstructionDesc[OpSGreaterThan].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpSGreaterThan].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpIEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpIEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpFOrdGreaterThan].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFOrdGreaterThan].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpFOrdEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFOrdEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpFUnordGreaterThan].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFUnordGreaterThan].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpFUnordEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFUnordEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpULessThanEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpULessThanEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpINotEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpINotEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpSLessThanEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpSLessThanEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpFOrdNotEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFOrdNotEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpFOrdLessThanEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFOrdLessThanEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpFUnordNotEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFUnordNotEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpFUnordLessThanEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFUnordLessThanEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpULessThan].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpULessThan].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpUGreaterThanEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpUGreaterThanEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpSLessThan].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpSLessThan].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpSGreaterThanEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpSGreaterThanEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpFOrdLessThan].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFOrdLessThan].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpFOrdGreaterThanEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFOrdGreaterThanEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpFUnordLessThan].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFUnordLessThan].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpFUnordGreaterThanEqual].operands.push(OperandId, "'Operand 1'"); + InstructionDesc[OpFUnordGreaterThanEqual].operands.push(OperandId, "'Operand 2'"); - InstructionDesc[OpUGreaterThan].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpUGreaterThan].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpDPdx].operands.push(OperandId, "'P'"); - InstructionDesc[OpSGreaterThan].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpSGreaterThan].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpDPdy].operands.push(OperandId, "'P'"); - InstructionDesc[OpFOrdGreaterThan].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFOrdGreaterThan].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpFwidth].operands.push(OperandId, "'P'"); - InstructionDesc[OpFUnordGreaterThan].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFUnordGreaterThan].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpDPdxFine].operands.push(OperandId, "'P'"); - InstructionDesc[OpULessThanEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpULessThanEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpDPdyFine].operands.push(OperandId, "'P'"); - InstructionDesc[OpSLessThanEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpSLessThanEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpFwidthFine].operands.push(OperandId, "'P'"); - InstructionDesc[OpFOrdLessThanEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFOrdLessThanEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpDPdxCoarse].operands.push(OperandId, "'P'"); - InstructionDesc[OpFUnordLessThanEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFUnordLessThanEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpDPdyCoarse].operands.push(OperandId, "'P'"); - InstructionDesc[OpUGreaterThanEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpUGreaterThanEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpFwidthCoarse].operands.push(OperandId, "'P'"); - InstructionDesc[OpSGreaterThanEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpSGreaterThanEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpEmitStreamVertex].operands.push(OperandId, "'Stream'"); - InstructionDesc[OpFOrdGreaterThanEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFOrdGreaterThanEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpEndStreamPrimitive].operands.push(OperandId, "'Stream'"); - InstructionDesc[OpFUnordGreaterThanEqual].operands.push(OperandId, "'Operand 1'"); - InstructionDesc[OpFUnordGreaterThanEqual].operands.push(OperandId, "'Operand 2'"); + InstructionDesc[OpControlBarrier].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpControlBarrier].operands.push(OperandScope, "'Memory'"); + InstructionDesc[OpControlBarrier].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpDPdx].operands.push(OperandId, "'P'"); + InstructionDesc[OpMemoryBarrier].operands.push(OperandScope, "'Memory'"); + InstructionDesc[OpMemoryBarrier].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpDPdy].operands.push(OperandId, "'P'"); + InstructionDesc[OpImageTexelPointer].operands.push(OperandId, "'Image'"); + InstructionDesc[OpImageTexelPointer].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageTexelPointer].operands.push(OperandId, "'Sample'"); - InstructionDesc[OpFwidth].operands.push(OperandId, "'P'"); + InstructionDesc[OpAtomicLoad].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicLoad].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicLoad].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpDPdxFine].operands.push(OperandId, "'P'"); + InstructionDesc[OpAtomicStore].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicStore].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicStore].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicStore].operands.push(OperandId, "'Value'"); - InstructionDesc[OpDPdyFine].operands.push(OperandId, "'P'"); + InstructionDesc[OpAtomicExchange].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicExchange].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicExchange].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicExchange].operands.push(OperandId, "'Value'"); - InstructionDesc[OpFwidthFine].operands.push(OperandId, "'P'"); + InstructionDesc[OpAtomicCompareExchange].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicCompareExchange].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicCompareExchange].operands.push(OperandMemorySemantics, "'Equal'"); + InstructionDesc[OpAtomicCompareExchange].operands.push(OperandMemorySemantics, "'Unequal'"); + InstructionDesc[OpAtomicCompareExchange].operands.push(OperandId, "'Value'"); + InstructionDesc[OpAtomicCompareExchange].operands.push(OperandId, "'Comparator'"); - InstructionDesc[OpDPdxCoarse].operands.push(OperandId, "'P'"); + InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandMemorySemantics, "'Equal'"); + InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandMemorySemantics, "'Unequal'"); + InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandId, "'Value'"); + InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandId, "'Comparator'"); - InstructionDesc[OpDPdyCoarse].operands.push(OperandId, "'P'"); + InstructionDesc[OpAtomicIIncrement].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicIIncrement].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicIIncrement].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpFwidthCoarse].operands.push(OperandId, "'P'"); + InstructionDesc[OpAtomicIDecrement].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicIDecrement].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicIDecrement].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpEmitStreamVertex].operands.push(OperandId, "'Stream'"); + InstructionDesc[OpAtomicIAdd].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicIAdd].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicIAdd].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicIAdd].operands.push(OperandId, "'Value'"); - InstructionDesc[OpEndStreamPrimitive].operands.push(OperandId, "'Stream'"); + InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicFAddEXT].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicFAddEXT].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Value'"); - InstructionDesc[OpControlBarrier].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpControlBarrier].operands.push(OperandScope, "'Memory'"); - InstructionDesc[OpControlBarrier].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicISub].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicISub].operands.push(OperandId, "'Value'"); - InstructionDesc[OpMemoryBarrier].operands.push(OperandScope, "'Memory'"); - InstructionDesc[OpMemoryBarrier].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicUMin].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicUMin].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicUMin].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicUMin].operands.push(OperandId, "'Value'"); - InstructionDesc[OpImageTexelPointer].operands.push(OperandId, "'Image'"); - InstructionDesc[OpImageTexelPointer].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageTexelPointer].operands.push(OperandId, "'Sample'"); + InstructionDesc[OpAtomicUMax].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicUMax].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicUMax].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicUMax].operands.push(OperandId, "'Value'"); - InstructionDesc[OpAtomicLoad].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicLoad].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicLoad].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicSMin].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicSMin].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicSMin].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicSMin].operands.push(OperandId, "'Value'"); - InstructionDesc[OpAtomicStore].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicStore].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicStore].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicStore].operands.push(OperandId, "'Value'"); + InstructionDesc[OpAtomicSMax].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicSMax].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicSMax].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicSMax].operands.push(OperandId, "'Value'"); - InstructionDesc[OpAtomicExchange].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicExchange].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicExchange].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicExchange].operands.push(OperandId, "'Value'"); + InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicFMinEXT].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicFMinEXT].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Value'"); - InstructionDesc[OpAtomicCompareExchange].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicCompareExchange].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicCompareExchange].operands.push(OperandMemorySemantics, "'Equal'"); - InstructionDesc[OpAtomicCompareExchange].operands.push(OperandMemorySemantics, "'Unequal'"); - InstructionDesc[OpAtomicCompareExchange].operands.push(OperandId, "'Value'"); - InstructionDesc[OpAtomicCompareExchange].operands.push(OperandId, "'Comparator'"); + InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Value'"); - InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandMemorySemantics, "'Equal'"); - InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandMemorySemantics, "'Unequal'"); - InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandId, "'Value'"); - InstructionDesc[OpAtomicCompareExchangeWeak].operands.push(OperandId, "'Comparator'"); + InstructionDesc[OpAtomicAnd].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicAnd].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicAnd].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicAnd].operands.push(OperandId, "'Value'"); + + InstructionDesc[OpAtomicOr].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicOr].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicOr].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicOr].operands.push(OperandId, "'Value'"); + + InstructionDesc[OpAtomicXor].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicXor].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicXor].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpAtomicXor].operands.push(OperandId, "'Value'"); + + InstructionDesc[OpAtomicFlagTestAndSet].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicFlagTestAndSet].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicFlagTestAndSet].operands.push(OperandMemorySemantics, "'Semantics'"); + + InstructionDesc[OpAtomicFlagClear].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpAtomicFlagClear].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpAtomicFlagClear].operands.push(OperandMemorySemantics, "'Semantics'"); + + InstructionDesc[OpLoopMerge].operands.push(OperandId, "'Merge Block'"); + InstructionDesc[OpLoopMerge].operands.push(OperandId, "'Continue Target'"); + InstructionDesc[OpLoopMerge].operands.push(OperandLoop, ""); + InstructionDesc[OpLoopMerge].operands.push(OperandOptionalLiteral, ""); + + InstructionDesc[OpSelectionMerge].operands.push(OperandId, "'Merge Block'"); + InstructionDesc[OpSelectionMerge].operands.push(OperandSelect, ""); + + InstructionDesc[OpBranch].operands.push(OperandId, "'Target Label'"); + + InstructionDesc[OpBranchConditional].operands.push(OperandId, "'Condition'"); + InstructionDesc[OpBranchConditional].operands.push(OperandId, "'True Label'"); + InstructionDesc[OpBranchConditional].operands.push(OperandId, "'False Label'"); + InstructionDesc[OpBranchConditional].operands.push(OperandVariableLiterals, "'Branch weights'"); + + InstructionDesc[OpSwitch].operands.push(OperandId, "'Selector'"); + InstructionDesc[OpSwitch].operands.push(OperandId, "'Default'"); + InstructionDesc[OpSwitch].operands.push(OperandVariableLiteralId, "'Target'"); + + + InstructionDesc[OpReturnValue].operands.push(OperandId, "'Value'"); + + InstructionDesc[OpLifetimeStart].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpLifetimeStart].operands.push(OperandLiteralNumber, "'Size'"); + + InstructionDesc[OpLifetimeStop].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpLifetimeStop].operands.push(OperandLiteralNumber, "'Size'"); + + InstructionDesc[OpGroupAsyncCopy].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Destination'"); + InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Source'"); + InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Num Elements'"); + InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Stride'"); + InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Event'"); + + InstructionDesc[OpGroupWaitEvents].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupWaitEvents].operands.push(OperandId, "'Num Events'"); + InstructionDesc[OpGroupWaitEvents].operands.push(OperandId, "'Events List'"); + + InstructionDesc[OpGroupAll].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupAll].operands.push(OperandId, "'Predicate'"); + + InstructionDesc[OpGroupAny].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupAny].operands.push(OperandId, "'Predicate'"); + + InstructionDesc[OpGroupBroadcast].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupBroadcast].operands.push(OperandId, "'Value'"); + InstructionDesc[OpGroupBroadcast].operands.push(OperandId, "'LocalId'"); + + InstructionDesc[OpGroupIAdd].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupIAdd].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupIAdd].operands.push(OperandId, "'X'"); + + InstructionDesc[OpGroupFAdd].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupFAdd].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupFAdd].operands.push(OperandId, "'X'"); + + InstructionDesc[OpGroupUMin].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupUMin].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupUMin].operands.push(OperandId, "'X'"); + + InstructionDesc[OpGroupSMin].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupSMin].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupSMin].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupFMin].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupFMin].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupFMin].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupUMax].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupUMax].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupUMax].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupSMax].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupSMax].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupSMax].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupFMax].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupFMax].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupFMax].operands.push(OperandId, "X"); + + InstructionDesc[OpReadPipe].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpReadPipe].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpReadPipe].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpReadPipe].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpWritePipe].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpWritePipe].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpWritePipe].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpWritePipe].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Reserve Id'"); + InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Index'"); + InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Reserve Id'"); + InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Index'"); + InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Num Packets'"); + InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Num Packets'"); + InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Reserve Id'"); + InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Reserve Id'"); + InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpIsValidReserveId].operands.push(OperandId, "'Reserve Id'"); + + InstructionDesc[OpGetNumPipePackets].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpGetNumPipePackets].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpGetNumPipePackets].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpGetMaxPipePackets].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpGetMaxPipePackets].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpGetMaxPipePackets].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Num Packets'"); + InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Num Packets'"); + InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Reserve Id'"); + InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Pipe'"); + InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Reserve Id'"); + InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Packet Size'"); + InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Packet Alignment'"); + + InstructionDesc[OpBuildNDRange].operands.push(OperandId, "'GlobalWorkSize'"); + InstructionDesc[OpBuildNDRange].operands.push(OperandId, "'LocalWorkSize'"); + InstructionDesc[OpBuildNDRange].operands.push(OperandId, "'GlobalWorkOffset'"); + + InstructionDesc[OpCaptureEventProfilingInfo].operands.push(OperandId, "'Event'"); + InstructionDesc[OpCaptureEventProfilingInfo].operands.push(OperandId, "'Profiling Info'"); + InstructionDesc[OpCaptureEventProfilingInfo].operands.push(OperandId, "'Value'"); + + InstructionDesc[OpSetUserEventStatus].operands.push(OperandId, "'Event'"); + InstructionDesc[OpSetUserEventStatus].operands.push(OperandId, "'Status'"); + + InstructionDesc[OpIsValidEvent].operands.push(OperandId, "'Event'"); + + InstructionDesc[OpRetainEvent].operands.push(OperandId, "'Event'"); + + InstructionDesc[OpReleaseEvent].operands.push(OperandId, "'Event'"); + + InstructionDesc[OpGetKernelWorkGroupSize].operands.push(OperandId, "'Invoke'"); + InstructionDesc[OpGetKernelWorkGroupSize].operands.push(OperandId, "'Param'"); + InstructionDesc[OpGetKernelWorkGroupSize].operands.push(OperandId, "'Param Size'"); + InstructionDesc[OpGetKernelWorkGroupSize].operands.push(OperandId, "'Param Align'"); + + InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].operands.push(OperandId, "'Invoke'"); + InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].operands.push(OperandId, "'Param'"); + InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].operands.push(OperandId, "'Param Size'"); + InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].operands.push(OperandId, "'Param Align'"); + + InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'ND Range'"); + InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'Invoke'"); + InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'Param'"); + InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'Param Size'"); + InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'Param Align'"); + + InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'ND Range'"); + InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'Invoke'"); + InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'Param'"); + InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'Param Size'"); + InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'Param Align'"); + + InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Queue'"); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Flags'"); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'ND Range'"); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Num Events'"); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Wait Events'"); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Ret Event'"); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Invoke'"); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Param'"); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Param Size'"); + InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Param Align'"); + InstructionDesc[OpEnqueueKernel].operands.push(OperandVariableIds, "'Local Size'"); + + InstructionDesc[OpEnqueueMarker].operands.push(OperandId, "'Queue'"); + InstructionDesc[OpEnqueueMarker].operands.push(OperandId, "'Num Events'"); + InstructionDesc[OpEnqueueMarker].operands.push(OperandId, "'Wait Events'"); + InstructionDesc[OpEnqueueMarker].operands.push(OperandId, "'Ret Event'"); + + InstructionDesc[OpGroupNonUniformElect].operands.push(OperandScope, "'Execution'"); + + InstructionDesc[OpGroupNonUniformAll].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformAll].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupNonUniformAny].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformAny].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupNonUniformAllEqual].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformAllEqual].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupNonUniformBroadcast].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformBroadcast].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformBroadcast].operands.push(OperandId, "ID"); + + InstructionDesc[OpGroupNonUniformBroadcastFirst].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformBroadcastFirst].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupNonUniformBallot].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformBallot].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupNonUniformInverseBallot].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformInverseBallot].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupNonUniformBallotBitExtract].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformBallotBitExtract].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformBallotBitExtract].operands.push(OperandId, "Bit"); + + InstructionDesc[OpGroupNonUniformBallotBitCount].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformBallotBitCount].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformBallotBitCount].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupNonUniformBallotFindLSB].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformBallotFindLSB].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupNonUniformBallotFindMSB].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformBallotFindMSB].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupNonUniformShuffle].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformShuffle].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformShuffle].operands.push(OperandId, "'Id'"); + + InstructionDesc[OpGroupNonUniformShuffleXor].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformShuffleXor].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformShuffleXor].operands.push(OperandId, "Mask"); + + InstructionDesc[OpGroupNonUniformShuffleUp].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformShuffleUp].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformShuffleUp].operands.push(OperandId, "Offset"); + + InstructionDesc[OpGroupNonUniformShuffleDown].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformShuffleDown].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformShuffleDown].operands.push(OperandId, "Offset"); + + InstructionDesc[OpGroupNonUniformIAdd].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformIAdd].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformIAdd].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformIAdd].operands.push(OperandId, "'ClusterSize'", true); + + InstructionDesc[OpGroupNonUniformFAdd].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformFAdd].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformFAdd].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformFAdd].operands.push(OperandId, "'ClusterSize'", true); + + InstructionDesc[OpGroupNonUniformIMul].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformIMul].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformIMul].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformIMul].operands.push(OperandId, "'ClusterSize'", true); + + InstructionDesc[OpGroupNonUniformFMul].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformFMul].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformFMul].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformFMul].operands.push(OperandId, "'ClusterSize'", true); + + InstructionDesc[OpGroupNonUniformSMin].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformSMin].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformSMin].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformSMin].operands.push(OperandId, "'ClusterSize'", true); + + InstructionDesc[OpGroupNonUniformUMin].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformUMin].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformUMin].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformUMin].operands.push(OperandId, "'ClusterSize'", true); + + InstructionDesc[OpGroupNonUniformFMin].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformFMin].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformFMin].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformFMin].operands.push(OperandId, "'ClusterSize'", true); - InstructionDesc[OpAtomicIIncrement].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicIIncrement].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicIIncrement].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpGroupNonUniformSMax].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformSMax].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformSMax].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformSMax].operands.push(OperandId, "'ClusterSize'", true); - InstructionDesc[OpAtomicIDecrement].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicIDecrement].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicIDecrement].operands.push(OperandMemorySemantics, "'Semantics'"); + InstructionDesc[OpGroupNonUniformUMax].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformUMax].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformUMax].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformUMax].operands.push(OperandId, "'ClusterSize'", true); - InstructionDesc[OpAtomicIAdd].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicIAdd].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicIAdd].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicIAdd].operands.push(OperandId, "'Value'"); + InstructionDesc[OpGroupNonUniformFMax].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformFMax].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformFMax].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformFMax].operands.push(OperandId, "'ClusterSize'", true); - InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicFAddEXT].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicFAddEXT].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicFAddEXT].operands.push(OperandId, "'Value'"); + InstructionDesc[OpGroupNonUniformBitwiseAnd].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformBitwiseAnd].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformBitwiseAnd].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformBitwiseAnd].operands.push(OperandId, "'ClusterSize'", true); - InstructionDesc[OpAtomicISub].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicISub].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicISub].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicISub].operands.push(OperandId, "'Value'"); + InstructionDesc[OpGroupNonUniformBitwiseOr].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformBitwiseOr].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformBitwiseOr].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformBitwiseOr].operands.push(OperandId, "'ClusterSize'", true); + + InstructionDesc[OpGroupNonUniformBitwiseXor].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformBitwiseXor].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformBitwiseXor].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformBitwiseXor].operands.push(OperandId, "'ClusterSize'", true); + + InstructionDesc[OpGroupNonUniformLogicalAnd].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformLogicalAnd].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformLogicalAnd].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformLogicalAnd].operands.push(OperandId, "'ClusterSize'", true); + + InstructionDesc[OpGroupNonUniformLogicalOr].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformLogicalOr].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformLogicalOr].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformLogicalOr].operands.push(OperandId, "'ClusterSize'", true); + + InstructionDesc[OpGroupNonUniformLogicalXor].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformLogicalXor].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupNonUniformLogicalXor].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformLogicalXor].operands.push(OperandId, "'ClusterSize'", true); + + InstructionDesc[OpGroupNonUniformQuadBroadcast].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformQuadBroadcast].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformQuadBroadcast].operands.push(OperandId, "'Id'"); + + InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "X"); + InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "'Direction'"); + + InstructionDesc[OpSubgroupBallotKHR].operands.push(OperandId, "'Predicate'"); + + InstructionDesc[OpSubgroupFirstInvocationKHR].operands.push(OperandId, "'Value'"); + + InstructionDesc[OpSubgroupAnyKHR].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpSubgroupAnyKHR].operands.push(OperandId, "'Predicate'"); + + InstructionDesc[OpSubgroupAllKHR].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpSubgroupAllKHR].operands.push(OperandId, "'Predicate'"); + + InstructionDesc[OpSubgroupAllEqualKHR].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpSubgroupAllEqualKHR].operands.push(OperandId, "'Predicate'"); + + InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Value'"); + InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Index'"); + + InstructionDesc[OpModuleProcessed].operands.push(OperandLiteralString, "'process'"); + + InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandId, "'X'"); + + InstructionDesc[OpGroupFAddNonUniformAMD].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupFAddNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupFAddNonUniformAMD].operands.push(OperandId, "'X'"); + + InstructionDesc[OpGroupUMinNonUniformAMD].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupUMinNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupUMinNonUniformAMD].operands.push(OperandId, "'X'"); + + InstructionDesc[OpGroupSMinNonUniformAMD].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupSMinNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupSMinNonUniformAMD].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupFMinNonUniformAMD].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupFMinNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupFMinNonUniformAMD].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupUMaxNonUniformAMD].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupUMaxNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupUMaxNonUniformAMD].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupSMaxNonUniformAMD].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupSMaxNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupSMaxNonUniformAMD].operands.push(OperandId, "X"); + + InstructionDesc[OpGroupFMaxNonUniformAMD].operands.push(OperandScope, "'Execution'"); + InstructionDesc[OpGroupFMaxNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); + InstructionDesc[OpGroupFMaxNonUniformAMD].operands.push(OperandId, "X"); + + InstructionDesc[OpFragmentMaskFetchAMD].operands.push(OperandId, "'Image'"); + InstructionDesc[OpFragmentMaskFetchAMD].operands.push(OperandId, "'Coordinate'"); + + InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Image'"); + InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Fragment Index'"); + + InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X"); + + InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false); + + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Acceleration Structure'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Flags'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Cull Mask'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Offset'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Stride'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Miss Index'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Origin'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Direction'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'"); + InstructionDesc[OpTraceNV].setResultAndType(false, false); + + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Acceleration Structure'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Flags'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Cull Mask'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Offset'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Stride'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Miss Index'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Origin'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Direction'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Time'"); + InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Payload'"); + InstructionDesc[OpTraceRayMotionNV].setResultAndType(false, false); + + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Acceleration Structure'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Offset'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Stride'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Miss Index'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Origin'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Direction'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Payload'"); + InstructionDesc[OpTraceRayKHR].setResultAndType(false, false); + + InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Parameter'"); + InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Kind'"); + + InstructionDesc[OpIgnoreIntersectionNV].setResultAndType(false, false); + + InstructionDesc[OpIgnoreIntersectionKHR].setResultAndType(false, false); + + InstructionDesc[OpTerminateRayNV].setResultAndType(false, false); + + InstructionDesc[OpTerminateRayKHR].setResultAndType(false, false); + + InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "SBT Record Index"); + InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "CallableData ID"); + InstructionDesc[OpExecuteCallableNV].setResultAndType(false, false); + + InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "SBT Record Index"); + InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "CallableData"); + InstructionDesc[OpExecuteCallableKHR].setResultAndType(false, false); + + InstructionDesc[OpConvertUToAccelerationStructureKHR].operands.push(OperandId, "Value"); + InstructionDesc[OpConvertUToAccelerationStructureKHR].setResultAndType(true, true); + + // Ray Query + InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false); + InstructionDesc[OpTypeRayQueryKHR].setResultAndType(true, false); + + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'AccelerationS'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayFlags'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'CullMask'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Origin'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmin'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Direction'"); + InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmax'"); + InstructionDesc[OpRayQueryInitializeKHR].setResultAndType(false, false); + + InstructionDesc[OpRayQueryTerminateKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryTerminateKHR].setResultAndType(false, false); + + InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'THit'"); + InstructionDesc[OpRayQueryGenerateIntersectionKHR].setResultAndType(false, false); + + InstructionDesc[OpRayQueryConfirmIntersectionKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryConfirmIntersectionKHR].setResultAndType(false, false); + + InstructionDesc[OpRayQueryProceedKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryProceedKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionTypeKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetRayTMinKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetRayTMinKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetRayFlagsKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetRayFlagsKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionTKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].setResultAndType(true, true); - InstructionDesc[OpAtomicUMin].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicUMin].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicUMin].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicUMin].operands.push(OperandId, "'Value'"); + InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].setResultAndType(true, true); - InstructionDesc[OpAtomicUMax].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicUMax].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicUMax].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicUMax].operands.push(OperandId, "'Value'"); + InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].setResultAndType(true, true); - InstructionDesc[OpAtomicSMin].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicSMin].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicSMin].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicSMin].operands.push(OperandId, "'Value'"); + InstructionDesc[OpRayQueryGetWorldRayOriginKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetWorldRayOriginKHR].setResultAndType(true, true); - InstructionDesc[OpAtomicSMax].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicSMax].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicSMax].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicSMax].operands.push(OperandId, "'Value'"); + InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].setResultAndType(true, true); + + InstructionDesc[OpRayQueryGetIntersectionTriangleVertexPositionsKHR].operands.push(OperandId, "'RayQuery'"); + InstructionDesc[OpRayQueryGetIntersectionTriangleVertexPositionsKHR].operands.push(OperandId, "'Committed'"); + InstructionDesc[OpRayQueryGetIntersectionTriangleVertexPositionsKHR].setResultAndType(true, true); + + InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Sampled Image'"); + InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'"); + InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Granularity'"); + InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coarse'"); + InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandVariableIds, "", true); + + InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Index Offset'"); + InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Packed Indices'"); - InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicFMinEXT].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicFMinEXT].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicFMinEXT].operands.push(OperandId, "'Value'"); + InstructionDesc[OpEmitMeshTasksEXT].operands.push(OperandId, "'groupCountX'"); + InstructionDesc[OpEmitMeshTasksEXT].operands.push(OperandId, "'groupCountY'"); + InstructionDesc[OpEmitMeshTasksEXT].operands.push(OperandId, "'groupCountZ'"); + InstructionDesc[OpEmitMeshTasksEXT].operands.push(OperandId, "'Payload'"); + InstructionDesc[OpEmitMeshTasksEXT].setResultAndType(false, false); - InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicFMaxEXT].operands.push(OperandId, "'Value'"); + InstructionDesc[OpSetMeshOutputsEXT].operands.push(OperandId, "'vertexCount'"); + InstructionDesc[OpSetMeshOutputsEXT].operands.push(OperandId, "'primitiveCount'"); + InstructionDesc[OpSetMeshOutputsEXT].setResultAndType(false, false); - InstructionDesc[OpAtomicAnd].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicAnd].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicAnd].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicAnd].operands.push(OperandId, "'Value'"); - - InstructionDesc[OpAtomicOr].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicOr].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicOr].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicOr].operands.push(OperandId, "'Value'"); - - InstructionDesc[OpAtomicXor].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicXor].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicXor].operands.push(OperandMemorySemantics, "'Semantics'"); - InstructionDesc[OpAtomicXor].operands.push(OperandId, "'Value'"); - - InstructionDesc[OpAtomicFlagTestAndSet].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicFlagTestAndSet].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicFlagTestAndSet].operands.push(OperandMemorySemantics, "'Semantics'"); - - InstructionDesc[OpAtomicFlagClear].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpAtomicFlagClear].operands.push(OperandScope, "'Scope'"); - InstructionDesc[OpAtomicFlagClear].operands.push(OperandMemorySemantics, "'Semantics'"); - - InstructionDesc[OpLoopMerge].operands.push(OperandId, "'Merge Block'"); - InstructionDesc[OpLoopMerge].operands.push(OperandId, "'Continue Target'"); - InstructionDesc[OpLoopMerge].operands.push(OperandLoop, ""); - InstructionDesc[OpLoopMerge].operands.push(OperandOptionalLiteral, ""); - - InstructionDesc[OpSelectionMerge].operands.push(OperandId, "'Merge Block'"); - InstructionDesc[OpSelectionMerge].operands.push(OperandSelect, ""); - - InstructionDesc[OpBranch].operands.push(OperandId, "'Target Label'"); - - InstructionDesc[OpBranchConditional].operands.push(OperandId, "'Condition'"); - InstructionDesc[OpBranchConditional].operands.push(OperandId, "'True Label'"); - InstructionDesc[OpBranchConditional].operands.push(OperandId, "'False Label'"); - InstructionDesc[OpBranchConditional].operands.push(OperandVariableLiterals, "'Branch weights'"); - - InstructionDesc[OpSwitch].operands.push(OperandId, "'Selector'"); - InstructionDesc[OpSwitch].operands.push(OperandId, "'Default'"); - InstructionDesc[OpSwitch].operands.push(OperandVariableLiteralId, "'Target'"); - - - InstructionDesc[OpReturnValue].operands.push(OperandId, "'Value'"); - - InstructionDesc[OpLifetimeStart].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpLifetimeStart].operands.push(OperandLiteralNumber, "'Size'"); - - InstructionDesc[OpLifetimeStop].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpLifetimeStop].operands.push(OperandLiteralNumber, "'Size'"); - - InstructionDesc[OpGroupAsyncCopy].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Destination'"); - InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Source'"); - InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Num Elements'"); - InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Stride'"); - InstructionDesc[OpGroupAsyncCopy].operands.push(OperandId, "'Event'"); - - InstructionDesc[OpGroupWaitEvents].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupWaitEvents].operands.push(OperandId, "'Num Events'"); - InstructionDesc[OpGroupWaitEvents].operands.push(OperandId, "'Events List'"); - - InstructionDesc[OpGroupAll].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupAll].operands.push(OperandId, "'Predicate'"); - - InstructionDesc[OpGroupAny].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupAny].operands.push(OperandId, "'Predicate'"); - - InstructionDesc[OpGroupBroadcast].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupBroadcast].operands.push(OperandId, "'Value'"); - InstructionDesc[OpGroupBroadcast].operands.push(OperandId, "'LocalId'"); - - InstructionDesc[OpGroupIAdd].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupIAdd].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupIAdd].operands.push(OperandId, "'X'"); - - InstructionDesc[OpGroupFAdd].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupFAdd].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupFAdd].operands.push(OperandId, "'X'"); - - InstructionDesc[OpGroupUMin].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupUMin].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupUMin].operands.push(OperandId, "'X'"); - - InstructionDesc[OpGroupSMin].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupSMin].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupSMin].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupFMin].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupFMin].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupFMin].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupUMax].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupUMax].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupUMax].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupSMax].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupSMax].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupSMax].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupFMax].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupFMax].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupFMax].operands.push(OperandId, "X"); - - InstructionDesc[OpReadPipe].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpReadPipe].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpReadPipe].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpReadPipe].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpWritePipe].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpWritePipe].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpWritePipe].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpWritePipe].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Reserve Id'"); - InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Index'"); - InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpReservedReadPipe].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Reserve Id'"); - InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Index'"); - InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpReservedWritePipe].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Num Packets'"); - InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpReserveReadPipePackets].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Num Packets'"); - InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpReserveWritePipePackets].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Reserve Id'"); - InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpCommitReadPipe].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Reserve Id'"); - InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpCommitWritePipe].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpIsValidReserveId].operands.push(OperandId, "'Reserve Id'"); - - InstructionDesc[OpGetNumPipePackets].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpGetNumPipePackets].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpGetNumPipePackets].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpGetMaxPipePackets].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpGetMaxPipePackets].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpGetMaxPipePackets].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Num Packets'"); - InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpGroupReserveReadPipePackets].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Num Packets'"); - InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpGroupReserveWritePipePackets].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Reserve Id'"); - InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpGroupCommitReadPipe].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Pipe'"); - InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Reserve Id'"); - InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Packet Size'"); - InstructionDesc[OpGroupCommitWritePipe].operands.push(OperandId, "'Packet Alignment'"); - - InstructionDesc[OpBuildNDRange].operands.push(OperandId, "'GlobalWorkSize'"); - InstructionDesc[OpBuildNDRange].operands.push(OperandId, "'LocalWorkSize'"); - InstructionDesc[OpBuildNDRange].operands.push(OperandId, "'GlobalWorkOffset'"); - - InstructionDesc[OpCaptureEventProfilingInfo].operands.push(OperandId, "'Event'"); - InstructionDesc[OpCaptureEventProfilingInfo].operands.push(OperandId, "'Profiling Info'"); - InstructionDesc[OpCaptureEventProfilingInfo].operands.push(OperandId, "'Value'"); - - InstructionDesc[OpSetUserEventStatus].operands.push(OperandId, "'Event'"); - InstructionDesc[OpSetUserEventStatus].operands.push(OperandId, "'Status'"); - - InstructionDesc[OpIsValidEvent].operands.push(OperandId, "'Event'"); - - InstructionDesc[OpRetainEvent].operands.push(OperandId, "'Event'"); - - InstructionDesc[OpReleaseEvent].operands.push(OperandId, "'Event'"); - - InstructionDesc[OpGetKernelWorkGroupSize].operands.push(OperandId, "'Invoke'"); - InstructionDesc[OpGetKernelWorkGroupSize].operands.push(OperandId, "'Param'"); - InstructionDesc[OpGetKernelWorkGroupSize].operands.push(OperandId, "'Param Size'"); - InstructionDesc[OpGetKernelWorkGroupSize].operands.push(OperandId, "'Param Align'"); - - InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].operands.push(OperandId, "'Invoke'"); - InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].operands.push(OperandId, "'Param'"); - InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].operands.push(OperandId, "'Param Size'"); - InstructionDesc[OpGetKernelPreferredWorkGroupSizeMultiple].operands.push(OperandId, "'Param Align'"); - - InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'ND Range'"); - InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'Invoke'"); - InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'Param'"); - InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'Param Size'"); - InstructionDesc[OpGetKernelNDrangeSubGroupCount].operands.push(OperandId, "'Param Align'"); - - InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'ND Range'"); - InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'Invoke'"); - InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'Param'"); - InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'Param Size'"); - InstructionDesc[OpGetKernelNDrangeMaxSubGroupSize].operands.push(OperandId, "'Param Align'"); - - InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Queue'"); - InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Flags'"); - InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'ND Range'"); - InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Num Events'"); - InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Wait Events'"); - InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Ret Event'"); - InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Invoke'"); - InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Param'"); - InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Param Size'"); - InstructionDesc[OpEnqueueKernel].operands.push(OperandId, "'Param Align'"); - InstructionDesc[OpEnqueueKernel].operands.push(OperandVariableIds, "'Local Size'"); - - InstructionDesc[OpEnqueueMarker].operands.push(OperandId, "'Queue'"); - InstructionDesc[OpEnqueueMarker].operands.push(OperandId, "'Num Events'"); - InstructionDesc[OpEnqueueMarker].operands.push(OperandId, "'Wait Events'"); - InstructionDesc[OpEnqueueMarker].operands.push(OperandId, "'Ret Event'"); - - InstructionDesc[OpGroupNonUniformElect].operands.push(OperandScope, "'Execution'"); - - InstructionDesc[OpGroupNonUniformAll].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformAll].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupNonUniformAny].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformAny].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupNonUniformAllEqual].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformAllEqual].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupNonUniformBroadcast].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformBroadcast].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformBroadcast].operands.push(OperandId, "ID"); - - InstructionDesc[OpGroupNonUniformBroadcastFirst].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformBroadcastFirst].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupNonUniformBallot].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformBallot].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupNonUniformInverseBallot].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformInverseBallot].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupNonUniformBallotBitExtract].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformBallotBitExtract].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformBallotBitExtract].operands.push(OperandId, "Bit"); - - InstructionDesc[OpGroupNonUniformBallotBitCount].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformBallotBitCount].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformBallotBitCount].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupNonUniformBallotFindLSB].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformBallotFindLSB].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupNonUniformBallotFindMSB].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformBallotFindMSB].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupNonUniformShuffle].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformShuffle].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformShuffle].operands.push(OperandId, "'Id'"); - - InstructionDesc[OpGroupNonUniformShuffleXor].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformShuffleXor].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformShuffleXor].operands.push(OperandId, "Mask"); - - InstructionDesc[OpGroupNonUniformShuffleUp].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformShuffleUp].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformShuffleUp].operands.push(OperandId, "Offset"); - - InstructionDesc[OpGroupNonUniformShuffleDown].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformShuffleDown].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformShuffleDown].operands.push(OperandId, "Offset"); - - InstructionDesc[OpGroupNonUniformIAdd].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformIAdd].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformIAdd].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformIAdd].operands.push(OperandId, "'ClusterSize'", true); - - InstructionDesc[OpGroupNonUniformFAdd].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformFAdd].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformFAdd].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformFAdd].operands.push(OperandId, "'ClusterSize'", true); - - InstructionDesc[OpGroupNonUniformIMul].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformIMul].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformIMul].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformIMul].operands.push(OperandId, "'ClusterSize'", true); - - InstructionDesc[OpGroupNonUniformFMul].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformFMul].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformFMul].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformFMul].operands.push(OperandId, "'ClusterSize'", true); - - InstructionDesc[OpGroupNonUniformSMin].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformSMin].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformSMin].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformSMin].operands.push(OperandId, "'ClusterSize'", true); - - InstructionDesc[OpGroupNonUniformUMin].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformUMin].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformUMin].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformUMin].operands.push(OperandId, "'ClusterSize'", true); - - InstructionDesc[OpGroupNonUniformFMin].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformFMin].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformFMin].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformFMin].operands.push(OperandId, "'ClusterSize'", true); - InstructionDesc[OpGroupNonUniformSMax].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformSMax].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformSMax].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformSMax].operands.push(OperandId, "'ClusterSize'", true); + InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Component Type'"); + InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Scope'"); + InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Rows'"); + InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Columns'"); - InstructionDesc[OpGroupNonUniformUMax].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformUMax].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformUMax].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformUMax].operands.push(OperandId, "'ClusterSize'", true); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Stride'"); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Column Major'"); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandMemoryAccess, "'Memory Access'"); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandLiteralNumber, "", true); + InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "", true); - InstructionDesc[OpGroupNonUniformFMax].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformFMax].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformFMax].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformFMax].operands.push(OperandId, "'ClusterSize'", true); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Object'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Stride'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Column Major'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandMemoryAccess, "'Memory Access'"); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandLiteralNumber, "", true); + InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "", true); - InstructionDesc[OpGroupNonUniformBitwiseAnd].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformBitwiseAnd].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformBitwiseAnd].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformBitwiseAnd].operands.push(OperandId, "'ClusterSize'", true); + InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'A'"); + InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'B'"); + InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'C'"); - InstructionDesc[OpGroupNonUniformBitwiseOr].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformBitwiseOr].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformBitwiseOr].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformBitwiseOr].operands.push(OperandId, "'ClusterSize'", true); - - InstructionDesc[OpGroupNonUniformBitwiseXor].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformBitwiseXor].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformBitwiseXor].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformBitwiseXor].operands.push(OperandId, "'ClusterSize'", true); - - InstructionDesc[OpGroupNonUniformLogicalAnd].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformLogicalAnd].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformLogicalAnd].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformLogicalAnd].operands.push(OperandId, "'ClusterSize'", true); - - InstructionDesc[OpGroupNonUniformLogicalOr].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformLogicalOr].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformLogicalOr].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformLogicalOr].operands.push(OperandId, "'ClusterSize'", true); - - InstructionDesc[OpGroupNonUniformLogicalXor].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformLogicalXor].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupNonUniformLogicalXor].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformLogicalXor].operands.push(OperandId, "'ClusterSize'", true); - - InstructionDesc[OpGroupNonUniformQuadBroadcast].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformQuadBroadcast].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformQuadBroadcast].operands.push(OperandId, "'Id'"); - - InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "X"); - InstructionDesc[OpGroupNonUniformQuadSwap].operands.push(OperandId, "'Direction'"); - - InstructionDesc[OpSubgroupBallotKHR].operands.push(OperandId, "'Predicate'"); - - InstructionDesc[OpSubgroupFirstInvocationKHR].operands.push(OperandId, "'Value'"); - - InstructionDesc[OpSubgroupAnyKHR].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpSubgroupAnyKHR].operands.push(OperandId, "'Predicate'"); - - InstructionDesc[OpSubgroupAllKHR].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpSubgroupAllKHR].operands.push(OperandId, "'Predicate'"); - - InstructionDesc[OpSubgroupAllEqualKHR].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpSubgroupAllEqualKHR].operands.push(OperandId, "'Predicate'"); - - InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Value'"); - InstructionDesc[OpSubgroupReadInvocationKHR].operands.push(OperandId, "'Index'"); - - InstructionDesc[OpModuleProcessed].operands.push(OperandLiteralString, "'process'"); - - InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupIAddNonUniformAMD].operands.push(OperandId, "'X'"); - - InstructionDesc[OpGroupFAddNonUniformAMD].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupFAddNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupFAddNonUniformAMD].operands.push(OperandId, "'X'"); - - InstructionDesc[OpGroupUMinNonUniformAMD].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupUMinNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupUMinNonUniformAMD].operands.push(OperandId, "'X'"); - - InstructionDesc[OpGroupSMinNonUniformAMD].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupSMinNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupSMinNonUniformAMD].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupFMinNonUniformAMD].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupFMinNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupFMinNonUniformAMD].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupUMaxNonUniformAMD].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupUMaxNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupUMaxNonUniformAMD].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupSMaxNonUniformAMD].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupSMaxNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupSMaxNonUniformAMD].operands.push(OperandId, "X"); - - InstructionDesc[OpGroupFMaxNonUniformAMD].operands.push(OperandScope, "'Execution'"); - InstructionDesc[OpGroupFMaxNonUniformAMD].operands.push(OperandGroupOperation, "'Operation'"); - InstructionDesc[OpGroupFMaxNonUniformAMD].operands.push(OperandId, "X"); - - InstructionDesc[OpFragmentMaskFetchAMD].operands.push(OperandId, "'Image'"); - InstructionDesc[OpFragmentMaskFetchAMD].operands.push(OperandId, "'Coordinate'"); - - InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Image'"); - InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpFragmentFetchAMD].operands.push(OperandId, "'Fragment Index'"); - - InstructionDesc[OpGroupNonUniformPartitionNV].operands.push(OperandId, "X"); - - InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false); - - InstructionDesc[OpTraceNV].operands.push(OperandId, "'Acceleration Structure'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Flags'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'Cull Mask'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Offset'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'SBT Record Stride'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'Miss Index'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Origin'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMin'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'Ray Direction'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'TMax'"); - InstructionDesc[OpTraceNV].operands.push(OperandId, "'Payload'"); - InstructionDesc[OpTraceNV].setResultAndType(false, false); - - InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Acceleration Structure'"); - InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Flags'"); - InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Cull Mask'"); - InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Offset'"); - InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'SBT Record Stride'"); - InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Miss Index'"); - InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Origin'"); - InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMin'"); - InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Ray Direction'"); - InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'TMax'"); - InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Time'"); - InstructionDesc[OpTraceRayMotionNV].operands.push(OperandId, "'Payload'"); - InstructionDesc[OpTraceRayMotionNV].setResultAndType(false, false); - - InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Acceleration Structure'"); - InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Flags'"); - InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Cull Mask'"); - InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Offset'"); - InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'SBT Record Stride'"); - InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Miss Index'"); - InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Origin'"); - InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMin'"); - InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Ray Direction'"); - InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'TMax'"); - InstructionDesc[OpTraceRayKHR].operands.push(OperandId, "'Payload'"); - InstructionDesc[OpTraceRayKHR].setResultAndType(false, false); - - InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Parameter'"); - InstructionDesc[OpReportIntersectionKHR].operands.push(OperandId, "'Hit Kind'"); - - InstructionDesc[OpIgnoreIntersectionNV].setResultAndType(false, false); - - InstructionDesc[OpIgnoreIntersectionKHR].setResultAndType(false, false); - - InstructionDesc[OpTerminateRayNV].setResultAndType(false, false); - - InstructionDesc[OpTerminateRayKHR].setResultAndType(false, false); - - InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "SBT Record Index"); - InstructionDesc[OpExecuteCallableNV].operands.push(OperandId, "CallableData ID"); - InstructionDesc[OpExecuteCallableNV].setResultAndType(false, false); - - InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "SBT Record Index"); - InstructionDesc[OpExecuteCallableKHR].operands.push(OperandId, "CallableData"); - InstructionDesc[OpExecuteCallableKHR].setResultAndType(false, false); - - InstructionDesc[OpConvertUToAccelerationStructureKHR].operands.push(OperandId, "Value"); - InstructionDesc[OpConvertUToAccelerationStructureKHR].setResultAndType(true, true); - - // Ray Query - InstructionDesc[OpTypeAccelerationStructureKHR].setResultAndType(true, false); - InstructionDesc[OpTypeRayQueryKHR].setResultAndType(true, false); - - InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'AccelerationS'"); - InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'RayFlags'"); - InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'CullMask'"); - InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Origin'"); - InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmin'"); - InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Direction'"); - InstructionDesc[OpRayQueryInitializeKHR].operands.push(OperandId, "'Tmax'"); - InstructionDesc[OpRayQueryInitializeKHR].setResultAndType(false, false); - - InstructionDesc[OpRayQueryTerminateKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryTerminateKHR].setResultAndType(false, false); - - InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGenerateIntersectionKHR].operands.push(OperandId, "'THit'"); - InstructionDesc[OpRayQueryGenerateIntersectionKHR].setResultAndType(false, false); - - InstructionDesc[OpRayQueryConfirmIntersectionKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryConfirmIntersectionKHR].setResultAndType(false, false); - - InstructionDesc[OpRayQueryProceedKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryProceedKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionTypeKHR].operands.push(OperandId, "'Committed'"); - InstructionDesc[OpRayQueryGetIntersectionTypeKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetRayTMinKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetRayTMinKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetRayFlagsKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetRayFlagsKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionTKHR].operands.push(OperandId, "'Committed'"); - InstructionDesc[OpRayQueryGetIntersectionTKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].operands.push(OperandId, "'Committed'"); - InstructionDesc[OpRayQueryGetIntersectionInstanceCustomIndexKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].operands.push(OperandId, "'Committed'"); - InstructionDesc[OpRayQueryGetIntersectionInstanceIdKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].operands.push(OperandId, "'Committed'"); - InstructionDesc[OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].operands.push(OperandId, "'Committed'"); - InstructionDesc[OpRayQueryGetIntersectionGeometryIndexKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].operands.push(OperandId, "'Committed'"); - InstructionDesc[OpRayQueryGetIntersectionPrimitiveIndexKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].operands.push(OperandId, "'Committed'"); - InstructionDesc[OpRayQueryGetIntersectionBarycentricsKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].operands.push(OperandId, "'Committed'"); - InstructionDesc[OpRayQueryGetIntersectionFrontFaceKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionCandidateAABBOpaqueKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].operands.push(OperandId, "'Committed'"); - InstructionDesc[OpRayQueryGetIntersectionObjectRayDirectionKHR].setResultAndType(true, true); + InstructionDesc[OpCooperativeMatrixLengthNV].operands.push(OperandId, "'Type'"); - InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].operands.push(OperandId, "'Committed'"); - InstructionDesc[OpRayQueryGetIntersectionObjectRayOriginKHR].setResultAndType(true, true); + InstructionDesc[OpTypeCooperativeMatrixKHR].operands.push(OperandId, "'Component Type'"); + InstructionDesc[OpTypeCooperativeMatrixKHR].operands.push(OperandId, "'Scope'"); + InstructionDesc[OpTypeCooperativeMatrixKHR].operands.push(OperandId, "'Rows'"); + InstructionDesc[OpTypeCooperativeMatrixKHR].operands.push(OperandId, "'Columns'"); + InstructionDesc[OpTypeCooperativeMatrixKHR].operands.push(OperandId, "'Use'"); - InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetWorldRayDirectionKHR].setResultAndType(true, true); + InstructionDesc[OpCooperativeMatrixLoadKHR].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpCooperativeMatrixLoadKHR].operands.push(OperandId, "'Memory Layout'"); + InstructionDesc[OpCooperativeMatrixLoadKHR].operands.push(OperandId, "'Stride'"); + InstructionDesc[OpCooperativeMatrixLoadKHR].operands.push(OperandMemoryAccess, "'Memory Access'"); + InstructionDesc[OpCooperativeMatrixLoadKHR].operands.push(OperandLiteralNumber, "", true); + InstructionDesc[OpCooperativeMatrixLoadKHR].operands.push(OperandId, "", true); - InstructionDesc[OpRayQueryGetWorldRayOriginKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetWorldRayOriginKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].operands.push(OperandId, "'Committed'"); - InstructionDesc[OpRayQueryGetIntersectionObjectToWorldKHR].setResultAndType(true, true); - - InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'RayQuery'"); - InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].operands.push(OperandId, "'Committed'"); - InstructionDesc[OpRayQueryGetIntersectionWorldToObjectKHR].setResultAndType(true, true); - - InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Sampled Image'"); - InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coordinate'"); - InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Granularity'"); - InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandId, "'Coarse'"); - InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandImageOperands, "", true); - InstructionDesc[OpImageSampleFootprintNV].operands.push(OperandVariableIds, "", true); - - InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Index Offset'"); - InstructionDesc[OpWritePackedPrimitiveIndices4x8NV].operands.push(OperandId, "'Packed Indices'"); - - InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Component Type'"); - InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Scope'"); - InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Rows'"); - InstructionDesc[OpTypeCooperativeMatrixNV].operands.push(OperandId, "'Columns'"); - - InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Stride'"); - InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "'Column Major'"); - InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandMemoryAccess, "'Memory Access'"); - InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandLiteralNumber, "", true); - InstructionDesc[OpCooperativeMatrixLoadNV].operands.push(OperandId, "", true); + InstructionDesc[OpCooperativeMatrixStoreKHR].operands.push(OperandId, "'Pointer'"); + InstructionDesc[OpCooperativeMatrixStoreKHR].operands.push(OperandId, "'Object'"); + InstructionDesc[OpCooperativeMatrixStoreKHR].operands.push(OperandId, "'Memory Layout'"); + InstructionDesc[OpCooperativeMatrixStoreKHR].operands.push(OperandId, "'Stride'"); + InstructionDesc[OpCooperativeMatrixStoreKHR].operands.push(OperandMemoryAccess, "'Memory Access'"); + InstructionDesc[OpCooperativeMatrixStoreKHR].operands.push(OperandLiteralNumber, "", true); + InstructionDesc[OpCooperativeMatrixStoreKHR].operands.push(OperandId, "", true); - InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Pointer'"); - InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Object'"); - InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Stride'"); - InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "'Column Major'"); - InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandMemoryAccess, "'Memory Access'"); - InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandLiteralNumber, "", true); - InstructionDesc[OpCooperativeMatrixStoreNV].operands.push(OperandId, "", true); + InstructionDesc[OpCooperativeMatrixMulAddKHR].operands.push(OperandId, "'A'"); + InstructionDesc[OpCooperativeMatrixMulAddKHR].operands.push(OperandId, "'B'"); + InstructionDesc[OpCooperativeMatrixMulAddKHR].operands.push(OperandId, "'C'"); + InstructionDesc[OpCooperativeMatrixMulAddKHR].operands.push(OperandCooperativeMatrixOperands, "'Cooperative Matrix Operands'", true); - InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'A'"); - InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'B'"); - InstructionDesc[OpCooperativeMatrixMulAddNV].operands.push(OperandId, "'C'"); - - InstructionDesc[OpCooperativeMatrixLengthNV].operands.push(OperandId, "'Type'"); - - InstructionDesc[OpDemoteToHelperInvocationEXT].setResultAndType(false, false); - - InstructionDesc[OpReadClockKHR].operands.push(OperandScope, "'Scope'"); + InstructionDesc[OpCooperativeMatrixLengthKHR].operands.push(OperandId, "'Type'"); + + InstructionDesc[OpDemoteToHelperInvocationEXT].setResultAndType(false, false); + + InstructionDesc[OpReadClockKHR].operands.push(OperandScope, "'Scope'"); + + InstructionDesc[OpTypeHitObjectNV].setResultAndType(true, false); + + InstructionDesc[OpHitObjectGetShaderRecordBufferHandleNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetShaderRecordBufferHandleNV].setResultAndType(true, true); + + InstructionDesc[OpReorderThreadWithHintNV].operands.push(OperandId, "'Hint'"); + InstructionDesc[OpReorderThreadWithHintNV].operands.push(OperandId, "'Bits'"); + InstructionDesc[OpReorderThreadWithHintNV].setResultAndType(false, false); + + InstructionDesc[OpReorderThreadWithHitObjectNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpReorderThreadWithHitObjectNV].operands.push(OperandId, "'Hint'"); + InstructionDesc[OpReorderThreadWithHitObjectNV].operands.push(OperandId, "'Bits'"); + InstructionDesc[OpReorderThreadWithHitObjectNV].setResultAndType(false, false); + + InstructionDesc[OpHitObjectGetCurrentTimeNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetCurrentTimeNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetHitKindNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetHitKindNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetPrimitiveIndexNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetPrimitiveIndexNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetGeometryIndexNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetGeometryIndexNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetInstanceIdNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetInstanceIdNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetInstanceCustomIndexNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetInstanceCustomIndexNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetObjectRayDirectionNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetObjectRayDirectionNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetObjectRayOriginNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetObjectRayOriginNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetWorldRayDirectionNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetWorldRayDirectionNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetWorldRayOriginNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetWorldRayOriginNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetWorldToObjectNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetWorldToObjectNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetObjectToWorldNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetObjectToWorldNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetRayTMaxNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetRayTMaxNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetRayTMinNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetRayTMinNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetShaderBindingTableRecordIndexNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetShaderBindingTableRecordIndexNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectIsEmptyNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectIsEmptyNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectIsHitNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectIsHitNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectIsMissNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectIsMissNV].setResultAndType(true, true); + + InstructionDesc[OpHitObjectGetAttributesNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectGetAttributesNV].operands.push(OperandId, "'HitObjectAttribute'"); + InstructionDesc[OpHitObjectGetAttributesNV].setResultAndType(false, false); + + InstructionDesc[OpHitObjectExecuteShaderNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectExecuteShaderNV].operands.push(OperandId, "'Payload'"); + InstructionDesc[OpHitObjectExecuteShaderNV].setResultAndType(false, false); + + InstructionDesc[OpHitObjectRecordHitNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectRecordHitNV].operands.push(OperandId, "'Acceleration Structure'"); + InstructionDesc[OpHitObjectRecordHitNV].operands.push(OperandId, "'InstanceId'"); + InstructionDesc[OpHitObjectRecordHitNV].operands.push(OperandId, "'PrimitiveId'"); + InstructionDesc[OpHitObjectRecordHitNV].operands.push(OperandId, "'GeometryIndex'"); + InstructionDesc[OpHitObjectRecordHitNV].operands.push(OperandId, "'HitKind'"); + InstructionDesc[OpHitObjectRecordHitNV].operands.push(OperandId, "'SBT Record Offset'"); + InstructionDesc[OpHitObjectRecordHitNV].operands.push(OperandId, "'SBT Record Stride'"); + InstructionDesc[OpHitObjectRecordHitNV].operands.push(OperandId, "'Origin'"); + InstructionDesc[OpHitObjectRecordHitNV].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpHitObjectRecordHitNV].operands.push(OperandId, "'Direction'"); + InstructionDesc[OpHitObjectRecordHitNV].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpHitObjectRecordHitNV].operands.push(OperandId, "'HitObject Attribute'"); + InstructionDesc[OpHitObjectRecordHitNV].setResultAndType(false, false); + + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'Acceleration Structure'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'InstanceId'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'PrimitiveId'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'GeometryIndex'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'HitKind'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'SBT Record Offset'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'SBT Record Stride'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'Origin'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'Direction'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'Current Time'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].operands.push(OperandId, "'HitObject Attribute'"); + InstructionDesc[OpHitObjectRecordHitMotionNV].setResultAndType(false, false); + + InstructionDesc[OpHitObjectRecordHitWithIndexNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectRecordHitWithIndexNV].operands.push(OperandId, "'Acceleration Structure'"); + InstructionDesc[OpHitObjectRecordHitWithIndexNV].operands.push(OperandId, "'InstanceId'"); + InstructionDesc[OpHitObjectRecordHitWithIndexNV].operands.push(OperandId, "'PrimitiveId'"); + InstructionDesc[OpHitObjectRecordHitWithIndexNV].operands.push(OperandId, "'GeometryIndex'"); + InstructionDesc[OpHitObjectRecordHitWithIndexNV].operands.push(OperandId, "'HitKind'"); + InstructionDesc[OpHitObjectRecordHitWithIndexNV].operands.push(OperandId, "'SBT Record Index'"); + InstructionDesc[OpHitObjectRecordHitWithIndexNV].operands.push(OperandId, "'Origin'"); + InstructionDesc[OpHitObjectRecordHitWithIndexNV].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpHitObjectRecordHitWithIndexNV].operands.push(OperandId, "'Direction'"); + InstructionDesc[OpHitObjectRecordHitWithIndexNV].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpHitObjectRecordHitWithIndexNV].operands.push(OperandId, "'HitObject Attribute'"); + InstructionDesc[OpHitObjectRecordHitWithIndexNV].setResultAndType(false, false); + + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].operands.push(OperandId, "'Acceleration Structure'"); + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].operands.push(OperandId, "'InstanceId'"); + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].operands.push(OperandId, "'PrimitiveId'"); + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].operands.push(OperandId, "'GeometryIndex'"); + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].operands.push(OperandId, "'HitKind'"); + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].operands.push(OperandId, "'SBT Record Index'"); + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].operands.push(OperandId, "'Origin'"); + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].operands.push(OperandId, "'Direction'"); + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].operands.push(OperandId, "'Current Time'"); + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].operands.push(OperandId, "'HitObject Attribute'"); + InstructionDesc[OpHitObjectRecordHitWithIndexMotionNV].setResultAndType(false, false); + + InstructionDesc[OpHitObjectRecordMissNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectRecordMissNV].operands.push(OperandId, "'SBT Index'"); + InstructionDesc[OpHitObjectRecordMissNV].operands.push(OperandId, "'Origin'"); + InstructionDesc[OpHitObjectRecordMissNV].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpHitObjectRecordMissNV].operands.push(OperandId, "'Direction'"); + InstructionDesc[OpHitObjectRecordMissNV].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpHitObjectRecordMissNV].setResultAndType(false, false); + + InstructionDesc[OpHitObjectRecordMissMotionNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectRecordMissMotionNV].operands.push(OperandId, "'SBT Index'"); + InstructionDesc[OpHitObjectRecordMissMotionNV].operands.push(OperandId, "'Origin'"); + InstructionDesc[OpHitObjectRecordMissMotionNV].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpHitObjectRecordMissMotionNV].operands.push(OperandId, "'Direction'"); + InstructionDesc[OpHitObjectRecordMissMotionNV].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpHitObjectRecordMissMotionNV].operands.push(OperandId, "'Current Time'"); + InstructionDesc[OpHitObjectRecordMissMotionNV].setResultAndType(false, false); + + InstructionDesc[OpHitObjectRecordEmptyNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectRecordEmptyNV].setResultAndType(false, false); + + InstructionDesc[OpHitObjectTraceRayNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectTraceRayNV].operands.push(OperandId, "'Acceleration Structure'"); + InstructionDesc[OpHitObjectTraceRayNV].operands.push(OperandId, "'RayFlags'"); + InstructionDesc[OpHitObjectTraceRayNV].operands.push(OperandId, "'Cullmask'"); + InstructionDesc[OpHitObjectTraceRayNV].operands.push(OperandId, "'SBT Record Offset'"); + InstructionDesc[OpHitObjectTraceRayNV].operands.push(OperandId, "'SBT Record Stride'"); + InstructionDesc[OpHitObjectTraceRayNV].operands.push(OperandId, "'Miss Index'"); + InstructionDesc[OpHitObjectTraceRayNV].operands.push(OperandId, "'Origin'"); + InstructionDesc[OpHitObjectTraceRayNV].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpHitObjectTraceRayNV].operands.push(OperandId, "'Direction'"); + InstructionDesc[OpHitObjectTraceRayNV].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpHitObjectTraceRayNV].operands.push(OperandId, "'Payload'"); + InstructionDesc[OpHitObjectTraceRayNV].setResultAndType(false, false); + + InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'HitObject'"); + InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'Acceleration Structure'"); + InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'RayFlags'"); + InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'Cullmask'"); + InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'SBT Record Offset'"); + InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'SBT Record Stride'"); + InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'Miss Index'"); + InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'Origin'"); + InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'TMin'"); + InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'Direction'"); + InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'TMax'"); + InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'Time'"); + InstructionDesc[OpHitObjectTraceRayMotionNV].operands.push(OperandId, "'Payload'"); + InstructionDesc[OpHitObjectTraceRayMotionNV].setResultAndType(false, false); + + InstructionDesc[OpFetchMicroTriangleVertexBarycentricNV].operands.push(OperandId, "'Acceleration Structure'"); + InstructionDesc[OpFetchMicroTriangleVertexBarycentricNV].operands.push(OperandId, "'Instance ID'"); + InstructionDesc[OpFetchMicroTriangleVertexBarycentricNV].operands.push(OperandId, "'Geometry Index'"); + InstructionDesc[OpFetchMicroTriangleVertexBarycentricNV].operands.push(OperandId, "'Primitive Index'"); + InstructionDesc[OpFetchMicroTriangleVertexBarycentricNV].operands.push(OperandId, "'Barycentrics'"); + InstructionDesc[OpFetchMicroTriangleVertexBarycentricNV].setResultAndType(true, true); + + InstructionDesc[OpFetchMicroTriangleVertexPositionNV].operands.push(OperandId, "'Acceleration Structure'"); + InstructionDesc[OpFetchMicroTriangleVertexPositionNV].operands.push(OperandId, "'Instance ID'"); + InstructionDesc[OpFetchMicroTriangleVertexPositionNV].operands.push(OperandId, "'Geometry Index'"); + InstructionDesc[OpFetchMicroTriangleVertexPositionNV].operands.push(OperandId, "'Primitive Index'"); + InstructionDesc[OpFetchMicroTriangleVertexPositionNV].operands.push(OperandId, "'Barycentrics'"); + InstructionDesc[OpFetchMicroTriangleVertexPositionNV].setResultAndType(true, true); + + InstructionDesc[OpColorAttachmentReadEXT].operands.push(OperandId, "'Attachment'"); + InstructionDesc[OpColorAttachmentReadEXT].operands.push(OperandId, "'Sample'", true); + InstructionDesc[OpStencilAttachmentReadEXT].operands.push(OperandId, "'Sample'", true); + InstructionDesc[OpDepthAttachmentReadEXT].operands.push(OperandId, "'Sample'", true); + + InstructionDesc[OpImageSampleWeightedQCOM].operands.push(OperandId, "'source texture'"); + InstructionDesc[OpImageSampleWeightedQCOM].operands.push(OperandId, "'texture coordinates'"); + InstructionDesc[OpImageSampleWeightedQCOM].operands.push(OperandId, "'weights texture'"); + InstructionDesc[OpImageSampleWeightedQCOM].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageSampleWeightedQCOM].setResultAndType(true, true); + + InstructionDesc[OpImageBoxFilterQCOM].operands.push(OperandId, "'source texture'"); + InstructionDesc[OpImageBoxFilterQCOM].operands.push(OperandId, "'texture coordinates'"); + InstructionDesc[OpImageBoxFilterQCOM].operands.push(OperandId, "'box size'"); + InstructionDesc[OpImageBoxFilterQCOM].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageBoxFilterQCOM].setResultAndType(true, true); + + InstructionDesc[OpImageBlockMatchSADQCOM].operands.push(OperandId, "'target texture'"); + InstructionDesc[OpImageBlockMatchSADQCOM].operands.push(OperandId, "'target coordinates'"); + InstructionDesc[OpImageBlockMatchSADQCOM].operands.push(OperandId, "'reference texture'"); + InstructionDesc[OpImageBlockMatchSADQCOM].operands.push(OperandId, "'reference coordinates'"); + InstructionDesc[OpImageBlockMatchSADQCOM].operands.push(OperandId, "'block size'"); + InstructionDesc[OpImageBlockMatchSADQCOM].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageBlockMatchSADQCOM].setResultAndType(true, true); + + InstructionDesc[OpImageBlockMatchSSDQCOM].operands.push(OperandId, "'target texture'"); + InstructionDesc[OpImageBlockMatchSSDQCOM].operands.push(OperandId, "'target coordinates'"); + InstructionDesc[OpImageBlockMatchSSDQCOM].operands.push(OperandId, "'reference texture'"); + InstructionDesc[OpImageBlockMatchSSDQCOM].operands.push(OperandId, "'reference coordinates'"); + InstructionDesc[OpImageBlockMatchSSDQCOM].operands.push(OperandId, "'block size'"); + InstructionDesc[OpImageBlockMatchSSDQCOM].operands.push(OperandImageOperands, "", true); + InstructionDesc[OpImageBlockMatchSSDQCOM].setResultAndType(true, true); + }); } }; // end spv namespace diff --git a/src/libraries/glslang/SPIRV/doc.h b/src/libraries/glslang/SPIRV/doc.h index 2a0b28c6b..521529913 100644 --- a/src/libraries/glslang/SPIRV/doc.h +++ b/src/libraries/glslang/SPIRV/doc.h @@ -156,6 +156,7 @@ enum OperandClass { OperandKernelEnqueueFlags, OperandKernelProfilingInfo, OperandCapability, + OperandCooperativeMatrixOperands, OperandOpcode, @@ -190,15 +191,15 @@ class OperandParameters { // Parameterize an enumerant class EnumParameters { public: - EnumParameters() : desc(0) { } + EnumParameters() : desc(nullptr) { } 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) { } + EnumDefinition() : + ceiling(0), bitmask(false), getName(nullptr), enumParams(nullptr), operandParams(nullptr) { } void set(int ceil, const char* (*name)(int), EnumParameters* ep, bool mask = false) { ceiling = ceil; @@ -239,8 +240,8 @@ class InstructionParameters { OperandParameters operands; protected: - int typePresent : 1; - int resultPresent : 1; + bool typePresent : 1; + bool resultPresent : 1; }; // The set of objects that hold all the instruction/operand diff --git a/src/libraries/glslang/SPIRV/hex_float.h b/src/libraries/glslang/SPIRV/hex_float.h index 8be8e9f7e..785e8af11 100644 --- a/src/libraries/glslang/SPIRV/hex_float.h +++ b/src/libraries/glslang/SPIRV/hex_float.h @@ -23,19 +23,6 @@ #include #include -#if defined(_MSC_VER) && _MSC_VER < 1800 -namespace std { -bool isnan(double f) -{ - return ::_isnan(f) != 0; -} -bool isinf(double f) -{ - return ::_finite(f) == 0; -} -} -#endif - #include "bitutils.h" namespace spvutils { diff --git a/src/libraries/glslang/SPIRV/spirv.hpp b/src/libraries/glslang/SPIRV/spirv.hpp index c1abd2640..5999aba93 100644 --- a/src/libraries/glslang/SPIRV/spirv.hpp +++ b/src/libraries/glslang/SPIRV/spirv.hpp @@ -1,2314 +1,2796 @@ -// Copyright (c) 2014-2020 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. - -// This header is automatically generated by the same tool that creates -// the Binary Section of the SPIR-V specification. - -// Enumeration tokens for SPIR-V, in various styles: -// C, C++, C++11, JSON, Lua, Python, C#, D -// -// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL -// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL -// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL -// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL -// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] -// - C# will use enum classes in the Specification class located in the "Spv" namespace, -// e.g.: Spv.Specification.SourceLanguage.GLSL -// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL -// -// Some tokens act like mask values, which can be OR'd together, -// while others are mutually exclusive. The mask-like ones have -// "Mask" in their name, and a parallel enum that has the shift -// amount (1 << x) for each corresponding enumerant. - -#ifndef spirv_HPP -#define spirv_HPP - -namespace spv { - -typedef unsigned int Id; - -#define SPV_VERSION 0x10500 -#define SPV_REVISION 4 - -static const unsigned int MagicNumber = 0x07230203; -static const unsigned int Version = 0x00010500; -static const unsigned int Revision = 4; -static const unsigned int OpCodeMask = 0xffff; -static const unsigned int WordCountShift = 16; - -enum SourceLanguage { - SourceLanguageUnknown = 0, - SourceLanguageESSL = 1, - SourceLanguageGLSL = 2, - SourceLanguageOpenCL_C = 3, - SourceLanguageOpenCL_CPP = 4, - SourceLanguageHLSL = 5, - SourceLanguageMax = 0x7fffffff, -}; - -enum ExecutionModel { - ExecutionModelVertex = 0, - ExecutionModelTessellationControl = 1, - ExecutionModelTessellationEvaluation = 2, - ExecutionModelGeometry = 3, - ExecutionModelFragment = 4, - ExecutionModelGLCompute = 5, - ExecutionModelKernel = 6, - ExecutionModelTaskNV = 5267, - ExecutionModelMeshNV = 5268, - ExecutionModelRayGenerationKHR = 5313, - ExecutionModelRayGenerationNV = 5313, - ExecutionModelIntersectionKHR = 5314, - ExecutionModelIntersectionNV = 5314, - ExecutionModelAnyHitKHR = 5315, - ExecutionModelAnyHitNV = 5315, - ExecutionModelClosestHitKHR = 5316, - ExecutionModelClosestHitNV = 5316, - ExecutionModelMissKHR = 5317, - ExecutionModelMissNV = 5317, - ExecutionModelCallableKHR = 5318, - ExecutionModelCallableNV = 5318, - ExecutionModelMax = 0x7fffffff, -}; - -enum AddressingModel { - AddressingModelLogical = 0, - AddressingModelPhysical32 = 1, - AddressingModelPhysical64 = 2, - AddressingModelPhysicalStorageBuffer64 = 5348, - AddressingModelPhysicalStorageBuffer64EXT = 5348, - AddressingModelMax = 0x7fffffff, -}; - -enum MemoryModel { - MemoryModelSimple = 0, - MemoryModelGLSL450 = 1, - MemoryModelOpenCL = 2, - MemoryModelVulkan = 3, - MemoryModelVulkanKHR = 3, - MemoryModelMax = 0x7fffffff, -}; - -enum ExecutionMode { - ExecutionModeInvocations = 0, - ExecutionModeSpacingEqual = 1, - ExecutionModeSpacingFractionalEven = 2, - ExecutionModeSpacingFractionalOdd = 3, - ExecutionModeVertexOrderCw = 4, - ExecutionModeVertexOrderCcw = 5, - ExecutionModePixelCenterInteger = 6, - ExecutionModeOriginUpperLeft = 7, - ExecutionModeOriginLowerLeft = 8, - ExecutionModeEarlyFragmentTests = 9, - ExecutionModePointMode = 10, - ExecutionModeXfb = 11, - ExecutionModeDepthReplacing = 12, - ExecutionModeDepthGreater = 14, - ExecutionModeDepthLess = 15, - ExecutionModeDepthUnchanged = 16, - ExecutionModeLocalSize = 17, - ExecutionModeLocalSizeHint = 18, - ExecutionModeInputPoints = 19, - ExecutionModeInputLines = 20, - ExecutionModeInputLinesAdjacency = 21, - ExecutionModeTriangles = 22, - ExecutionModeInputTrianglesAdjacency = 23, - ExecutionModeQuads = 24, - ExecutionModeIsolines = 25, - ExecutionModeOutputVertices = 26, - ExecutionModeOutputPoints = 27, - ExecutionModeOutputLineStrip = 28, - ExecutionModeOutputTriangleStrip = 29, - ExecutionModeVecTypeHint = 30, - ExecutionModeContractionOff = 31, - ExecutionModeInitializer = 33, - ExecutionModeFinalizer = 34, - ExecutionModeSubgroupSize = 35, - ExecutionModeSubgroupsPerWorkgroup = 36, - ExecutionModeSubgroupsPerWorkgroupId = 37, - ExecutionModeLocalSizeId = 38, - ExecutionModeLocalSizeHintId = 39, - ExecutionModeSubgroupUniformControlFlowKHR = 4421, - ExecutionModePostDepthCoverage = 4446, - ExecutionModeDenormPreserve = 4459, - ExecutionModeDenormFlushToZero = 4460, - ExecutionModeSignedZeroInfNanPreserve = 4461, - ExecutionModeRoundingModeRTE = 4462, - ExecutionModeRoundingModeRTZ = 4463, - ExecutionModeStencilRefReplacingEXT = 5027, - ExecutionModeOutputLinesNV = 5269, - ExecutionModeOutputPrimitivesNV = 5270, - ExecutionModeDerivativeGroupQuadsNV = 5289, - ExecutionModeDerivativeGroupLinearNV = 5290, - ExecutionModeOutputTrianglesNV = 5298, - ExecutionModePixelInterlockOrderedEXT = 5366, - ExecutionModePixelInterlockUnorderedEXT = 5367, - ExecutionModeSampleInterlockOrderedEXT = 5368, - ExecutionModeSampleInterlockUnorderedEXT = 5369, - ExecutionModeShadingRateInterlockOrderedEXT = 5370, - ExecutionModeShadingRateInterlockUnorderedEXT = 5371, - ExecutionModeSharedLocalMemorySizeINTEL = 5618, - ExecutionModeRoundingModeRTPINTEL = 5620, - ExecutionModeRoundingModeRTNINTEL = 5621, - ExecutionModeFloatingPointModeALTINTEL = 5622, - ExecutionModeFloatingPointModeIEEEINTEL = 5623, - ExecutionModeMaxWorkgroupSizeINTEL = 5893, - ExecutionModeMaxWorkDimINTEL = 5894, - ExecutionModeNoGlobalOffsetINTEL = 5895, - ExecutionModeNumSIMDWorkitemsINTEL = 5896, - ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, - ExecutionModeMax = 0x7fffffff, -}; - -enum StorageClass { - StorageClassUniformConstant = 0, - StorageClassInput = 1, - StorageClassUniform = 2, - StorageClassOutput = 3, - StorageClassWorkgroup = 4, - StorageClassCrossWorkgroup = 5, - StorageClassPrivate = 6, - StorageClassFunction = 7, - StorageClassGeneric = 8, - StorageClassPushConstant = 9, - StorageClassAtomicCounter = 10, - StorageClassImage = 11, - StorageClassStorageBuffer = 12, - StorageClassCallableDataKHR = 5328, - StorageClassCallableDataNV = 5328, - StorageClassIncomingCallableDataKHR = 5329, - StorageClassIncomingCallableDataNV = 5329, - StorageClassRayPayloadKHR = 5338, - StorageClassRayPayloadNV = 5338, - StorageClassHitAttributeKHR = 5339, - StorageClassHitAttributeNV = 5339, - StorageClassIncomingRayPayloadKHR = 5342, - StorageClassIncomingRayPayloadNV = 5342, - StorageClassShaderRecordBufferKHR = 5343, - StorageClassShaderRecordBufferNV = 5343, - StorageClassPhysicalStorageBuffer = 5349, - StorageClassPhysicalStorageBufferEXT = 5349, - StorageClassCodeSectionINTEL = 5605, - StorageClassDeviceOnlyINTEL = 5936, - StorageClassHostOnlyINTEL = 5937, - StorageClassMax = 0x7fffffff, -}; - -enum Dim { - Dim1D = 0, - Dim2D = 1, - Dim3D = 2, - DimCube = 3, - DimRect = 4, - DimBuffer = 5, - DimSubpassData = 6, - DimMax = 0x7fffffff, -}; - -enum SamplerAddressingMode { - SamplerAddressingModeNone = 0, - SamplerAddressingModeClampToEdge = 1, - SamplerAddressingModeClamp = 2, - SamplerAddressingModeRepeat = 3, - SamplerAddressingModeRepeatMirrored = 4, - SamplerAddressingModeMax = 0x7fffffff, -}; - -enum SamplerFilterMode { - SamplerFilterModeNearest = 0, - SamplerFilterModeLinear = 1, - SamplerFilterModeMax = 0x7fffffff, -}; - -enum ImageFormat { - ImageFormatUnknown = 0, - ImageFormatRgba32f = 1, - ImageFormatRgba16f = 2, - ImageFormatR32f = 3, - ImageFormatRgba8 = 4, - ImageFormatRgba8Snorm = 5, - ImageFormatRg32f = 6, - ImageFormatRg16f = 7, - ImageFormatR11fG11fB10f = 8, - ImageFormatR16f = 9, - ImageFormatRgba16 = 10, - ImageFormatRgb10A2 = 11, - ImageFormatRg16 = 12, - ImageFormatRg8 = 13, - ImageFormatR16 = 14, - ImageFormatR8 = 15, - ImageFormatRgba16Snorm = 16, - ImageFormatRg16Snorm = 17, - ImageFormatRg8Snorm = 18, - ImageFormatR16Snorm = 19, - ImageFormatR8Snorm = 20, - ImageFormatRgba32i = 21, - ImageFormatRgba16i = 22, - ImageFormatRgba8i = 23, - ImageFormatR32i = 24, - ImageFormatRg32i = 25, - ImageFormatRg16i = 26, - ImageFormatRg8i = 27, - ImageFormatR16i = 28, - ImageFormatR8i = 29, - ImageFormatRgba32ui = 30, - ImageFormatRgba16ui = 31, - ImageFormatRgba8ui = 32, - ImageFormatR32ui = 33, - ImageFormatRgb10a2ui = 34, - ImageFormatRg32ui = 35, - ImageFormatRg16ui = 36, - ImageFormatRg8ui = 37, - ImageFormatR16ui = 38, - ImageFormatR8ui = 39, - ImageFormatR64ui = 40, - ImageFormatR64i = 41, - ImageFormatMax = 0x7fffffff, -}; - -enum ImageChannelOrder { - ImageChannelOrderR = 0, - ImageChannelOrderA = 1, - ImageChannelOrderRG = 2, - ImageChannelOrderRA = 3, - ImageChannelOrderRGB = 4, - ImageChannelOrderRGBA = 5, - ImageChannelOrderBGRA = 6, - ImageChannelOrderARGB = 7, - ImageChannelOrderIntensity = 8, - ImageChannelOrderLuminance = 9, - ImageChannelOrderRx = 10, - ImageChannelOrderRGx = 11, - ImageChannelOrderRGBx = 12, - ImageChannelOrderDepth = 13, - ImageChannelOrderDepthStencil = 14, - ImageChannelOrdersRGB = 15, - ImageChannelOrdersRGBx = 16, - ImageChannelOrdersRGBA = 17, - ImageChannelOrdersBGRA = 18, - ImageChannelOrderABGR = 19, - ImageChannelOrderMax = 0x7fffffff, -}; - -enum ImageChannelDataType { - ImageChannelDataTypeSnormInt8 = 0, - ImageChannelDataTypeSnormInt16 = 1, - ImageChannelDataTypeUnormInt8 = 2, - ImageChannelDataTypeUnormInt16 = 3, - ImageChannelDataTypeUnormShort565 = 4, - ImageChannelDataTypeUnormShort555 = 5, - ImageChannelDataTypeUnormInt101010 = 6, - ImageChannelDataTypeSignedInt8 = 7, - ImageChannelDataTypeSignedInt16 = 8, - ImageChannelDataTypeSignedInt32 = 9, - ImageChannelDataTypeUnsignedInt8 = 10, - ImageChannelDataTypeUnsignedInt16 = 11, - ImageChannelDataTypeUnsignedInt32 = 12, - ImageChannelDataTypeHalfFloat = 13, - ImageChannelDataTypeFloat = 14, - ImageChannelDataTypeUnormInt24 = 15, - ImageChannelDataTypeUnormInt101010_2 = 16, - ImageChannelDataTypeMax = 0x7fffffff, -}; - -enum ImageOperandsShift { - ImageOperandsBiasShift = 0, - ImageOperandsLodShift = 1, - ImageOperandsGradShift = 2, - ImageOperandsConstOffsetShift = 3, - ImageOperandsOffsetShift = 4, - ImageOperandsConstOffsetsShift = 5, - ImageOperandsSampleShift = 6, - ImageOperandsMinLodShift = 7, - ImageOperandsMakeTexelAvailableShift = 8, - ImageOperandsMakeTexelAvailableKHRShift = 8, - ImageOperandsMakeTexelVisibleShift = 9, - ImageOperandsMakeTexelVisibleKHRShift = 9, - ImageOperandsNonPrivateTexelShift = 10, - ImageOperandsNonPrivateTexelKHRShift = 10, - ImageOperandsVolatileTexelShift = 11, - ImageOperandsVolatileTexelKHRShift = 11, - ImageOperandsSignExtendShift = 12, - ImageOperandsZeroExtendShift = 13, - ImageOperandsMax = 0x7fffffff, -}; - -enum ImageOperandsMask { - ImageOperandsMaskNone = 0, - ImageOperandsBiasMask = 0x00000001, - ImageOperandsLodMask = 0x00000002, - ImageOperandsGradMask = 0x00000004, - ImageOperandsConstOffsetMask = 0x00000008, - ImageOperandsOffsetMask = 0x00000010, - ImageOperandsConstOffsetsMask = 0x00000020, - ImageOperandsSampleMask = 0x00000040, - ImageOperandsMinLodMask = 0x00000080, - ImageOperandsMakeTexelAvailableMask = 0x00000100, - ImageOperandsMakeTexelAvailableKHRMask = 0x00000100, - ImageOperandsMakeTexelVisibleMask = 0x00000200, - ImageOperandsMakeTexelVisibleKHRMask = 0x00000200, - ImageOperandsNonPrivateTexelMask = 0x00000400, - ImageOperandsNonPrivateTexelKHRMask = 0x00000400, - ImageOperandsVolatileTexelMask = 0x00000800, - ImageOperandsVolatileTexelKHRMask = 0x00000800, - ImageOperandsSignExtendMask = 0x00001000, - ImageOperandsZeroExtendMask = 0x00002000, -}; - -enum FPFastMathModeShift { - FPFastMathModeNotNaNShift = 0, - FPFastMathModeNotInfShift = 1, - FPFastMathModeNSZShift = 2, - FPFastMathModeAllowRecipShift = 3, - FPFastMathModeFastShift = 4, - FPFastMathModeAllowContractFastINTELShift = 16, - FPFastMathModeAllowReassocINTELShift = 17, - FPFastMathModeMax = 0x7fffffff, -}; - -enum FPFastMathModeMask { - FPFastMathModeMaskNone = 0, - FPFastMathModeNotNaNMask = 0x00000001, - FPFastMathModeNotInfMask = 0x00000002, - FPFastMathModeNSZMask = 0x00000004, - FPFastMathModeAllowRecipMask = 0x00000008, - FPFastMathModeFastMask = 0x00000010, - FPFastMathModeAllowContractFastINTELMask = 0x00010000, - FPFastMathModeAllowReassocINTELMask = 0x00020000, -}; - -enum FPRoundingMode { - FPRoundingModeRTE = 0, - FPRoundingModeRTZ = 1, - FPRoundingModeRTP = 2, - FPRoundingModeRTN = 3, - FPRoundingModeMax = 0x7fffffff, -}; - -enum LinkageType { - LinkageTypeExport = 0, - LinkageTypeImport = 1, - LinkageTypeLinkOnceODR = 2, - LinkageTypeMax = 0x7fffffff, -}; - -enum AccessQualifier { - AccessQualifierReadOnly = 0, - AccessQualifierWriteOnly = 1, - AccessQualifierReadWrite = 2, - AccessQualifierMax = 0x7fffffff, -}; - -enum FunctionParameterAttribute { - FunctionParameterAttributeZext = 0, - FunctionParameterAttributeSext = 1, - FunctionParameterAttributeByVal = 2, - FunctionParameterAttributeSret = 3, - FunctionParameterAttributeNoAlias = 4, - FunctionParameterAttributeNoCapture = 5, - FunctionParameterAttributeNoWrite = 6, - FunctionParameterAttributeNoReadWrite = 7, - FunctionParameterAttributeMax = 0x7fffffff, -}; - -enum Decoration { - DecorationRelaxedPrecision = 0, - DecorationSpecId = 1, - DecorationBlock = 2, - DecorationBufferBlock = 3, - DecorationRowMajor = 4, - DecorationColMajor = 5, - DecorationArrayStride = 6, - DecorationMatrixStride = 7, - DecorationGLSLShared = 8, - DecorationGLSLPacked = 9, - DecorationCPacked = 10, - DecorationBuiltIn = 11, - DecorationNoPerspective = 13, - DecorationFlat = 14, - DecorationPatch = 15, - DecorationCentroid = 16, - DecorationSample = 17, - DecorationInvariant = 18, - DecorationRestrict = 19, - DecorationAliased = 20, - DecorationVolatile = 21, - DecorationConstant = 22, - DecorationCoherent = 23, - DecorationNonWritable = 24, - DecorationNonReadable = 25, - DecorationUniform = 26, - DecorationUniformId = 27, - DecorationSaturatedConversion = 28, - DecorationStream = 29, - DecorationLocation = 30, - DecorationComponent = 31, - DecorationIndex = 32, - DecorationBinding = 33, - DecorationDescriptorSet = 34, - DecorationOffset = 35, - DecorationXfbBuffer = 36, - DecorationXfbStride = 37, - DecorationFuncParamAttr = 38, - DecorationFPRoundingMode = 39, - DecorationFPFastMathMode = 40, - DecorationLinkageAttributes = 41, - DecorationNoContraction = 42, - DecorationInputAttachmentIndex = 43, - DecorationAlignment = 44, - DecorationMaxByteOffset = 45, - DecorationAlignmentId = 46, - DecorationMaxByteOffsetId = 47, - DecorationNoSignedWrap = 4469, - DecorationNoUnsignedWrap = 4470, - DecorationExplicitInterpAMD = 4999, - DecorationOverrideCoverageNV = 5248, - DecorationPassthroughNV = 5250, - DecorationViewportRelativeNV = 5252, - DecorationSecondaryViewportRelativeNV = 5256, - DecorationPerPrimitiveNV = 5271, - DecorationPerViewNV = 5272, - DecorationPerTaskNV = 5273, - DecorationPerVertexNV = 5285, - DecorationNonUniform = 5300, - DecorationNonUniformEXT = 5300, - DecorationRestrictPointer = 5355, - DecorationRestrictPointerEXT = 5355, - DecorationAliasedPointer = 5356, - DecorationAliasedPointerEXT = 5356, - DecorationSIMTCallINTEL = 5599, - DecorationReferencedIndirectlyINTEL = 5602, - DecorationClobberINTEL = 5607, - DecorationSideEffectsINTEL = 5608, - DecorationVectorComputeVariableINTEL = 5624, - DecorationFuncParamIOKindINTEL = 5625, - DecorationVectorComputeFunctionINTEL = 5626, - DecorationStackCallINTEL = 5627, - DecorationGlobalVariableOffsetINTEL = 5628, - DecorationCounterBuffer = 5634, - DecorationHlslCounterBufferGOOGLE = 5634, - DecorationHlslSemanticGOOGLE = 5635, - DecorationUserSemantic = 5635, - DecorationUserTypeGOOGLE = 5636, - DecorationFunctionRoundingModeINTEL = 5822, - DecorationFunctionDenormModeINTEL = 5823, - DecorationRegisterINTEL = 5825, - DecorationMemoryINTEL = 5826, - DecorationNumbanksINTEL = 5827, - DecorationBankwidthINTEL = 5828, - DecorationMaxPrivateCopiesINTEL = 5829, - DecorationSinglepumpINTEL = 5830, - DecorationDoublepumpINTEL = 5831, - DecorationMaxReplicatesINTEL = 5832, - DecorationSimpleDualPortINTEL = 5833, - DecorationMergeINTEL = 5834, - DecorationBankBitsINTEL = 5835, - DecorationForcePow2DepthINTEL = 5836, - DecorationBurstCoalesceINTEL = 5899, - DecorationCacheSizeINTEL = 5900, - DecorationDontStaticallyCoalesceINTEL = 5901, - DecorationPrefetchINTEL = 5902, - DecorationStallEnableINTEL = 5905, - DecorationFuseLoopsInFunctionINTEL = 5907, - DecorationBufferLocationINTEL = 5921, - DecorationIOPipeStorageINTEL = 5944, - DecorationFunctionFloatingPointModeINTEL = 6080, - DecorationSingleElementVectorINTEL = 6085, - DecorationVectorComputeCallableFunctionINTEL = 6087, - DecorationMax = 0x7fffffff, -}; - -enum BuiltIn { - BuiltInPosition = 0, - BuiltInPointSize = 1, - BuiltInClipDistance = 3, - BuiltInCullDistance = 4, - BuiltInVertexId = 5, - BuiltInInstanceId = 6, - BuiltInPrimitiveId = 7, - BuiltInInvocationId = 8, - BuiltInLayer = 9, - BuiltInViewportIndex = 10, - BuiltInTessLevelOuter = 11, - BuiltInTessLevelInner = 12, - BuiltInTessCoord = 13, - BuiltInPatchVertices = 14, - BuiltInFragCoord = 15, - BuiltInPointCoord = 16, - BuiltInFrontFacing = 17, - BuiltInSampleId = 18, - BuiltInSamplePosition = 19, - BuiltInSampleMask = 20, - BuiltInFragDepth = 22, - BuiltInHelperInvocation = 23, - BuiltInNumWorkgroups = 24, - BuiltInWorkgroupSize = 25, - BuiltInWorkgroupId = 26, - BuiltInLocalInvocationId = 27, - BuiltInGlobalInvocationId = 28, - BuiltInLocalInvocationIndex = 29, - BuiltInWorkDim = 30, - BuiltInGlobalSize = 31, - BuiltInEnqueuedWorkgroupSize = 32, - BuiltInGlobalOffset = 33, - BuiltInGlobalLinearId = 34, - BuiltInSubgroupSize = 36, - BuiltInSubgroupMaxSize = 37, - BuiltInNumSubgroups = 38, - BuiltInNumEnqueuedSubgroups = 39, - BuiltInSubgroupId = 40, - BuiltInSubgroupLocalInvocationId = 41, - BuiltInVertexIndex = 42, - BuiltInInstanceIndex = 43, - BuiltInSubgroupEqMask = 4416, - BuiltInSubgroupEqMaskKHR = 4416, - BuiltInSubgroupGeMask = 4417, - BuiltInSubgroupGeMaskKHR = 4417, - BuiltInSubgroupGtMask = 4418, - BuiltInSubgroupGtMaskKHR = 4418, - BuiltInSubgroupLeMask = 4419, - BuiltInSubgroupLeMaskKHR = 4419, - BuiltInSubgroupLtMask = 4420, - BuiltInSubgroupLtMaskKHR = 4420, - BuiltInBaseVertex = 4424, - BuiltInBaseInstance = 4425, - BuiltInDrawIndex = 4426, - BuiltInPrimitiveShadingRateKHR = 4432, - BuiltInDeviceIndex = 4438, - BuiltInViewIndex = 4440, - BuiltInShadingRateKHR = 4444, - BuiltInBaryCoordNoPerspAMD = 4992, - BuiltInBaryCoordNoPerspCentroidAMD = 4993, - BuiltInBaryCoordNoPerspSampleAMD = 4994, - BuiltInBaryCoordSmoothAMD = 4995, - BuiltInBaryCoordSmoothCentroidAMD = 4996, - BuiltInBaryCoordSmoothSampleAMD = 4997, - BuiltInBaryCoordPullModelAMD = 4998, - BuiltInFragStencilRefEXT = 5014, - BuiltInViewportMaskNV = 5253, - BuiltInSecondaryPositionNV = 5257, - BuiltInSecondaryViewportMaskNV = 5258, - BuiltInPositionPerViewNV = 5261, - BuiltInViewportMaskPerViewNV = 5262, - BuiltInFullyCoveredEXT = 5264, - BuiltInTaskCountNV = 5274, - BuiltInPrimitiveCountNV = 5275, - BuiltInPrimitiveIndicesNV = 5276, - BuiltInClipDistancePerViewNV = 5277, - BuiltInCullDistancePerViewNV = 5278, - BuiltInLayerPerViewNV = 5279, - BuiltInMeshViewCountNV = 5280, - BuiltInMeshViewIndicesNV = 5281, - BuiltInBaryCoordNV = 5286, - BuiltInBaryCoordNoPerspNV = 5287, - BuiltInFragSizeEXT = 5292, - BuiltInFragmentSizeNV = 5292, - BuiltInFragInvocationCountEXT = 5293, - BuiltInInvocationsPerPixelNV = 5293, - BuiltInLaunchIdKHR = 5319, - BuiltInLaunchIdNV = 5319, - BuiltInLaunchSizeKHR = 5320, - BuiltInLaunchSizeNV = 5320, - BuiltInWorldRayOriginKHR = 5321, - BuiltInWorldRayOriginNV = 5321, - BuiltInWorldRayDirectionKHR = 5322, - BuiltInWorldRayDirectionNV = 5322, - BuiltInObjectRayOriginKHR = 5323, - BuiltInObjectRayOriginNV = 5323, - BuiltInObjectRayDirectionKHR = 5324, - BuiltInObjectRayDirectionNV = 5324, - BuiltInRayTminKHR = 5325, - BuiltInRayTminNV = 5325, - BuiltInRayTmaxKHR = 5326, - BuiltInRayTmaxNV = 5326, - BuiltInInstanceCustomIndexKHR = 5327, - BuiltInInstanceCustomIndexNV = 5327, - BuiltInObjectToWorldKHR = 5330, - BuiltInObjectToWorldNV = 5330, - BuiltInWorldToObjectKHR = 5331, - BuiltInWorldToObjectNV = 5331, - BuiltInHitTNV = 5332, - BuiltInHitKindKHR = 5333, - BuiltInHitKindNV = 5333, - BuiltInCurrentRayTimeNV = 5334, - BuiltInIncomingRayFlagsKHR = 5351, - BuiltInIncomingRayFlagsNV = 5351, - BuiltInRayGeometryIndexKHR = 5352, - BuiltInWarpsPerSMNV = 5374, - BuiltInSMCountNV = 5375, - BuiltInWarpIDNV = 5376, - BuiltInSMIDNV = 5377, - BuiltInMax = 0x7fffffff, -}; - -enum SelectionControlShift { - SelectionControlFlattenShift = 0, - SelectionControlDontFlattenShift = 1, - SelectionControlMax = 0x7fffffff, -}; - -enum SelectionControlMask { - SelectionControlMaskNone = 0, - SelectionControlFlattenMask = 0x00000001, - SelectionControlDontFlattenMask = 0x00000002, -}; - -enum LoopControlShift { - LoopControlUnrollShift = 0, - LoopControlDontUnrollShift = 1, - LoopControlDependencyInfiniteShift = 2, - LoopControlDependencyLengthShift = 3, - LoopControlMinIterationsShift = 4, - LoopControlMaxIterationsShift = 5, - LoopControlIterationMultipleShift = 6, - LoopControlPeelCountShift = 7, - LoopControlPartialCountShift = 8, - LoopControlInitiationIntervalINTELShift = 16, - LoopControlMaxConcurrencyINTELShift = 17, - LoopControlDependencyArrayINTELShift = 18, - LoopControlPipelineEnableINTELShift = 19, - LoopControlLoopCoalesceINTELShift = 20, - LoopControlMaxInterleavingINTELShift = 21, - LoopControlSpeculatedIterationsINTELShift = 22, - LoopControlNoFusionINTELShift = 23, - LoopControlMax = 0x7fffffff, -}; - -enum LoopControlMask { - LoopControlMaskNone = 0, - LoopControlUnrollMask = 0x00000001, - LoopControlDontUnrollMask = 0x00000002, - LoopControlDependencyInfiniteMask = 0x00000004, - LoopControlDependencyLengthMask = 0x00000008, - LoopControlMinIterationsMask = 0x00000010, - LoopControlMaxIterationsMask = 0x00000020, - LoopControlIterationMultipleMask = 0x00000040, - LoopControlPeelCountMask = 0x00000080, - LoopControlPartialCountMask = 0x00000100, - LoopControlInitiationIntervalINTELMask = 0x00010000, - LoopControlMaxConcurrencyINTELMask = 0x00020000, - LoopControlDependencyArrayINTELMask = 0x00040000, - LoopControlPipelineEnableINTELMask = 0x00080000, - LoopControlLoopCoalesceINTELMask = 0x00100000, - LoopControlMaxInterleavingINTELMask = 0x00200000, - LoopControlSpeculatedIterationsINTELMask = 0x00400000, - LoopControlNoFusionINTELMask = 0x00800000, -}; - -enum FunctionControlShift { - FunctionControlInlineShift = 0, - FunctionControlDontInlineShift = 1, - FunctionControlPureShift = 2, - FunctionControlConstShift = 3, - FunctionControlMax = 0x7fffffff, -}; - -enum FunctionControlMask { - FunctionControlMaskNone = 0, - FunctionControlInlineMask = 0x00000001, - FunctionControlDontInlineMask = 0x00000002, - FunctionControlPureMask = 0x00000004, - FunctionControlConstMask = 0x00000008, -}; - -enum MemorySemanticsShift { - MemorySemanticsAcquireShift = 1, - MemorySemanticsReleaseShift = 2, - MemorySemanticsAcquireReleaseShift = 3, - MemorySemanticsSequentiallyConsistentShift = 4, - MemorySemanticsUniformMemoryShift = 6, - MemorySemanticsSubgroupMemoryShift = 7, - MemorySemanticsWorkgroupMemoryShift = 8, - MemorySemanticsCrossWorkgroupMemoryShift = 9, - MemorySemanticsAtomicCounterMemoryShift = 10, - MemorySemanticsImageMemoryShift = 11, - MemorySemanticsOutputMemoryShift = 12, - MemorySemanticsOutputMemoryKHRShift = 12, - MemorySemanticsMakeAvailableShift = 13, - MemorySemanticsMakeAvailableKHRShift = 13, - MemorySemanticsMakeVisibleShift = 14, - MemorySemanticsMakeVisibleKHRShift = 14, - MemorySemanticsVolatileShift = 15, - MemorySemanticsMax = 0x7fffffff, -}; - -enum MemorySemanticsMask { - MemorySemanticsMaskNone = 0, - MemorySemanticsAcquireMask = 0x00000002, - MemorySemanticsReleaseMask = 0x00000004, - MemorySemanticsAcquireReleaseMask = 0x00000008, - MemorySemanticsSequentiallyConsistentMask = 0x00000010, - MemorySemanticsUniformMemoryMask = 0x00000040, - MemorySemanticsSubgroupMemoryMask = 0x00000080, - MemorySemanticsWorkgroupMemoryMask = 0x00000100, - MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, - MemorySemanticsAtomicCounterMemoryMask = 0x00000400, - MemorySemanticsImageMemoryMask = 0x00000800, - MemorySemanticsOutputMemoryMask = 0x00001000, - MemorySemanticsOutputMemoryKHRMask = 0x00001000, - MemorySemanticsMakeAvailableMask = 0x00002000, - MemorySemanticsMakeAvailableKHRMask = 0x00002000, - MemorySemanticsMakeVisibleMask = 0x00004000, - MemorySemanticsMakeVisibleKHRMask = 0x00004000, - MemorySemanticsVolatileMask = 0x00008000, -}; - -enum MemoryAccessShift { - MemoryAccessVolatileShift = 0, - MemoryAccessAlignedShift = 1, - MemoryAccessNontemporalShift = 2, - MemoryAccessMakePointerAvailableShift = 3, - MemoryAccessMakePointerAvailableKHRShift = 3, - MemoryAccessMakePointerVisibleShift = 4, - MemoryAccessMakePointerVisibleKHRShift = 4, - MemoryAccessNonPrivatePointerShift = 5, - MemoryAccessNonPrivatePointerKHRShift = 5, - MemoryAccessMax = 0x7fffffff, -}; - -enum MemoryAccessMask { - MemoryAccessMaskNone = 0, - MemoryAccessVolatileMask = 0x00000001, - MemoryAccessAlignedMask = 0x00000002, - MemoryAccessNontemporalMask = 0x00000004, - MemoryAccessMakePointerAvailableMask = 0x00000008, - MemoryAccessMakePointerAvailableKHRMask = 0x00000008, - MemoryAccessMakePointerVisibleMask = 0x00000010, - MemoryAccessMakePointerVisibleKHRMask = 0x00000010, - MemoryAccessNonPrivatePointerMask = 0x00000020, - MemoryAccessNonPrivatePointerKHRMask = 0x00000020, -}; - -enum Scope { - ScopeCrossDevice = 0, - ScopeDevice = 1, - ScopeWorkgroup = 2, - ScopeSubgroup = 3, - ScopeInvocation = 4, - ScopeQueueFamily = 5, - ScopeQueueFamilyKHR = 5, - ScopeShaderCallKHR = 6, - ScopeMax = 0x7fffffff, -}; - -enum GroupOperation { - GroupOperationReduce = 0, - GroupOperationInclusiveScan = 1, - GroupOperationExclusiveScan = 2, - GroupOperationClusteredReduce = 3, - GroupOperationPartitionedReduceNV = 6, - GroupOperationPartitionedInclusiveScanNV = 7, - GroupOperationPartitionedExclusiveScanNV = 8, - GroupOperationMax = 0x7fffffff, -}; - -enum KernelEnqueueFlags { - KernelEnqueueFlagsNoWait = 0, - KernelEnqueueFlagsWaitKernel = 1, - KernelEnqueueFlagsWaitWorkGroup = 2, - KernelEnqueueFlagsMax = 0x7fffffff, -}; - -enum KernelProfilingInfoShift { - KernelProfilingInfoCmdExecTimeShift = 0, - KernelProfilingInfoMax = 0x7fffffff, -}; - -enum KernelProfilingInfoMask { - KernelProfilingInfoMaskNone = 0, - KernelProfilingInfoCmdExecTimeMask = 0x00000001, -}; - -enum Capability { - CapabilityMatrix = 0, - CapabilityShader = 1, - CapabilityGeometry = 2, - CapabilityTessellation = 3, - CapabilityAddresses = 4, - CapabilityLinkage = 5, - CapabilityKernel = 6, - CapabilityVector16 = 7, - CapabilityFloat16Buffer = 8, - CapabilityFloat16 = 9, - CapabilityFloat64 = 10, - CapabilityInt64 = 11, - CapabilityInt64Atomics = 12, - CapabilityImageBasic = 13, - CapabilityImageReadWrite = 14, - CapabilityImageMipmap = 15, - CapabilityPipes = 17, - CapabilityGroups = 18, - CapabilityDeviceEnqueue = 19, - CapabilityLiteralSampler = 20, - CapabilityAtomicStorage = 21, - CapabilityInt16 = 22, - CapabilityTessellationPointSize = 23, - CapabilityGeometryPointSize = 24, - CapabilityImageGatherExtended = 25, - CapabilityStorageImageMultisample = 27, - CapabilityUniformBufferArrayDynamicIndexing = 28, - CapabilitySampledImageArrayDynamicIndexing = 29, - CapabilityStorageBufferArrayDynamicIndexing = 30, - CapabilityStorageImageArrayDynamicIndexing = 31, - CapabilityClipDistance = 32, - CapabilityCullDistance = 33, - CapabilityImageCubeArray = 34, - CapabilitySampleRateShading = 35, - CapabilityImageRect = 36, - CapabilitySampledRect = 37, - CapabilityGenericPointer = 38, - CapabilityInt8 = 39, - CapabilityInputAttachment = 40, - CapabilitySparseResidency = 41, - CapabilityMinLod = 42, - CapabilitySampled1D = 43, - CapabilityImage1D = 44, - CapabilitySampledCubeArray = 45, - CapabilitySampledBuffer = 46, - CapabilityImageBuffer = 47, - CapabilityImageMSArray = 48, - CapabilityStorageImageExtendedFormats = 49, - CapabilityImageQuery = 50, - CapabilityDerivativeControl = 51, - CapabilityInterpolationFunction = 52, - CapabilityTransformFeedback = 53, - CapabilityGeometryStreams = 54, - CapabilityStorageImageReadWithoutFormat = 55, - CapabilityStorageImageWriteWithoutFormat = 56, - CapabilityMultiViewport = 57, - CapabilitySubgroupDispatch = 58, - CapabilityNamedBarrier = 59, - CapabilityPipeStorage = 60, - CapabilityGroupNonUniform = 61, - CapabilityGroupNonUniformVote = 62, - CapabilityGroupNonUniformArithmetic = 63, - CapabilityGroupNonUniformBallot = 64, - CapabilityGroupNonUniformShuffle = 65, - CapabilityGroupNonUniformShuffleRelative = 66, - CapabilityGroupNonUniformClustered = 67, - CapabilityGroupNonUniformQuad = 68, - CapabilityShaderLayer = 69, - CapabilityShaderViewportIndex = 70, - CapabilityFragmentShadingRateKHR = 4422, - CapabilitySubgroupBallotKHR = 4423, - CapabilityDrawParameters = 4427, - CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, - CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, - CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, - CapabilitySubgroupVoteKHR = 4431, - CapabilityStorageBuffer16BitAccess = 4433, - CapabilityStorageUniformBufferBlock16 = 4433, - CapabilityStorageUniform16 = 4434, - CapabilityUniformAndStorageBuffer16BitAccess = 4434, - CapabilityStoragePushConstant16 = 4435, - CapabilityStorageInputOutput16 = 4436, - CapabilityDeviceGroup = 4437, - CapabilityMultiView = 4439, - CapabilityVariablePointersStorageBuffer = 4441, - CapabilityVariablePointers = 4442, - CapabilityAtomicStorageOps = 4445, - CapabilitySampleMaskPostDepthCoverage = 4447, - CapabilityStorageBuffer8BitAccess = 4448, - CapabilityUniformAndStorageBuffer8BitAccess = 4449, - CapabilityStoragePushConstant8 = 4450, - CapabilityDenormPreserve = 4464, - CapabilityDenormFlushToZero = 4465, - CapabilitySignedZeroInfNanPreserve = 4466, - CapabilityRoundingModeRTE = 4467, - CapabilityRoundingModeRTZ = 4468, - CapabilityRayQueryProvisionalKHR = 4471, - CapabilityRayQueryKHR = 4472, - CapabilityRayTraversalPrimitiveCullingKHR = 4478, - CapabilityRayTracingKHR = 4479, - CapabilityFloat16ImageAMD = 5008, - CapabilityImageGatherBiasLodAMD = 5009, - CapabilityFragmentMaskAMD = 5010, - CapabilityStencilExportEXT = 5013, - CapabilityImageReadWriteLodAMD = 5015, - CapabilityInt64ImageEXT = 5016, - CapabilityShaderClockKHR = 5055, - CapabilitySampleMaskOverrideCoverageNV = 5249, - CapabilityGeometryShaderPassthroughNV = 5251, - CapabilityShaderViewportIndexLayerEXT = 5254, - CapabilityShaderViewportIndexLayerNV = 5254, - CapabilityShaderViewportMaskNV = 5255, - CapabilityShaderStereoViewNV = 5259, - CapabilityPerViewAttributesNV = 5260, - CapabilityFragmentFullyCoveredEXT = 5265, - CapabilityMeshShadingNV = 5266, - CapabilityImageFootprintNV = 5282, - CapabilityFragmentBarycentricNV = 5284, - CapabilityComputeDerivativeGroupQuadsNV = 5288, - CapabilityFragmentDensityEXT = 5291, - CapabilityShadingRateNV = 5291, - CapabilityGroupNonUniformPartitionedNV = 5297, - CapabilityShaderNonUniform = 5301, - CapabilityShaderNonUniformEXT = 5301, - CapabilityRuntimeDescriptorArray = 5302, - CapabilityRuntimeDescriptorArrayEXT = 5302, - CapabilityInputAttachmentArrayDynamicIndexing = 5303, - CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, - CapabilityUniformTexelBufferArrayDynamicIndexing = 5304, - CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, - CapabilityStorageTexelBufferArrayDynamicIndexing = 5305, - CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, - CapabilityUniformBufferArrayNonUniformIndexing = 5306, - CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, - CapabilitySampledImageArrayNonUniformIndexing = 5307, - CapabilitySampledImageArrayNonUniformIndexingEXT = 5307, - CapabilityStorageBufferArrayNonUniformIndexing = 5308, - CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, - CapabilityStorageImageArrayNonUniformIndexing = 5309, - CapabilityStorageImageArrayNonUniformIndexingEXT = 5309, - CapabilityInputAttachmentArrayNonUniformIndexing = 5310, - CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, - CapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, - CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, - CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, - CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, - CapabilityRayTracingNV = 5340, - CapabilityRayTracingMotionBlurNV = 5341, - CapabilityVulkanMemoryModel = 5345, - CapabilityVulkanMemoryModelKHR = 5345, - CapabilityVulkanMemoryModelDeviceScope = 5346, - CapabilityVulkanMemoryModelDeviceScopeKHR = 5346, - CapabilityPhysicalStorageBufferAddresses = 5347, - CapabilityPhysicalStorageBufferAddressesEXT = 5347, - CapabilityComputeDerivativeGroupLinearNV = 5350, - CapabilityRayTracingProvisionalKHR = 5353, - CapabilityCooperativeMatrixNV = 5357, - CapabilityFragmentShaderSampleInterlockEXT = 5363, - CapabilityFragmentShaderShadingRateInterlockEXT = 5372, - CapabilityShaderSMBuiltinsNV = 5373, - CapabilityFragmentShaderPixelInterlockEXT = 5378, - CapabilityDemoteToHelperInvocation = 5379, - CapabilityDemoteToHelperInvocationEXT = 5379, - CapabilitySubgroupShuffleINTEL = 5568, - CapabilitySubgroupBufferBlockIOINTEL = 5569, - CapabilitySubgroupImageBlockIOINTEL = 5570, - CapabilitySubgroupImageMediaBlockIOINTEL = 5579, - CapabilityRoundToInfinityINTEL = 5582, - CapabilityFloatingPointModeINTEL = 5583, - CapabilityIntegerFunctions2INTEL = 5584, - CapabilityFunctionPointersINTEL = 5603, - CapabilityIndirectReferencesINTEL = 5604, - CapabilityAsmINTEL = 5606, - CapabilityAtomicFloat32MinMaxEXT = 5612, - CapabilityAtomicFloat64MinMaxEXT = 5613, - CapabilityAtomicFloat16MinMaxEXT = 5616, - CapabilityVectorComputeINTEL = 5617, - CapabilityVectorAnyINTEL = 5619, - CapabilityExpectAssumeKHR = 5629, - CapabilitySubgroupAvcMotionEstimationINTEL = 5696, - CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, - CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, - CapabilityVariableLengthArrayINTEL = 5817, - CapabilityFunctionFloatControlINTEL = 5821, - CapabilityFPGAMemoryAttributesINTEL = 5824, - CapabilityFPFastMathModeINTEL = 5837, - CapabilityArbitraryPrecisionIntegersINTEL = 5844, - CapabilityUnstructuredLoopControlsINTEL = 5886, - CapabilityFPGALoopControlsINTEL = 5888, - CapabilityKernelAttributesINTEL = 5892, - CapabilityFPGAKernelAttributesINTEL = 5897, - CapabilityFPGAMemoryAccessesINTEL = 5898, - CapabilityFPGAClusterAttributesINTEL = 5904, - CapabilityLoopFuseINTEL = 5906, - CapabilityFPGABufferLocationINTEL = 5920, - CapabilityUSMStorageClassesINTEL = 5935, - CapabilityIOPipesINTEL = 5943, - CapabilityBlockingPipesINTEL = 5945, - CapabilityFPGARegINTEL = 5948, - CapabilityAtomicFloat32AddEXT = 6033, - CapabilityAtomicFloat64AddEXT = 6034, - CapabilityLongConstantCompositeINTEL = 6089, - CapabilityAtomicFloat16AddEXT = 6095, - CapabilityMax = 0x7fffffff, -}; - -enum RayFlagsShift { - RayFlagsOpaqueKHRShift = 0, - RayFlagsNoOpaqueKHRShift = 1, - RayFlagsTerminateOnFirstHitKHRShift = 2, - RayFlagsSkipClosestHitShaderKHRShift = 3, - RayFlagsCullBackFacingTrianglesKHRShift = 4, - RayFlagsCullFrontFacingTrianglesKHRShift = 5, - RayFlagsCullOpaqueKHRShift = 6, - RayFlagsCullNoOpaqueKHRShift = 7, - RayFlagsSkipTrianglesKHRShift = 8, - RayFlagsSkipAABBsKHRShift = 9, - RayFlagsMax = 0x7fffffff, -}; - -enum RayFlagsMask { - RayFlagsMaskNone = 0, - RayFlagsOpaqueKHRMask = 0x00000001, - RayFlagsNoOpaqueKHRMask = 0x00000002, - RayFlagsTerminateOnFirstHitKHRMask = 0x00000004, - RayFlagsSkipClosestHitShaderKHRMask = 0x00000008, - RayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, - RayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, - RayFlagsCullOpaqueKHRMask = 0x00000040, - RayFlagsCullNoOpaqueKHRMask = 0x00000080, - RayFlagsSkipTrianglesKHRMask = 0x00000100, - RayFlagsSkipAABBsKHRMask = 0x00000200, -}; - -enum RayQueryIntersection { - RayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, - RayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, - RayQueryIntersectionMax = 0x7fffffff, -}; - -enum RayQueryCommittedIntersectionType { - RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, - RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, - RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, - RayQueryCommittedIntersectionTypeMax = 0x7fffffff, -}; - -enum RayQueryCandidateIntersectionType { - RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, - RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, - RayQueryCandidateIntersectionTypeMax = 0x7fffffff, -}; - -enum FragmentShadingRateShift { - FragmentShadingRateVertical2PixelsShift = 0, - FragmentShadingRateVertical4PixelsShift = 1, - FragmentShadingRateHorizontal2PixelsShift = 2, - FragmentShadingRateHorizontal4PixelsShift = 3, - FragmentShadingRateMax = 0x7fffffff, -}; - -enum FragmentShadingRateMask { - FragmentShadingRateMaskNone = 0, - FragmentShadingRateVertical2PixelsMask = 0x00000001, - FragmentShadingRateVertical4PixelsMask = 0x00000002, - FragmentShadingRateHorizontal2PixelsMask = 0x00000004, - FragmentShadingRateHorizontal4PixelsMask = 0x00000008, -}; - -enum FPDenormMode { - FPDenormModePreserve = 0, - FPDenormModeFlushToZero = 1, - FPDenormModeMax = 0x7fffffff, -}; - -enum FPOperationMode { - FPOperationModeIEEE = 0, - FPOperationModeALT = 1, - FPOperationModeMax = 0x7fffffff, -}; - -enum Op { - OpNop = 0, - OpUndef = 1, - OpSourceContinued = 2, - OpSource = 3, - OpSourceExtension = 4, - OpName = 5, - OpMemberName = 6, - OpString = 7, - OpLine = 8, - OpExtension = 10, - OpExtInstImport = 11, - OpExtInst = 12, - OpMemoryModel = 14, - OpEntryPoint = 15, - OpExecutionMode = 16, - OpCapability = 17, - OpTypeVoid = 19, - OpTypeBool = 20, - OpTypeInt = 21, - OpTypeFloat = 22, - OpTypeVector = 23, - OpTypeMatrix = 24, - OpTypeImage = 25, - OpTypeSampler = 26, - OpTypeSampledImage = 27, - OpTypeArray = 28, - OpTypeRuntimeArray = 29, - OpTypeStruct = 30, - OpTypeOpaque = 31, - OpTypePointer = 32, - OpTypeFunction = 33, - OpTypeEvent = 34, - OpTypeDeviceEvent = 35, - OpTypeReserveId = 36, - OpTypeQueue = 37, - OpTypePipe = 38, - OpTypeForwardPointer = 39, - OpConstantTrue = 41, - OpConstantFalse = 42, - OpConstant = 43, - OpConstantComposite = 44, - OpConstantSampler = 45, - OpConstantNull = 46, - OpSpecConstantTrue = 48, - OpSpecConstantFalse = 49, - OpSpecConstant = 50, - OpSpecConstantComposite = 51, - OpSpecConstantOp = 52, - OpFunction = 54, - OpFunctionParameter = 55, - OpFunctionEnd = 56, - OpFunctionCall = 57, - OpVariable = 59, - OpImageTexelPointer = 60, - OpLoad = 61, - OpStore = 62, - OpCopyMemory = 63, - OpCopyMemorySized = 64, - OpAccessChain = 65, - OpInBoundsAccessChain = 66, - OpPtrAccessChain = 67, - OpArrayLength = 68, - OpGenericPtrMemSemantics = 69, - OpInBoundsPtrAccessChain = 70, - OpDecorate = 71, - OpMemberDecorate = 72, - OpDecorationGroup = 73, - OpGroupDecorate = 74, - OpGroupMemberDecorate = 75, - OpVectorExtractDynamic = 77, - OpVectorInsertDynamic = 78, - OpVectorShuffle = 79, - OpCompositeConstruct = 80, - OpCompositeExtract = 81, - OpCompositeInsert = 82, - OpCopyObject = 83, - OpTranspose = 84, - OpSampledImage = 86, - OpImageSampleImplicitLod = 87, - OpImageSampleExplicitLod = 88, - OpImageSampleDrefImplicitLod = 89, - OpImageSampleDrefExplicitLod = 90, - OpImageSampleProjImplicitLod = 91, - OpImageSampleProjExplicitLod = 92, - OpImageSampleProjDrefImplicitLod = 93, - OpImageSampleProjDrefExplicitLod = 94, - OpImageFetch = 95, - OpImageGather = 96, - OpImageDrefGather = 97, - OpImageRead = 98, - OpImageWrite = 99, - OpImage = 100, - OpImageQueryFormat = 101, - OpImageQueryOrder = 102, - OpImageQuerySizeLod = 103, - OpImageQuerySize = 104, - OpImageQueryLod = 105, - OpImageQueryLevels = 106, - OpImageQuerySamples = 107, - OpConvertFToU = 109, - OpConvertFToS = 110, - OpConvertSToF = 111, - OpConvertUToF = 112, - OpUConvert = 113, - OpSConvert = 114, - OpFConvert = 115, - OpQuantizeToF16 = 116, - OpConvertPtrToU = 117, - OpSatConvertSToU = 118, - OpSatConvertUToS = 119, - OpConvertUToPtr = 120, - OpPtrCastToGeneric = 121, - OpGenericCastToPtr = 122, - OpGenericCastToPtrExplicit = 123, - OpBitcast = 124, - OpSNegate = 126, - OpFNegate = 127, - OpIAdd = 128, - OpFAdd = 129, - OpISub = 130, - OpFSub = 131, - OpIMul = 132, - OpFMul = 133, - OpUDiv = 134, - OpSDiv = 135, - OpFDiv = 136, - OpUMod = 137, - OpSRem = 138, - OpSMod = 139, - OpFRem = 140, - OpFMod = 141, - OpVectorTimesScalar = 142, - OpMatrixTimesScalar = 143, - OpVectorTimesMatrix = 144, - OpMatrixTimesVector = 145, - OpMatrixTimesMatrix = 146, - OpOuterProduct = 147, - OpDot = 148, - OpIAddCarry = 149, - OpISubBorrow = 150, - OpUMulExtended = 151, - OpSMulExtended = 152, - OpAny = 154, - OpAll = 155, - OpIsNan = 156, - OpIsInf = 157, - OpIsFinite = 158, - OpIsNormal = 159, - OpSignBitSet = 160, - OpLessOrGreater = 161, - OpOrdered = 162, - OpUnordered = 163, - OpLogicalEqual = 164, - OpLogicalNotEqual = 165, - OpLogicalOr = 166, - OpLogicalAnd = 167, - OpLogicalNot = 168, - OpSelect = 169, - OpIEqual = 170, - OpINotEqual = 171, - OpUGreaterThan = 172, - OpSGreaterThan = 173, - OpUGreaterThanEqual = 174, - OpSGreaterThanEqual = 175, - OpULessThan = 176, - OpSLessThan = 177, - OpULessThanEqual = 178, - OpSLessThanEqual = 179, - OpFOrdEqual = 180, - OpFUnordEqual = 181, - OpFOrdNotEqual = 182, - OpFUnordNotEqual = 183, - OpFOrdLessThan = 184, - OpFUnordLessThan = 185, - OpFOrdGreaterThan = 186, - OpFUnordGreaterThan = 187, - OpFOrdLessThanEqual = 188, - OpFUnordLessThanEqual = 189, - OpFOrdGreaterThanEqual = 190, - OpFUnordGreaterThanEqual = 191, - OpShiftRightLogical = 194, - OpShiftRightArithmetic = 195, - OpShiftLeftLogical = 196, - OpBitwiseOr = 197, - OpBitwiseXor = 198, - OpBitwiseAnd = 199, - OpNot = 200, - OpBitFieldInsert = 201, - OpBitFieldSExtract = 202, - OpBitFieldUExtract = 203, - OpBitReverse = 204, - OpBitCount = 205, - OpDPdx = 207, - OpDPdy = 208, - OpFwidth = 209, - OpDPdxFine = 210, - OpDPdyFine = 211, - OpFwidthFine = 212, - OpDPdxCoarse = 213, - OpDPdyCoarse = 214, - OpFwidthCoarse = 215, - OpEmitVertex = 218, - OpEndPrimitive = 219, - OpEmitStreamVertex = 220, - OpEndStreamPrimitive = 221, - OpControlBarrier = 224, - OpMemoryBarrier = 225, - OpAtomicLoad = 227, - OpAtomicStore = 228, - OpAtomicExchange = 229, - OpAtomicCompareExchange = 230, - OpAtomicCompareExchangeWeak = 231, - OpAtomicIIncrement = 232, - OpAtomicIDecrement = 233, - OpAtomicIAdd = 234, - OpAtomicISub = 235, - OpAtomicSMin = 236, - OpAtomicUMin = 237, - OpAtomicSMax = 238, - OpAtomicUMax = 239, - OpAtomicAnd = 240, - OpAtomicOr = 241, - OpAtomicXor = 242, - OpPhi = 245, - OpLoopMerge = 246, - OpSelectionMerge = 247, - OpLabel = 248, - OpBranch = 249, - OpBranchConditional = 250, - OpSwitch = 251, - OpKill = 252, - OpReturn = 253, - OpReturnValue = 254, - OpUnreachable = 255, - OpLifetimeStart = 256, - OpLifetimeStop = 257, - OpGroupAsyncCopy = 259, - OpGroupWaitEvents = 260, - OpGroupAll = 261, - OpGroupAny = 262, - OpGroupBroadcast = 263, - OpGroupIAdd = 264, - OpGroupFAdd = 265, - OpGroupFMin = 266, - OpGroupUMin = 267, - OpGroupSMin = 268, - OpGroupFMax = 269, - OpGroupUMax = 270, - OpGroupSMax = 271, - OpReadPipe = 274, - OpWritePipe = 275, - OpReservedReadPipe = 276, - OpReservedWritePipe = 277, - OpReserveReadPipePackets = 278, - OpReserveWritePipePackets = 279, - OpCommitReadPipe = 280, - OpCommitWritePipe = 281, - OpIsValidReserveId = 282, - OpGetNumPipePackets = 283, - OpGetMaxPipePackets = 284, - OpGroupReserveReadPipePackets = 285, - OpGroupReserveWritePipePackets = 286, - OpGroupCommitReadPipe = 287, - OpGroupCommitWritePipe = 288, - OpEnqueueMarker = 291, - OpEnqueueKernel = 292, - OpGetKernelNDrangeSubGroupCount = 293, - OpGetKernelNDrangeMaxSubGroupSize = 294, - OpGetKernelWorkGroupSize = 295, - OpGetKernelPreferredWorkGroupSizeMultiple = 296, - OpRetainEvent = 297, - OpReleaseEvent = 298, - OpCreateUserEvent = 299, - OpIsValidEvent = 300, - OpSetUserEventStatus = 301, - OpCaptureEventProfilingInfo = 302, - OpGetDefaultQueue = 303, - OpBuildNDRange = 304, - OpImageSparseSampleImplicitLod = 305, - OpImageSparseSampleExplicitLod = 306, - OpImageSparseSampleDrefImplicitLod = 307, - OpImageSparseSampleDrefExplicitLod = 308, - OpImageSparseSampleProjImplicitLod = 309, - OpImageSparseSampleProjExplicitLod = 310, - OpImageSparseSampleProjDrefImplicitLod = 311, - OpImageSparseSampleProjDrefExplicitLod = 312, - OpImageSparseFetch = 313, - OpImageSparseGather = 314, - OpImageSparseDrefGather = 315, - OpImageSparseTexelsResident = 316, - OpNoLine = 317, - OpAtomicFlagTestAndSet = 318, - OpAtomicFlagClear = 319, - OpImageSparseRead = 320, - OpSizeOf = 321, - OpTypePipeStorage = 322, - OpConstantPipeStorage = 323, - OpCreatePipeFromPipeStorage = 324, - OpGetKernelLocalSizeForSubgroupCount = 325, - OpGetKernelMaxNumSubgroups = 326, - OpTypeNamedBarrier = 327, - OpNamedBarrierInitialize = 328, - OpMemoryNamedBarrier = 329, - OpModuleProcessed = 330, - OpExecutionModeId = 331, - OpDecorateId = 332, - OpGroupNonUniformElect = 333, - OpGroupNonUniformAll = 334, - OpGroupNonUniformAny = 335, - OpGroupNonUniformAllEqual = 336, - OpGroupNonUniformBroadcast = 337, - OpGroupNonUniformBroadcastFirst = 338, - OpGroupNonUniformBallot = 339, - OpGroupNonUniformInverseBallot = 340, - OpGroupNonUniformBallotBitExtract = 341, - OpGroupNonUniformBallotBitCount = 342, - OpGroupNonUniformBallotFindLSB = 343, - OpGroupNonUniformBallotFindMSB = 344, - OpGroupNonUniformShuffle = 345, - OpGroupNonUniformShuffleXor = 346, - OpGroupNonUniformShuffleUp = 347, - OpGroupNonUniformShuffleDown = 348, - OpGroupNonUniformIAdd = 349, - OpGroupNonUniformFAdd = 350, - OpGroupNonUniformIMul = 351, - OpGroupNonUniformFMul = 352, - OpGroupNonUniformSMin = 353, - OpGroupNonUniformUMin = 354, - OpGroupNonUniformFMin = 355, - OpGroupNonUniformSMax = 356, - OpGroupNonUniformUMax = 357, - OpGroupNonUniformFMax = 358, - OpGroupNonUniformBitwiseAnd = 359, - OpGroupNonUniformBitwiseOr = 360, - OpGroupNonUniformBitwiseXor = 361, - OpGroupNonUniformLogicalAnd = 362, - OpGroupNonUniformLogicalOr = 363, - OpGroupNonUniformLogicalXor = 364, - OpGroupNonUniformQuadBroadcast = 365, - OpGroupNonUniformQuadSwap = 366, - OpCopyLogical = 400, - OpPtrEqual = 401, - OpPtrNotEqual = 402, - OpPtrDiff = 403, - OpTerminateInvocation = 4416, - OpSubgroupBallotKHR = 4421, - OpSubgroupFirstInvocationKHR = 4422, - OpSubgroupAllKHR = 4428, - OpSubgroupAnyKHR = 4429, - OpSubgroupAllEqualKHR = 4430, - OpSubgroupReadInvocationKHR = 4432, - OpTraceRayKHR = 4445, - OpExecuteCallableKHR = 4446, - OpConvertUToAccelerationStructureKHR = 4447, - OpIgnoreIntersectionKHR = 4448, - OpTerminateRayKHR = 4449, - OpTypeRayQueryKHR = 4472, - OpRayQueryInitializeKHR = 4473, - OpRayQueryTerminateKHR = 4474, - OpRayQueryGenerateIntersectionKHR = 4475, - OpRayQueryConfirmIntersectionKHR = 4476, - OpRayQueryProceedKHR = 4477, - OpRayQueryGetIntersectionTypeKHR = 4479, - OpGroupIAddNonUniformAMD = 5000, - OpGroupFAddNonUniformAMD = 5001, - OpGroupFMinNonUniformAMD = 5002, - OpGroupUMinNonUniformAMD = 5003, - OpGroupSMinNonUniformAMD = 5004, - OpGroupFMaxNonUniformAMD = 5005, - OpGroupUMaxNonUniformAMD = 5006, - OpGroupSMaxNonUniformAMD = 5007, - OpFragmentMaskFetchAMD = 5011, - OpFragmentFetchAMD = 5012, - OpReadClockKHR = 5056, - OpImageSampleFootprintNV = 5283, - OpGroupNonUniformPartitionNV = 5296, - OpWritePackedPrimitiveIndices4x8NV = 5299, - OpReportIntersectionKHR = 5334, - OpReportIntersectionNV = 5334, - OpIgnoreIntersectionNV = 5335, - OpTerminateRayNV = 5336, - OpTraceNV = 5337, - OpTraceMotionNV = 5338, - OpTraceRayMotionNV = 5339, - OpTypeAccelerationStructureKHR = 5341, - OpTypeAccelerationStructureNV = 5341, - OpExecuteCallableNV = 5344, - OpTypeCooperativeMatrixNV = 5358, - OpCooperativeMatrixLoadNV = 5359, - OpCooperativeMatrixStoreNV = 5360, - OpCooperativeMatrixMulAddNV = 5361, - OpCooperativeMatrixLengthNV = 5362, - OpBeginInvocationInterlockEXT = 5364, - OpEndInvocationInterlockEXT = 5365, - OpDemoteToHelperInvocationEXT = 5380, - OpIsHelperInvocationEXT = 5381, - OpSubgroupShuffleINTEL = 5571, - OpSubgroupShuffleDownINTEL = 5572, - OpSubgroupShuffleUpINTEL = 5573, - OpSubgroupShuffleXorINTEL = 5574, - OpSubgroupBlockReadINTEL = 5575, - OpSubgroupBlockWriteINTEL = 5576, - OpSubgroupImageBlockReadINTEL = 5577, - OpSubgroupImageBlockWriteINTEL = 5578, - OpSubgroupImageMediaBlockReadINTEL = 5580, - OpSubgroupImageMediaBlockWriteINTEL = 5581, - OpUCountLeadingZerosINTEL = 5585, - OpUCountTrailingZerosINTEL = 5586, - OpAbsISubINTEL = 5587, - OpAbsUSubINTEL = 5588, - OpIAddSatINTEL = 5589, - OpUAddSatINTEL = 5590, - OpIAverageINTEL = 5591, - OpUAverageINTEL = 5592, - OpIAverageRoundedINTEL = 5593, - OpUAverageRoundedINTEL = 5594, - OpISubSatINTEL = 5595, - OpUSubSatINTEL = 5596, - OpIMul32x16INTEL = 5597, - OpUMul32x16INTEL = 5598, - OpConstFunctionPointerINTEL = 5600, - OpFunctionPointerCallINTEL = 5601, - OpAsmTargetINTEL = 5609, - OpAsmINTEL = 5610, - OpAsmCallINTEL = 5611, - OpAtomicFMinEXT = 5614, - OpAtomicFMaxEXT = 5615, - OpAssumeTrueKHR = 5630, - OpExpectKHR = 5631, - OpDecorateString = 5632, - OpDecorateStringGOOGLE = 5632, - OpMemberDecorateString = 5633, - OpMemberDecorateStringGOOGLE = 5633, - OpVmeImageINTEL = 5699, - OpTypeVmeImageINTEL = 5700, - OpTypeAvcImePayloadINTEL = 5701, - OpTypeAvcRefPayloadINTEL = 5702, - OpTypeAvcSicPayloadINTEL = 5703, - OpTypeAvcMcePayloadINTEL = 5704, - OpTypeAvcMceResultINTEL = 5705, - OpTypeAvcImeResultINTEL = 5706, - OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, - OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, - OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, - OpTypeAvcImeDualReferenceStreaminINTEL = 5710, - OpTypeAvcRefResultINTEL = 5711, - OpTypeAvcSicResultINTEL = 5712, - OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, - OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, - OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, - OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, - OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, - OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, - OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, - OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, - OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, - OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, - OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, - OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, - OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, - OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, - OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, - OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, - OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, - OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, - OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, - OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, - OpSubgroupAvcMceConvertToImeResultINTEL = 5733, - OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, - OpSubgroupAvcMceConvertToRefResultINTEL = 5735, - OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, - OpSubgroupAvcMceConvertToSicResultINTEL = 5737, - OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, - OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, - OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, - OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, - OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, - OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, - OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, - OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, - OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, - OpSubgroupAvcImeInitializeINTEL = 5747, - OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, - OpSubgroupAvcImeSetDualReferenceINTEL = 5749, - OpSubgroupAvcImeRefWindowSizeINTEL = 5750, - OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, - OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, - OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, - OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, - OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, - OpSubgroupAvcImeSetWeightedSadINTEL = 5756, - OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, - OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, - OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, - OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, - OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, - OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, - OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, - OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, - OpSubgroupAvcImeConvertToMceResultINTEL = 5765, - OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, - OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, - OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, - OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, - OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, - OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, - OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, - OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, - OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, - OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, - OpSubgroupAvcImeGetBorderReachedINTEL = 5776, - OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, - OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, - OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, - OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, - OpSubgroupAvcFmeInitializeINTEL = 5781, - OpSubgroupAvcBmeInitializeINTEL = 5782, - OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, - OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, - OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, - OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, - OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, - OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, - OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, - OpSubgroupAvcRefConvertToMceResultINTEL = 5790, - OpSubgroupAvcSicInitializeINTEL = 5791, - OpSubgroupAvcSicConfigureSkcINTEL = 5792, - OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, - OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, - OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, - OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, - OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, - OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, - OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, - OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, - OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, - OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, - OpSubgroupAvcSicEvaluateIpeINTEL = 5803, - OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, - OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, - OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, - OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, - OpSubgroupAvcSicConvertToMceResultINTEL = 5808, - OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, - OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, - OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, - OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, - OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, - OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, - OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, - OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, - OpVariableLengthArrayINTEL = 5818, - OpSaveMemoryINTEL = 5819, - OpRestoreMemoryINTEL = 5820, - OpLoopControlINTEL = 5887, - OpPtrCastToCrossWorkgroupINTEL = 5934, - OpCrossWorkgroupCastToPtrINTEL = 5938, - OpReadPipeBlockingINTEL = 5946, - OpWritePipeBlockingINTEL = 5947, - OpFPGARegINTEL = 5949, - OpRayQueryGetRayTMinKHR = 6016, - OpRayQueryGetRayFlagsKHR = 6017, - OpRayQueryGetIntersectionTKHR = 6018, - OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, - OpRayQueryGetIntersectionInstanceIdKHR = 6020, - OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, - OpRayQueryGetIntersectionGeometryIndexKHR = 6022, - OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, - OpRayQueryGetIntersectionBarycentricsKHR = 6024, - OpRayQueryGetIntersectionFrontFaceKHR = 6025, - OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, - OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, - OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, - OpRayQueryGetWorldRayDirectionKHR = 6029, - OpRayQueryGetWorldRayOriginKHR = 6030, - OpRayQueryGetIntersectionObjectToWorldKHR = 6031, - OpRayQueryGetIntersectionWorldToObjectKHR = 6032, - OpAtomicFAddEXT = 6035, - OpTypeBufferSurfaceINTEL = 6086, - OpTypeStructContinuedINTEL = 6090, - OpConstantCompositeContinuedINTEL = 6091, - OpSpecConstantCompositeContinuedINTEL = 6092, - OpMax = 0x7fffffff, -}; - -#ifdef SPV_ENABLE_UTILITY_CODE -inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { - *hasResult = *hasResultType = false; - switch (opcode) { - default: /* unknown opcode */ break; - case OpNop: *hasResult = false; *hasResultType = false; break; - case OpUndef: *hasResult = true; *hasResultType = true; break; - case OpSourceContinued: *hasResult = false; *hasResultType = false; break; - case OpSource: *hasResult = false; *hasResultType = false; break; - case OpSourceExtension: *hasResult = false; *hasResultType = false; break; - case OpName: *hasResult = false; *hasResultType = false; break; - case OpMemberName: *hasResult = false; *hasResultType = false; break; - case OpString: *hasResult = true; *hasResultType = false; break; - case OpLine: *hasResult = false; *hasResultType = false; break; - case OpExtension: *hasResult = false; *hasResultType = false; break; - case OpExtInstImport: *hasResult = true; *hasResultType = false; break; - case OpExtInst: *hasResult = true; *hasResultType = true; break; - case OpMemoryModel: *hasResult = false; *hasResultType = false; break; - case OpEntryPoint: *hasResult = false; *hasResultType = false; break; - case OpExecutionMode: *hasResult = false; *hasResultType = false; break; - case OpCapability: *hasResult = false; *hasResultType = false; break; - case OpTypeVoid: *hasResult = true; *hasResultType = false; break; - case OpTypeBool: *hasResult = true; *hasResultType = false; break; - case OpTypeInt: *hasResult = true; *hasResultType = false; break; - case OpTypeFloat: *hasResult = true; *hasResultType = false; break; - case OpTypeVector: *hasResult = true; *hasResultType = false; break; - case OpTypeMatrix: *hasResult = true; *hasResultType = false; break; - case OpTypeImage: *hasResult = true; *hasResultType = false; break; - case OpTypeSampler: *hasResult = true; *hasResultType = false; break; - case OpTypeSampledImage: *hasResult = true; *hasResultType = false; break; - case OpTypeArray: *hasResult = true; *hasResultType = false; break; - case OpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; - case OpTypeStruct: *hasResult = true; *hasResultType = false; break; - case OpTypeOpaque: *hasResult = true; *hasResultType = false; break; - case OpTypePointer: *hasResult = true; *hasResultType = false; break; - case OpTypeFunction: *hasResult = true; *hasResultType = false; break; - case OpTypeEvent: *hasResult = true; *hasResultType = false; break; - case OpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; - case OpTypeReserveId: *hasResult = true; *hasResultType = false; break; - case OpTypeQueue: *hasResult = true; *hasResultType = false; break; - case OpTypePipe: *hasResult = true; *hasResultType = false; break; - case OpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; - case OpConstantTrue: *hasResult = true; *hasResultType = true; break; - case OpConstantFalse: *hasResult = true; *hasResultType = true; break; - case OpConstant: *hasResult = true; *hasResultType = true; break; - case OpConstantComposite: *hasResult = true; *hasResultType = true; break; - case OpConstantSampler: *hasResult = true; *hasResultType = true; break; - case OpConstantNull: *hasResult = true; *hasResultType = true; break; - case OpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; - case OpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; - case OpSpecConstant: *hasResult = true; *hasResultType = true; break; - case OpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; - case OpSpecConstantOp: *hasResult = true; *hasResultType = true; break; - case OpFunction: *hasResult = true; *hasResultType = true; break; - case OpFunctionParameter: *hasResult = true; *hasResultType = true; break; - case OpFunctionEnd: *hasResult = false; *hasResultType = false; break; - case OpFunctionCall: *hasResult = true; *hasResultType = true; break; - case OpVariable: *hasResult = true; *hasResultType = true; break; - case OpImageTexelPointer: *hasResult = true; *hasResultType = true; break; - case OpLoad: *hasResult = true; *hasResultType = true; break; - case OpStore: *hasResult = false; *hasResultType = false; break; - case OpCopyMemory: *hasResult = false; *hasResultType = false; break; - case OpCopyMemorySized: *hasResult = false; *hasResultType = false; break; - case OpAccessChain: *hasResult = true; *hasResultType = true; break; - case OpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; - case OpPtrAccessChain: *hasResult = true; *hasResultType = true; break; - case OpArrayLength: *hasResult = true; *hasResultType = true; break; - case OpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; - case OpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; - case OpDecorate: *hasResult = false; *hasResultType = false; break; - case OpMemberDecorate: *hasResult = false; *hasResultType = false; break; - case OpDecorationGroup: *hasResult = true; *hasResultType = false; break; - case OpGroupDecorate: *hasResult = false; *hasResultType = false; break; - case OpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; - case OpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; - case OpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; - case OpVectorShuffle: *hasResult = true; *hasResultType = true; break; - case OpCompositeConstruct: *hasResult = true; *hasResultType = true; break; - case OpCompositeExtract: *hasResult = true; *hasResultType = true; break; - case OpCompositeInsert: *hasResult = true; *hasResultType = true; break; - case OpCopyObject: *hasResult = true; *hasResultType = true; break; - case OpTranspose: *hasResult = true; *hasResultType = true; break; - case OpSampledImage: *hasResult = true; *hasResultType = true; break; - case OpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageFetch: *hasResult = true; *hasResultType = true; break; - case OpImageGather: *hasResult = true; *hasResultType = true; break; - case OpImageDrefGather: *hasResult = true; *hasResultType = true; break; - case OpImageRead: *hasResult = true; *hasResultType = true; break; - case OpImageWrite: *hasResult = false; *hasResultType = false; break; - case OpImage: *hasResult = true; *hasResultType = true; break; - case OpImageQueryFormat: *hasResult = true; *hasResultType = true; break; - case OpImageQueryOrder: *hasResult = true; *hasResultType = true; break; - case OpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; - case OpImageQuerySize: *hasResult = true; *hasResultType = true; break; - case OpImageQueryLod: *hasResult = true; *hasResultType = true; break; - case OpImageQueryLevels: *hasResult = true; *hasResultType = true; break; - case OpImageQuerySamples: *hasResult = true; *hasResultType = true; break; - case OpConvertFToU: *hasResult = true; *hasResultType = true; break; - case OpConvertFToS: *hasResult = true; *hasResultType = true; break; - case OpConvertSToF: *hasResult = true; *hasResultType = true; break; - case OpConvertUToF: *hasResult = true; *hasResultType = true; break; - case OpUConvert: *hasResult = true; *hasResultType = true; break; - case OpSConvert: *hasResult = true; *hasResultType = true; break; - case OpFConvert: *hasResult = true; *hasResultType = true; break; - case OpQuantizeToF16: *hasResult = true; *hasResultType = true; break; - case OpConvertPtrToU: *hasResult = true; *hasResultType = true; break; - case OpSatConvertSToU: *hasResult = true; *hasResultType = true; break; - case OpSatConvertUToS: *hasResult = true; *hasResultType = true; break; - case OpConvertUToPtr: *hasResult = true; *hasResultType = true; break; - case OpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; - case OpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; - case OpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; - case OpBitcast: *hasResult = true; *hasResultType = true; break; - case OpSNegate: *hasResult = true; *hasResultType = true; break; - case OpFNegate: *hasResult = true; *hasResultType = true; break; - case OpIAdd: *hasResult = true; *hasResultType = true; break; - case OpFAdd: *hasResult = true; *hasResultType = true; break; - case OpISub: *hasResult = true; *hasResultType = true; break; - case OpFSub: *hasResult = true; *hasResultType = true; break; - case OpIMul: *hasResult = true; *hasResultType = true; break; - case OpFMul: *hasResult = true; *hasResultType = true; break; - case OpUDiv: *hasResult = true; *hasResultType = true; break; - case OpSDiv: *hasResult = true; *hasResultType = true; break; - case OpFDiv: *hasResult = true; *hasResultType = true; break; - case OpUMod: *hasResult = true; *hasResultType = true; break; - case OpSRem: *hasResult = true; *hasResultType = true; break; - case OpSMod: *hasResult = true; *hasResultType = true; break; - case OpFRem: *hasResult = true; *hasResultType = true; break; - case OpFMod: *hasResult = true; *hasResultType = true; break; - case OpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; - case OpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; - case OpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; - case OpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; - case OpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; - case OpOuterProduct: *hasResult = true; *hasResultType = true; break; - case OpDot: *hasResult = true; *hasResultType = true; break; - case OpIAddCarry: *hasResult = true; *hasResultType = true; break; - case OpISubBorrow: *hasResult = true; *hasResultType = true; break; - case OpUMulExtended: *hasResult = true; *hasResultType = true; break; - case OpSMulExtended: *hasResult = true; *hasResultType = true; break; - case OpAny: *hasResult = true; *hasResultType = true; break; - case OpAll: *hasResult = true; *hasResultType = true; break; - case OpIsNan: *hasResult = true; *hasResultType = true; break; - case OpIsInf: *hasResult = true; *hasResultType = true; break; - case OpIsFinite: *hasResult = true; *hasResultType = true; break; - case OpIsNormal: *hasResult = true; *hasResultType = true; break; - case OpSignBitSet: *hasResult = true; *hasResultType = true; break; - case OpLessOrGreater: *hasResult = true; *hasResultType = true; break; - case OpOrdered: *hasResult = true; *hasResultType = true; break; - case OpUnordered: *hasResult = true; *hasResultType = true; break; - case OpLogicalEqual: *hasResult = true; *hasResultType = true; break; - case OpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; - case OpLogicalOr: *hasResult = true; *hasResultType = true; break; - case OpLogicalAnd: *hasResult = true; *hasResultType = true; break; - case OpLogicalNot: *hasResult = true; *hasResultType = true; break; - case OpSelect: *hasResult = true; *hasResultType = true; break; - case OpIEqual: *hasResult = true; *hasResultType = true; break; - case OpINotEqual: *hasResult = true; *hasResultType = true; break; - case OpUGreaterThan: *hasResult = true; *hasResultType = true; break; - case OpSGreaterThan: *hasResult = true; *hasResultType = true; break; - case OpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case OpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case OpULessThan: *hasResult = true; *hasResultType = true; break; - case OpSLessThan: *hasResult = true; *hasResultType = true; break; - case OpULessThanEqual: *hasResult = true; *hasResultType = true; break; - case OpSLessThanEqual: *hasResult = true; *hasResultType = true; break; - case OpFOrdEqual: *hasResult = true; *hasResultType = true; break; - case OpFUnordEqual: *hasResult = true; *hasResultType = true; break; - case OpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; - case OpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; - case OpFOrdLessThan: *hasResult = true; *hasResultType = true; break; - case OpFUnordLessThan: *hasResult = true; *hasResultType = true; break; - case OpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; - case OpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; - case OpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; - case OpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; - case OpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case OpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case OpShiftRightLogical: *hasResult = true; *hasResultType = true; break; - case OpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; - case OpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; - case OpBitwiseOr: *hasResult = true; *hasResultType = true; break; - case OpBitwiseXor: *hasResult = true; *hasResultType = true; break; - case OpBitwiseAnd: *hasResult = true; *hasResultType = true; break; - case OpNot: *hasResult = true; *hasResultType = true; break; - case OpBitFieldInsert: *hasResult = true; *hasResultType = true; break; - case OpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; - case OpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; - case OpBitReverse: *hasResult = true; *hasResultType = true; break; - case OpBitCount: *hasResult = true; *hasResultType = true; break; - case OpDPdx: *hasResult = true; *hasResultType = true; break; - case OpDPdy: *hasResult = true; *hasResultType = true; break; - case OpFwidth: *hasResult = true; *hasResultType = true; break; - case OpDPdxFine: *hasResult = true; *hasResultType = true; break; - case OpDPdyFine: *hasResult = true; *hasResultType = true; break; - case OpFwidthFine: *hasResult = true; *hasResultType = true; break; - case OpDPdxCoarse: *hasResult = true; *hasResultType = true; break; - case OpDPdyCoarse: *hasResult = true; *hasResultType = true; break; - case OpFwidthCoarse: *hasResult = true; *hasResultType = true; break; - case OpEmitVertex: *hasResult = false; *hasResultType = false; break; - case OpEndPrimitive: *hasResult = false; *hasResultType = false; break; - case OpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; - case OpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; - case OpControlBarrier: *hasResult = false; *hasResultType = false; break; - case OpMemoryBarrier: *hasResult = false; *hasResultType = false; break; - case OpAtomicLoad: *hasResult = true; *hasResultType = true; break; - case OpAtomicStore: *hasResult = false; *hasResultType = false; break; - case OpAtomicExchange: *hasResult = true; *hasResultType = true; break; - case OpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; - case OpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; - case OpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; - case OpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; - case OpAtomicIAdd: *hasResult = true; *hasResultType = true; break; - case OpAtomicISub: *hasResult = true; *hasResultType = true; break; - case OpAtomicSMin: *hasResult = true; *hasResultType = true; break; - case OpAtomicUMin: *hasResult = true; *hasResultType = true; break; - case OpAtomicSMax: *hasResult = true; *hasResultType = true; break; - case OpAtomicUMax: *hasResult = true; *hasResultType = true; break; - case OpAtomicAnd: *hasResult = true; *hasResultType = true; break; - case OpAtomicOr: *hasResult = true; *hasResultType = true; break; - case OpAtomicXor: *hasResult = true; *hasResultType = true; break; - case OpPhi: *hasResult = true; *hasResultType = true; break; - case OpLoopMerge: *hasResult = false; *hasResultType = false; break; - case OpSelectionMerge: *hasResult = false; *hasResultType = false; break; - case OpLabel: *hasResult = true; *hasResultType = false; break; - case OpBranch: *hasResult = false; *hasResultType = false; break; - case OpBranchConditional: *hasResult = false; *hasResultType = false; break; - case OpSwitch: *hasResult = false; *hasResultType = false; break; - case OpKill: *hasResult = false; *hasResultType = false; break; - case OpReturn: *hasResult = false; *hasResultType = false; break; - case OpReturnValue: *hasResult = false; *hasResultType = false; break; - case OpUnreachable: *hasResult = false; *hasResultType = false; break; - case OpLifetimeStart: *hasResult = false; *hasResultType = false; break; - case OpLifetimeStop: *hasResult = false; *hasResultType = false; break; - case OpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; - case OpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; - case OpGroupAll: *hasResult = true; *hasResultType = true; break; - case OpGroupAny: *hasResult = true; *hasResultType = true; break; - case OpGroupBroadcast: *hasResult = true; *hasResultType = true; break; - case OpGroupIAdd: *hasResult = true; *hasResultType = true; break; - case OpGroupFAdd: *hasResult = true; *hasResultType = true; break; - case OpGroupFMin: *hasResult = true; *hasResultType = true; break; - case OpGroupUMin: *hasResult = true; *hasResultType = true; break; - case OpGroupSMin: *hasResult = true; *hasResultType = true; break; - case OpGroupFMax: *hasResult = true; *hasResultType = true; break; - case OpGroupUMax: *hasResult = true; *hasResultType = true; break; - case OpGroupSMax: *hasResult = true; *hasResultType = true; break; - case OpReadPipe: *hasResult = true; *hasResultType = true; break; - case OpWritePipe: *hasResult = true; *hasResultType = true; break; - case OpReservedReadPipe: *hasResult = true; *hasResultType = true; break; - case OpReservedWritePipe: *hasResult = true; *hasResultType = true; break; - case OpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; - case OpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; - case OpCommitReadPipe: *hasResult = false; *hasResultType = false; break; - case OpCommitWritePipe: *hasResult = false; *hasResultType = false; break; - case OpIsValidReserveId: *hasResult = true; *hasResultType = true; break; - case OpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; - case OpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; - case OpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; - case OpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; - case OpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; - case OpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; - case OpEnqueueMarker: *hasResult = true; *hasResultType = true; break; - case OpEnqueueKernel: *hasResult = true; *hasResultType = true; break; - case OpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; - case OpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; - case OpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; - case OpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; - case OpRetainEvent: *hasResult = false; *hasResultType = false; break; - case OpReleaseEvent: *hasResult = false; *hasResultType = false; break; - case OpCreateUserEvent: *hasResult = true; *hasResultType = true; break; - case OpIsValidEvent: *hasResult = true; *hasResultType = true; break; - case OpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; - case OpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; - case OpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; - case OpBuildNDRange: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case OpImageSparseFetch: *hasResult = true; *hasResultType = true; break; - case OpImageSparseGather: *hasResult = true; *hasResultType = true; break; - case OpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; - case OpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; - case OpNoLine: *hasResult = false; *hasResultType = false; break; - case OpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; - case OpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; - case OpImageSparseRead: *hasResult = true; *hasResultType = true; break; - case OpSizeOf: *hasResult = true; *hasResultType = true; break; - case OpTypePipeStorage: *hasResult = true; *hasResultType = false; break; - case OpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; - case OpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; - case OpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; - case OpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; - case OpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; - case OpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; - case OpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; - case OpModuleProcessed: *hasResult = false; *hasResultType = false; break; - case OpExecutionModeId: *hasResult = false; *hasResultType = false; break; - case OpDecorateId: *hasResult = false; *hasResultType = false; break; - case OpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; - case OpCopyLogical: *hasResult = true; *hasResultType = true; break; - case OpPtrEqual: *hasResult = true; *hasResultType = true; break; - case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break; - case OpPtrDiff: *hasResult = true; *hasResultType = true; break; - case OpTerminateInvocation: *hasResult = false; *hasResultType = false; break; - case OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; - case OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; - case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; - case OpTraceRayKHR: *hasResult = false; *hasResultType = false; break; - case OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; - case OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; - case OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; - case OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; - case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; - case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; - case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; - case OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; - case OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; - case OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; - case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; - case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; - case OpReadClockKHR: *hasResult = true; *hasResultType = true; break; - case OpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; - case OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; - case OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; - case OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; - case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; - case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break; - case OpTraceNV: *hasResult = false; *hasResultType = false; break; - case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break; - case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; - case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; - case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; - case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; - case OpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; - case OpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; - case OpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; - case OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; - case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; - case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; - case OpDemoteToHelperInvocationEXT: *hasResult = false; *hasResultType = false; break; - case OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; - case OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; - case OpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; - case OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; - case OpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; - case OpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; - case OpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; - case OpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; - case OpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; - case OpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; - case OpIAverageINTEL: *hasResult = true; *hasResultType = true; break; - case OpUAverageINTEL: *hasResult = true; *hasResultType = true; break; - case OpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; - case OpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; - case OpISubSatINTEL: *hasResult = true; *hasResultType = true; break; - case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; - case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; - case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; - case OpConstFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; - case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; - case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; - case OpAsmINTEL: *hasResult = true; *hasResultType = true; break; - case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; - case OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; - case OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; - case OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; - case OpExpectKHR: *hasResult = true; *hasResultType = true; break; - case OpDecorateString: *hasResult = false; *hasResultType = false; break; - case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; - case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; - case OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; - case OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; - case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; - case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; - case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; - case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; - case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; - case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; - case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; - case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; - case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; - case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; - case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; - case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; - case OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; - case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; - case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; - case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; - } -} -#endif /* SPV_ENABLE_UTILITY_CODE */ - -// Overload operator| for mask bit combining - -inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } -inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } -inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } -inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } -inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } -inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } -inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } -inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } -inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); } -inline FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); } - -} // end namespace spv - -#endif // #ifndef spirv_HPP +// Copyright (c) 2014-2020 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. + +// This header is automatically generated by the same tool that creates +// the Binary Section of the SPIR-V specification. + +// Enumeration tokens for SPIR-V, in various styles: +// C, C++, C++11, JSON, Lua, Python, C#, D, Beef +// +// - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL +// - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL +// - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL +// - Lua will use tables, e.g.: spv.SourceLanguage.GLSL +// - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] +// - C# will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +// - Beef will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL +// +// Some tokens act like mask values, which can be OR'd together, +// while others are mutually exclusive. The mask-like ones have +// "Mask" in their name, and a parallel enum that has the shift +// amount (1 << x) for each corresponding enumerant. + +#ifndef spirv_HPP +#define spirv_HPP + +namespace spv { + +typedef unsigned int Id; + +#define SPV_VERSION 0x10600 +#define SPV_REVISION 1 + +static const unsigned int MagicNumber = 0x07230203; +static const unsigned int Version = 0x00010600; +static const unsigned int Revision = 1; +static const unsigned int OpCodeMask = 0xffff; +static const unsigned int WordCountShift = 16; + +enum SourceLanguage { + SourceLanguageUnknown = 0, + SourceLanguageESSL = 1, + SourceLanguageGLSL = 2, + SourceLanguageOpenCL_C = 3, + SourceLanguageOpenCL_CPP = 4, + SourceLanguageHLSL = 5, + SourceLanguageCPP_for_OpenCL = 6, + SourceLanguageSYCL = 7, + SourceLanguageMax = 0x7fffffff, +}; + +enum ExecutionModel { + ExecutionModelVertex = 0, + ExecutionModelTessellationControl = 1, + ExecutionModelTessellationEvaluation = 2, + ExecutionModelGeometry = 3, + ExecutionModelFragment = 4, + ExecutionModelGLCompute = 5, + ExecutionModelKernel = 6, + ExecutionModelTaskNV = 5267, + ExecutionModelMeshNV = 5268, + ExecutionModelRayGenerationKHR = 5313, + ExecutionModelRayGenerationNV = 5313, + ExecutionModelIntersectionKHR = 5314, + ExecutionModelIntersectionNV = 5314, + ExecutionModelAnyHitKHR = 5315, + ExecutionModelAnyHitNV = 5315, + ExecutionModelClosestHitKHR = 5316, + ExecutionModelClosestHitNV = 5316, + ExecutionModelMissKHR = 5317, + ExecutionModelMissNV = 5317, + ExecutionModelCallableKHR = 5318, + ExecutionModelCallableNV = 5318, + ExecutionModelTaskEXT = 5364, + ExecutionModelMeshEXT = 5365, + ExecutionModelMax = 0x7fffffff, +}; + +enum AddressingModel { + AddressingModelLogical = 0, + AddressingModelPhysical32 = 1, + AddressingModelPhysical64 = 2, + AddressingModelPhysicalStorageBuffer64 = 5348, + AddressingModelPhysicalStorageBuffer64EXT = 5348, + AddressingModelMax = 0x7fffffff, +}; + +enum MemoryModel { + MemoryModelSimple = 0, + MemoryModelGLSL450 = 1, + MemoryModelOpenCL = 2, + MemoryModelVulkan = 3, + MemoryModelVulkanKHR = 3, + MemoryModelMax = 0x7fffffff, +}; + +enum ExecutionMode { + ExecutionModeInvocations = 0, + ExecutionModeSpacingEqual = 1, + ExecutionModeSpacingFractionalEven = 2, + ExecutionModeSpacingFractionalOdd = 3, + ExecutionModeVertexOrderCw = 4, + ExecutionModeVertexOrderCcw = 5, + ExecutionModePixelCenterInteger = 6, + ExecutionModeOriginUpperLeft = 7, + ExecutionModeOriginLowerLeft = 8, + ExecutionModeEarlyFragmentTests = 9, + ExecutionModePointMode = 10, + ExecutionModeXfb = 11, + ExecutionModeDepthReplacing = 12, + ExecutionModeDepthGreater = 14, + ExecutionModeDepthLess = 15, + ExecutionModeDepthUnchanged = 16, + ExecutionModeLocalSize = 17, + ExecutionModeLocalSizeHint = 18, + ExecutionModeInputPoints = 19, + ExecutionModeInputLines = 20, + ExecutionModeInputLinesAdjacency = 21, + ExecutionModeTriangles = 22, + ExecutionModeInputTrianglesAdjacency = 23, + ExecutionModeQuads = 24, + ExecutionModeIsolines = 25, + ExecutionModeOutputVertices = 26, + ExecutionModeOutputPoints = 27, + ExecutionModeOutputLineStrip = 28, + ExecutionModeOutputTriangleStrip = 29, + ExecutionModeVecTypeHint = 30, + ExecutionModeContractionOff = 31, + ExecutionModeInitializer = 33, + ExecutionModeFinalizer = 34, + ExecutionModeSubgroupSize = 35, + ExecutionModeSubgroupsPerWorkgroup = 36, + ExecutionModeSubgroupsPerWorkgroupId = 37, + ExecutionModeLocalSizeId = 38, + ExecutionModeLocalSizeHintId = 39, + ExecutionModeNonCoherentColorAttachmentReadEXT = 4169, + ExecutionModeNonCoherentDepthAttachmentReadEXT = 4170, + ExecutionModeNonCoherentStencilAttachmentReadEXT = 4171, + ExecutionModeSubgroupUniformControlFlowKHR = 4421, + ExecutionModePostDepthCoverage = 4446, + ExecutionModeDenormPreserve = 4459, + ExecutionModeDenormFlushToZero = 4460, + ExecutionModeSignedZeroInfNanPreserve = 4461, + ExecutionModeRoundingModeRTE = 4462, + ExecutionModeRoundingModeRTZ = 4463, + ExecutionModeEarlyAndLateFragmentTestsAMD = 5017, + ExecutionModeStencilRefReplacingEXT = 5027, + ExecutionModeStencilRefUnchangedFrontAMD = 5079, + ExecutionModeStencilRefGreaterFrontAMD = 5080, + ExecutionModeStencilRefLessFrontAMD = 5081, + ExecutionModeStencilRefUnchangedBackAMD = 5082, + ExecutionModeStencilRefGreaterBackAMD = 5083, + ExecutionModeStencilRefLessBackAMD = 5084, + ExecutionModeOutputLinesEXT = 5269, + ExecutionModeOutputLinesNV = 5269, + ExecutionModeOutputPrimitivesEXT = 5270, + ExecutionModeOutputPrimitivesNV = 5270, + ExecutionModeDerivativeGroupQuadsNV = 5289, + ExecutionModeDerivativeGroupLinearNV = 5290, + ExecutionModeOutputTrianglesEXT = 5298, + ExecutionModeOutputTrianglesNV = 5298, + ExecutionModePixelInterlockOrderedEXT = 5366, + ExecutionModePixelInterlockUnorderedEXT = 5367, + ExecutionModeSampleInterlockOrderedEXT = 5368, + ExecutionModeSampleInterlockUnorderedEXT = 5369, + ExecutionModeShadingRateInterlockOrderedEXT = 5370, + ExecutionModeShadingRateInterlockUnorderedEXT = 5371, + ExecutionModeSharedLocalMemorySizeINTEL = 5618, + ExecutionModeRoundingModeRTPINTEL = 5620, + ExecutionModeRoundingModeRTNINTEL = 5621, + ExecutionModeFloatingPointModeALTINTEL = 5622, + ExecutionModeFloatingPointModeIEEEINTEL = 5623, + ExecutionModeMaxWorkgroupSizeINTEL = 5893, + ExecutionModeMaxWorkDimINTEL = 5894, + ExecutionModeNoGlobalOffsetINTEL = 5895, + ExecutionModeNumSIMDWorkitemsINTEL = 5896, + ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, + ExecutionModeStreamingInterfaceINTEL = 6154, + ExecutionModeNamedBarrierCountINTEL = 6417, + ExecutionModeMax = 0x7fffffff, +}; + +enum StorageClass { + StorageClassUniformConstant = 0, + StorageClassInput = 1, + StorageClassUniform = 2, + StorageClassOutput = 3, + StorageClassWorkgroup = 4, + StorageClassCrossWorkgroup = 5, + StorageClassPrivate = 6, + StorageClassFunction = 7, + StorageClassGeneric = 8, + StorageClassPushConstant = 9, + StorageClassAtomicCounter = 10, + StorageClassImage = 11, + StorageClassStorageBuffer = 12, + StorageClassTileImageEXT = 4172, + StorageClassCallableDataKHR = 5328, + StorageClassCallableDataNV = 5328, + StorageClassIncomingCallableDataKHR = 5329, + StorageClassIncomingCallableDataNV = 5329, + StorageClassRayPayloadKHR = 5338, + StorageClassRayPayloadNV = 5338, + StorageClassHitAttributeKHR = 5339, + StorageClassHitAttributeNV = 5339, + StorageClassIncomingRayPayloadKHR = 5342, + StorageClassIncomingRayPayloadNV = 5342, + StorageClassShaderRecordBufferKHR = 5343, + StorageClassShaderRecordBufferNV = 5343, + StorageClassPhysicalStorageBuffer = 5349, + StorageClassPhysicalStorageBufferEXT = 5349, + StorageClassHitObjectAttributeNV = 5385, + StorageClassTaskPayloadWorkgroupEXT = 5402, + StorageClassCodeSectionINTEL = 5605, + StorageClassDeviceOnlyINTEL = 5936, + StorageClassHostOnlyINTEL = 5937, + StorageClassMax = 0x7fffffff, +}; + +enum Dim { + Dim1D = 0, + Dim2D = 1, + Dim3D = 2, + DimCube = 3, + DimRect = 4, + DimBuffer = 5, + DimSubpassData = 6, + DimTileImageDataEXT = 4173, + DimMax = 0x7fffffff, +}; + +enum SamplerAddressingMode { + SamplerAddressingModeNone = 0, + SamplerAddressingModeClampToEdge = 1, + SamplerAddressingModeClamp = 2, + SamplerAddressingModeRepeat = 3, + SamplerAddressingModeRepeatMirrored = 4, + SamplerAddressingModeMax = 0x7fffffff, +}; + +enum SamplerFilterMode { + SamplerFilterModeNearest = 0, + SamplerFilterModeLinear = 1, + SamplerFilterModeMax = 0x7fffffff, +}; + +enum ImageFormat { + ImageFormatUnknown = 0, + ImageFormatRgba32f = 1, + ImageFormatRgba16f = 2, + ImageFormatR32f = 3, + ImageFormatRgba8 = 4, + ImageFormatRgba8Snorm = 5, + ImageFormatRg32f = 6, + ImageFormatRg16f = 7, + ImageFormatR11fG11fB10f = 8, + ImageFormatR16f = 9, + ImageFormatRgba16 = 10, + ImageFormatRgb10A2 = 11, + ImageFormatRg16 = 12, + ImageFormatRg8 = 13, + ImageFormatR16 = 14, + ImageFormatR8 = 15, + ImageFormatRgba16Snorm = 16, + ImageFormatRg16Snorm = 17, + ImageFormatRg8Snorm = 18, + ImageFormatR16Snorm = 19, + ImageFormatR8Snorm = 20, + ImageFormatRgba32i = 21, + ImageFormatRgba16i = 22, + ImageFormatRgba8i = 23, + ImageFormatR32i = 24, + ImageFormatRg32i = 25, + ImageFormatRg16i = 26, + ImageFormatRg8i = 27, + ImageFormatR16i = 28, + ImageFormatR8i = 29, + ImageFormatRgba32ui = 30, + ImageFormatRgba16ui = 31, + ImageFormatRgba8ui = 32, + ImageFormatR32ui = 33, + ImageFormatRgb10a2ui = 34, + ImageFormatRg32ui = 35, + ImageFormatRg16ui = 36, + ImageFormatRg8ui = 37, + ImageFormatR16ui = 38, + ImageFormatR8ui = 39, + ImageFormatR64ui = 40, + ImageFormatR64i = 41, + ImageFormatMax = 0x7fffffff, +}; + +enum ImageChannelOrder { + ImageChannelOrderR = 0, + ImageChannelOrderA = 1, + ImageChannelOrderRG = 2, + ImageChannelOrderRA = 3, + ImageChannelOrderRGB = 4, + ImageChannelOrderRGBA = 5, + ImageChannelOrderBGRA = 6, + ImageChannelOrderARGB = 7, + ImageChannelOrderIntensity = 8, + ImageChannelOrderLuminance = 9, + ImageChannelOrderRx = 10, + ImageChannelOrderRGx = 11, + ImageChannelOrderRGBx = 12, + ImageChannelOrderDepth = 13, + ImageChannelOrderDepthStencil = 14, + ImageChannelOrdersRGB = 15, + ImageChannelOrdersRGBx = 16, + ImageChannelOrdersRGBA = 17, + ImageChannelOrdersBGRA = 18, + ImageChannelOrderABGR = 19, + ImageChannelOrderMax = 0x7fffffff, +}; + +enum ImageChannelDataType { + ImageChannelDataTypeSnormInt8 = 0, + ImageChannelDataTypeSnormInt16 = 1, + ImageChannelDataTypeUnormInt8 = 2, + ImageChannelDataTypeUnormInt16 = 3, + ImageChannelDataTypeUnormShort565 = 4, + ImageChannelDataTypeUnormShort555 = 5, + ImageChannelDataTypeUnormInt101010 = 6, + ImageChannelDataTypeSignedInt8 = 7, + ImageChannelDataTypeSignedInt16 = 8, + ImageChannelDataTypeSignedInt32 = 9, + ImageChannelDataTypeUnsignedInt8 = 10, + ImageChannelDataTypeUnsignedInt16 = 11, + ImageChannelDataTypeUnsignedInt32 = 12, + ImageChannelDataTypeHalfFloat = 13, + ImageChannelDataTypeFloat = 14, + ImageChannelDataTypeUnormInt24 = 15, + ImageChannelDataTypeUnormInt101010_2 = 16, + ImageChannelDataTypeMax = 0x7fffffff, +}; + +enum ImageOperandsShift { + ImageOperandsBiasShift = 0, + ImageOperandsLodShift = 1, + ImageOperandsGradShift = 2, + ImageOperandsConstOffsetShift = 3, + ImageOperandsOffsetShift = 4, + ImageOperandsConstOffsetsShift = 5, + ImageOperandsSampleShift = 6, + ImageOperandsMinLodShift = 7, + ImageOperandsMakeTexelAvailableShift = 8, + ImageOperandsMakeTexelAvailableKHRShift = 8, + ImageOperandsMakeTexelVisibleShift = 9, + ImageOperandsMakeTexelVisibleKHRShift = 9, + ImageOperandsNonPrivateTexelShift = 10, + ImageOperandsNonPrivateTexelKHRShift = 10, + ImageOperandsVolatileTexelShift = 11, + ImageOperandsVolatileTexelKHRShift = 11, + ImageOperandsSignExtendShift = 12, + ImageOperandsZeroExtendShift = 13, + ImageOperandsNontemporalShift = 14, + ImageOperandsOffsetsShift = 16, + ImageOperandsMax = 0x7fffffff, +}; + +enum ImageOperandsMask { + ImageOperandsMaskNone = 0, + ImageOperandsBiasMask = 0x00000001, + ImageOperandsLodMask = 0x00000002, + ImageOperandsGradMask = 0x00000004, + ImageOperandsConstOffsetMask = 0x00000008, + ImageOperandsOffsetMask = 0x00000010, + ImageOperandsConstOffsetsMask = 0x00000020, + ImageOperandsSampleMask = 0x00000040, + ImageOperandsMinLodMask = 0x00000080, + ImageOperandsMakeTexelAvailableMask = 0x00000100, + ImageOperandsMakeTexelAvailableKHRMask = 0x00000100, + ImageOperandsMakeTexelVisibleMask = 0x00000200, + ImageOperandsMakeTexelVisibleKHRMask = 0x00000200, + ImageOperandsNonPrivateTexelMask = 0x00000400, + ImageOperandsNonPrivateTexelKHRMask = 0x00000400, + ImageOperandsVolatileTexelMask = 0x00000800, + ImageOperandsVolatileTexelKHRMask = 0x00000800, + ImageOperandsSignExtendMask = 0x00001000, + ImageOperandsZeroExtendMask = 0x00002000, + ImageOperandsNontemporalMask = 0x00004000, + ImageOperandsOffsetsMask = 0x00010000, +}; + +enum FPFastMathModeShift { + FPFastMathModeNotNaNShift = 0, + FPFastMathModeNotInfShift = 1, + FPFastMathModeNSZShift = 2, + FPFastMathModeAllowRecipShift = 3, + FPFastMathModeFastShift = 4, + FPFastMathModeAllowContractFastINTELShift = 16, + FPFastMathModeAllowReassocINTELShift = 17, + FPFastMathModeMax = 0x7fffffff, +}; + +enum FPFastMathModeMask { + FPFastMathModeMaskNone = 0, + FPFastMathModeNotNaNMask = 0x00000001, + FPFastMathModeNotInfMask = 0x00000002, + FPFastMathModeNSZMask = 0x00000004, + FPFastMathModeAllowRecipMask = 0x00000008, + FPFastMathModeFastMask = 0x00000010, + FPFastMathModeAllowContractFastINTELMask = 0x00010000, + FPFastMathModeAllowReassocINTELMask = 0x00020000, +}; + +enum FPRoundingMode { + FPRoundingModeRTE = 0, + FPRoundingModeRTZ = 1, + FPRoundingModeRTP = 2, + FPRoundingModeRTN = 3, + FPRoundingModeMax = 0x7fffffff, +}; + +enum LinkageType { + LinkageTypeExport = 0, + LinkageTypeImport = 1, + LinkageTypeLinkOnceODR = 2, + LinkageTypeMax = 0x7fffffff, +}; + +enum AccessQualifier { + AccessQualifierReadOnly = 0, + AccessQualifierWriteOnly = 1, + AccessQualifierReadWrite = 2, + AccessQualifierMax = 0x7fffffff, +}; + +enum FunctionParameterAttribute { + FunctionParameterAttributeZext = 0, + FunctionParameterAttributeSext = 1, + FunctionParameterAttributeByVal = 2, + FunctionParameterAttributeSret = 3, + FunctionParameterAttributeNoAlias = 4, + FunctionParameterAttributeNoCapture = 5, + FunctionParameterAttributeNoWrite = 6, + FunctionParameterAttributeNoReadWrite = 7, + FunctionParameterAttributeRuntimeAlignedINTEL = 5940, + FunctionParameterAttributeMax = 0x7fffffff, +}; + +enum Decoration { + DecorationRelaxedPrecision = 0, + DecorationSpecId = 1, + DecorationBlock = 2, + DecorationBufferBlock = 3, + DecorationRowMajor = 4, + DecorationColMajor = 5, + DecorationArrayStride = 6, + DecorationMatrixStride = 7, + DecorationGLSLShared = 8, + DecorationGLSLPacked = 9, + DecorationCPacked = 10, + DecorationBuiltIn = 11, + DecorationNoPerspective = 13, + DecorationFlat = 14, + DecorationPatch = 15, + DecorationCentroid = 16, + DecorationSample = 17, + DecorationInvariant = 18, + DecorationRestrict = 19, + DecorationAliased = 20, + DecorationVolatile = 21, + DecorationConstant = 22, + DecorationCoherent = 23, + DecorationNonWritable = 24, + DecorationNonReadable = 25, + DecorationUniform = 26, + DecorationUniformId = 27, + DecorationSaturatedConversion = 28, + DecorationStream = 29, + DecorationLocation = 30, + DecorationComponent = 31, + DecorationIndex = 32, + DecorationBinding = 33, + DecorationDescriptorSet = 34, + DecorationOffset = 35, + DecorationXfbBuffer = 36, + DecorationXfbStride = 37, + DecorationFuncParamAttr = 38, + DecorationFPRoundingMode = 39, + DecorationFPFastMathMode = 40, + DecorationLinkageAttributes = 41, + DecorationNoContraction = 42, + DecorationInputAttachmentIndex = 43, + DecorationAlignment = 44, + DecorationMaxByteOffset = 45, + DecorationAlignmentId = 46, + DecorationMaxByteOffsetId = 47, + DecorationNoSignedWrap = 4469, + DecorationNoUnsignedWrap = 4470, + DecorationWeightTextureQCOM = 4487, + DecorationBlockMatchTextureQCOM = 4488, + DecorationExplicitInterpAMD = 4999, + DecorationOverrideCoverageNV = 5248, + DecorationPassthroughNV = 5250, + DecorationViewportRelativeNV = 5252, + DecorationSecondaryViewportRelativeNV = 5256, + DecorationPerPrimitiveEXT = 5271, + DecorationPerPrimitiveNV = 5271, + DecorationPerViewNV = 5272, + DecorationPerTaskNV = 5273, + DecorationPerVertexKHR = 5285, + DecorationPerVertexNV = 5285, + DecorationNonUniform = 5300, + DecorationNonUniformEXT = 5300, + DecorationRestrictPointer = 5355, + DecorationRestrictPointerEXT = 5355, + DecorationAliasedPointer = 5356, + DecorationAliasedPointerEXT = 5356, + DecorationHitObjectShaderRecordBufferNV = 5386, + DecorationBindlessSamplerNV = 5398, + DecorationBindlessImageNV = 5399, + DecorationBoundSamplerNV = 5400, + DecorationBoundImageNV = 5401, + DecorationSIMTCallINTEL = 5599, + DecorationReferencedIndirectlyINTEL = 5602, + DecorationClobberINTEL = 5607, + DecorationSideEffectsINTEL = 5608, + DecorationVectorComputeVariableINTEL = 5624, + DecorationFuncParamIOKindINTEL = 5625, + DecorationVectorComputeFunctionINTEL = 5626, + DecorationStackCallINTEL = 5627, + DecorationGlobalVariableOffsetINTEL = 5628, + DecorationCounterBuffer = 5634, + DecorationHlslCounterBufferGOOGLE = 5634, + DecorationHlslSemanticGOOGLE = 5635, + DecorationUserSemantic = 5635, + DecorationUserTypeGOOGLE = 5636, + DecorationFunctionRoundingModeINTEL = 5822, + DecorationFunctionDenormModeINTEL = 5823, + DecorationRegisterINTEL = 5825, + DecorationMemoryINTEL = 5826, + DecorationNumbanksINTEL = 5827, + DecorationBankwidthINTEL = 5828, + DecorationMaxPrivateCopiesINTEL = 5829, + DecorationSinglepumpINTEL = 5830, + DecorationDoublepumpINTEL = 5831, + DecorationMaxReplicatesINTEL = 5832, + DecorationSimpleDualPortINTEL = 5833, + DecorationMergeINTEL = 5834, + DecorationBankBitsINTEL = 5835, + DecorationForcePow2DepthINTEL = 5836, + DecorationBurstCoalesceINTEL = 5899, + DecorationCacheSizeINTEL = 5900, + DecorationDontStaticallyCoalesceINTEL = 5901, + DecorationPrefetchINTEL = 5902, + DecorationStallEnableINTEL = 5905, + DecorationFuseLoopsInFunctionINTEL = 5907, + DecorationMathOpDSPModeINTEL = 5909, + DecorationAliasScopeINTEL = 5914, + DecorationNoAliasINTEL = 5915, + DecorationInitiationIntervalINTEL = 5917, + DecorationMaxConcurrencyINTEL = 5918, + DecorationPipelineEnableINTEL = 5919, + DecorationBufferLocationINTEL = 5921, + DecorationIOPipeStorageINTEL = 5944, + DecorationFunctionFloatingPointModeINTEL = 6080, + DecorationSingleElementVectorINTEL = 6085, + DecorationVectorComputeCallableFunctionINTEL = 6087, + DecorationMediaBlockIOINTEL = 6140, + DecorationConduitKernelArgumentINTEL = 6175, + DecorationRegisterMapKernelArgumentINTEL = 6176, + DecorationMMHostInterfaceAddressWidthINTEL = 6177, + DecorationMMHostInterfaceDataWidthINTEL = 6178, + DecorationMMHostInterfaceLatencyINTEL = 6179, + DecorationMMHostInterfaceReadWriteModeINTEL = 6180, + DecorationMMHostInterfaceMaxBurstINTEL = 6181, + DecorationMMHostInterfaceWaitRequestINTEL = 6182, + DecorationStableKernelArgumentINTEL = 6183, + DecorationMax = 0x7fffffff, +}; + +enum BuiltIn { + BuiltInPosition = 0, + BuiltInPointSize = 1, + BuiltInClipDistance = 3, + BuiltInCullDistance = 4, + BuiltInVertexId = 5, + BuiltInInstanceId = 6, + BuiltInPrimitiveId = 7, + BuiltInInvocationId = 8, + BuiltInLayer = 9, + BuiltInViewportIndex = 10, + BuiltInTessLevelOuter = 11, + BuiltInTessLevelInner = 12, + BuiltInTessCoord = 13, + BuiltInPatchVertices = 14, + BuiltInFragCoord = 15, + BuiltInPointCoord = 16, + BuiltInFrontFacing = 17, + BuiltInSampleId = 18, + BuiltInSamplePosition = 19, + BuiltInSampleMask = 20, + BuiltInFragDepth = 22, + BuiltInHelperInvocation = 23, + BuiltInNumWorkgroups = 24, + BuiltInWorkgroupSize = 25, + BuiltInWorkgroupId = 26, + BuiltInLocalInvocationId = 27, + BuiltInGlobalInvocationId = 28, + BuiltInLocalInvocationIndex = 29, + BuiltInWorkDim = 30, + BuiltInGlobalSize = 31, + BuiltInEnqueuedWorkgroupSize = 32, + BuiltInGlobalOffset = 33, + BuiltInGlobalLinearId = 34, + BuiltInSubgroupSize = 36, + BuiltInSubgroupMaxSize = 37, + BuiltInNumSubgroups = 38, + BuiltInNumEnqueuedSubgroups = 39, + BuiltInSubgroupId = 40, + BuiltInSubgroupLocalInvocationId = 41, + BuiltInVertexIndex = 42, + BuiltInInstanceIndex = 43, + BuiltInCoreIDARM = 4160, + BuiltInCoreCountARM = 4161, + BuiltInCoreMaxIDARM = 4162, + BuiltInWarpIDARM = 4163, + BuiltInWarpMaxIDARM = 4164, + BuiltInSubgroupEqMask = 4416, + BuiltInSubgroupEqMaskKHR = 4416, + BuiltInSubgroupGeMask = 4417, + BuiltInSubgroupGeMaskKHR = 4417, + BuiltInSubgroupGtMask = 4418, + BuiltInSubgroupGtMaskKHR = 4418, + BuiltInSubgroupLeMask = 4419, + BuiltInSubgroupLeMaskKHR = 4419, + BuiltInSubgroupLtMask = 4420, + BuiltInSubgroupLtMaskKHR = 4420, + BuiltInBaseVertex = 4424, + BuiltInBaseInstance = 4425, + BuiltInDrawIndex = 4426, + BuiltInPrimitiveShadingRateKHR = 4432, + BuiltInDeviceIndex = 4438, + BuiltInViewIndex = 4440, + BuiltInShadingRateKHR = 4444, + BuiltInBaryCoordNoPerspAMD = 4992, + BuiltInBaryCoordNoPerspCentroidAMD = 4993, + BuiltInBaryCoordNoPerspSampleAMD = 4994, + BuiltInBaryCoordSmoothAMD = 4995, + BuiltInBaryCoordSmoothCentroidAMD = 4996, + BuiltInBaryCoordSmoothSampleAMD = 4997, + BuiltInBaryCoordPullModelAMD = 4998, + BuiltInFragStencilRefEXT = 5014, + BuiltInViewportMaskNV = 5253, + BuiltInSecondaryPositionNV = 5257, + BuiltInSecondaryViewportMaskNV = 5258, + BuiltInPositionPerViewNV = 5261, + BuiltInViewportMaskPerViewNV = 5262, + BuiltInFullyCoveredEXT = 5264, + BuiltInTaskCountNV = 5274, + BuiltInPrimitiveCountNV = 5275, + BuiltInPrimitiveIndicesNV = 5276, + BuiltInClipDistancePerViewNV = 5277, + BuiltInCullDistancePerViewNV = 5278, + BuiltInLayerPerViewNV = 5279, + BuiltInMeshViewCountNV = 5280, + BuiltInMeshViewIndicesNV = 5281, + BuiltInBaryCoordKHR = 5286, + BuiltInBaryCoordNV = 5286, + BuiltInBaryCoordNoPerspKHR = 5287, + BuiltInBaryCoordNoPerspNV = 5287, + BuiltInFragSizeEXT = 5292, + BuiltInFragmentSizeNV = 5292, + BuiltInFragInvocationCountEXT = 5293, + BuiltInInvocationsPerPixelNV = 5293, + BuiltInPrimitivePointIndicesEXT = 5294, + BuiltInPrimitiveLineIndicesEXT = 5295, + BuiltInPrimitiveTriangleIndicesEXT = 5296, + BuiltInCullPrimitiveEXT = 5299, + BuiltInLaunchIdKHR = 5319, + BuiltInLaunchIdNV = 5319, + BuiltInLaunchSizeKHR = 5320, + BuiltInLaunchSizeNV = 5320, + BuiltInWorldRayOriginKHR = 5321, + BuiltInWorldRayOriginNV = 5321, + BuiltInWorldRayDirectionKHR = 5322, + BuiltInWorldRayDirectionNV = 5322, + BuiltInObjectRayOriginKHR = 5323, + BuiltInObjectRayOriginNV = 5323, + BuiltInObjectRayDirectionKHR = 5324, + BuiltInObjectRayDirectionNV = 5324, + BuiltInRayTminKHR = 5325, + BuiltInRayTminNV = 5325, + BuiltInRayTmaxKHR = 5326, + BuiltInRayTmaxNV = 5326, + BuiltInInstanceCustomIndexKHR = 5327, + BuiltInInstanceCustomIndexNV = 5327, + BuiltInObjectToWorldKHR = 5330, + BuiltInObjectToWorldNV = 5330, + BuiltInWorldToObjectKHR = 5331, + BuiltInWorldToObjectNV = 5331, + BuiltInHitTNV = 5332, + BuiltInHitKindKHR = 5333, + BuiltInHitKindNV = 5333, + BuiltInCurrentRayTimeNV = 5334, + BuiltInHitTriangleVertexPositionsKHR = 5335, + BuiltInHitMicroTriangleVertexPositionsNV = 5337, + BuiltInHitMicroTriangleVertexBarycentricsNV = 5344, + BuiltInHitKindFrontFacingMicroTriangleNV = 5405, + BuiltInHitKindBackFacingMicroTriangleNV = 5406, + BuiltInIncomingRayFlagsKHR = 5351, + BuiltInIncomingRayFlagsNV = 5351, + BuiltInRayGeometryIndexKHR = 5352, + BuiltInWarpsPerSMNV = 5374, + BuiltInSMCountNV = 5375, + BuiltInWarpIDNV = 5376, + BuiltInSMIDNV = 5377, + BuiltInCullMaskKHR = 6021, + BuiltInMax = 0x7fffffff, +}; + +enum SelectionControlShift { + SelectionControlFlattenShift = 0, + SelectionControlDontFlattenShift = 1, + SelectionControlMax = 0x7fffffff, +}; + +enum SelectionControlMask { + SelectionControlMaskNone = 0, + SelectionControlFlattenMask = 0x00000001, + SelectionControlDontFlattenMask = 0x00000002, +}; + +enum LoopControlShift { + LoopControlUnrollShift = 0, + LoopControlDontUnrollShift = 1, + LoopControlDependencyInfiniteShift = 2, + LoopControlDependencyLengthShift = 3, + LoopControlMinIterationsShift = 4, + LoopControlMaxIterationsShift = 5, + LoopControlIterationMultipleShift = 6, + LoopControlPeelCountShift = 7, + LoopControlPartialCountShift = 8, + LoopControlInitiationIntervalINTELShift = 16, + LoopControlMaxConcurrencyINTELShift = 17, + LoopControlDependencyArrayINTELShift = 18, + LoopControlPipelineEnableINTELShift = 19, + LoopControlLoopCoalesceINTELShift = 20, + LoopControlMaxInterleavingINTELShift = 21, + LoopControlSpeculatedIterationsINTELShift = 22, + LoopControlNoFusionINTELShift = 23, + LoopControlLoopCountINTELShift = 24, + LoopControlMaxReinvocationDelayINTELShift = 25, + LoopControlMax = 0x7fffffff, +}; + +enum LoopControlMask { + LoopControlMaskNone = 0, + LoopControlUnrollMask = 0x00000001, + LoopControlDontUnrollMask = 0x00000002, + LoopControlDependencyInfiniteMask = 0x00000004, + LoopControlDependencyLengthMask = 0x00000008, + LoopControlMinIterationsMask = 0x00000010, + LoopControlMaxIterationsMask = 0x00000020, + LoopControlIterationMultipleMask = 0x00000040, + LoopControlPeelCountMask = 0x00000080, + LoopControlPartialCountMask = 0x00000100, + LoopControlInitiationIntervalINTELMask = 0x00010000, + LoopControlMaxConcurrencyINTELMask = 0x00020000, + LoopControlDependencyArrayINTELMask = 0x00040000, + LoopControlPipelineEnableINTELMask = 0x00080000, + LoopControlLoopCoalesceINTELMask = 0x00100000, + LoopControlMaxInterleavingINTELMask = 0x00200000, + LoopControlSpeculatedIterationsINTELMask = 0x00400000, + LoopControlNoFusionINTELMask = 0x00800000, + LoopControlLoopCountINTELMask = 0x01000000, + LoopControlMaxReinvocationDelayINTELMask = 0x02000000, +}; + +enum FunctionControlShift { + FunctionControlInlineShift = 0, + FunctionControlDontInlineShift = 1, + FunctionControlPureShift = 2, + FunctionControlConstShift = 3, + FunctionControlOptNoneINTELShift = 16, + FunctionControlMax = 0x7fffffff, +}; + +enum FunctionControlMask { + FunctionControlMaskNone = 0, + FunctionControlInlineMask = 0x00000001, + FunctionControlDontInlineMask = 0x00000002, + FunctionControlPureMask = 0x00000004, + FunctionControlConstMask = 0x00000008, + FunctionControlOptNoneINTELMask = 0x00010000, +}; + +enum MemorySemanticsShift { + MemorySemanticsAcquireShift = 1, + MemorySemanticsReleaseShift = 2, + MemorySemanticsAcquireReleaseShift = 3, + MemorySemanticsSequentiallyConsistentShift = 4, + MemorySemanticsUniformMemoryShift = 6, + MemorySemanticsSubgroupMemoryShift = 7, + MemorySemanticsWorkgroupMemoryShift = 8, + MemorySemanticsCrossWorkgroupMemoryShift = 9, + MemorySemanticsAtomicCounterMemoryShift = 10, + MemorySemanticsImageMemoryShift = 11, + MemorySemanticsOutputMemoryShift = 12, + MemorySemanticsOutputMemoryKHRShift = 12, + MemorySemanticsMakeAvailableShift = 13, + MemorySemanticsMakeAvailableKHRShift = 13, + MemorySemanticsMakeVisibleShift = 14, + MemorySemanticsMakeVisibleKHRShift = 14, + MemorySemanticsVolatileShift = 15, + MemorySemanticsMax = 0x7fffffff, +}; + +enum MemorySemanticsMask { + MemorySemanticsMaskNone = 0, + MemorySemanticsAcquireMask = 0x00000002, + MemorySemanticsReleaseMask = 0x00000004, + MemorySemanticsAcquireReleaseMask = 0x00000008, + MemorySemanticsSequentiallyConsistentMask = 0x00000010, + MemorySemanticsUniformMemoryMask = 0x00000040, + MemorySemanticsSubgroupMemoryMask = 0x00000080, + MemorySemanticsWorkgroupMemoryMask = 0x00000100, + MemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, + MemorySemanticsAtomicCounterMemoryMask = 0x00000400, + MemorySemanticsImageMemoryMask = 0x00000800, + MemorySemanticsOutputMemoryMask = 0x00001000, + MemorySemanticsOutputMemoryKHRMask = 0x00001000, + MemorySemanticsMakeAvailableMask = 0x00002000, + MemorySemanticsMakeAvailableKHRMask = 0x00002000, + MemorySemanticsMakeVisibleMask = 0x00004000, + MemorySemanticsMakeVisibleKHRMask = 0x00004000, + MemorySemanticsVolatileMask = 0x00008000, +}; + +enum MemoryAccessShift { + MemoryAccessVolatileShift = 0, + MemoryAccessAlignedShift = 1, + MemoryAccessNontemporalShift = 2, + MemoryAccessMakePointerAvailableShift = 3, + MemoryAccessMakePointerAvailableKHRShift = 3, + MemoryAccessMakePointerVisibleShift = 4, + MemoryAccessMakePointerVisibleKHRShift = 4, + MemoryAccessNonPrivatePointerShift = 5, + MemoryAccessNonPrivatePointerKHRShift = 5, + MemoryAccessAliasScopeINTELMaskShift = 16, + MemoryAccessNoAliasINTELMaskShift = 17, + MemoryAccessMax = 0x7fffffff, +}; + +enum MemoryAccessMask { + MemoryAccessMaskNone = 0, + MemoryAccessVolatileMask = 0x00000001, + MemoryAccessAlignedMask = 0x00000002, + MemoryAccessNontemporalMask = 0x00000004, + MemoryAccessMakePointerAvailableMask = 0x00000008, + MemoryAccessMakePointerAvailableKHRMask = 0x00000008, + MemoryAccessMakePointerVisibleMask = 0x00000010, + MemoryAccessMakePointerVisibleKHRMask = 0x00000010, + MemoryAccessNonPrivatePointerMask = 0x00000020, + MemoryAccessNonPrivatePointerKHRMask = 0x00000020, + MemoryAccessAliasScopeINTELMaskMask = 0x00010000, + MemoryAccessNoAliasINTELMaskMask = 0x00020000, +}; + +enum Scope { + ScopeCrossDevice = 0, + ScopeDevice = 1, + ScopeWorkgroup = 2, + ScopeSubgroup = 3, + ScopeInvocation = 4, + ScopeQueueFamily = 5, + ScopeQueueFamilyKHR = 5, + ScopeShaderCallKHR = 6, + ScopeMax = 0x7fffffff, +}; + +enum GroupOperation { + GroupOperationReduce = 0, + GroupOperationInclusiveScan = 1, + GroupOperationExclusiveScan = 2, + GroupOperationClusteredReduce = 3, + GroupOperationPartitionedReduceNV = 6, + GroupOperationPartitionedInclusiveScanNV = 7, + GroupOperationPartitionedExclusiveScanNV = 8, + GroupOperationMax = 0x7fffffff, +}; + +enum KernelEnqueueFlags { + KernelEnqueueFlagsNoWait = 0, + KernelEnqueueFlagsWaitKernel = 1, + KernelEnqueueFlagsWaitWorkGroup = 2, + KernelEnqueueFlagsMax = 0x7fffffff, +}; + +enum KernelProfilingInfoShift { + KernelProfilingInfoCmdExecTimeShift = 0, + KernelProfilingInfoMax = 0x7fffffff, +}; + +enum KernelProfilingInfoMask { + KernelProfilingInfoMaskNone = 0, + KernelProfilingInfoCmdExecTimeMask = 0x00000001, +}; + +enum Capability { + CapabilityMatrix = 0, + CapabilityShader = 1, + CapabilityGeometry = 2, + CapabilityTessellation = 3, + CapabilityAddresses = 4, + CapabilityLinkage = 5, + CapabilityKernel = 6, + CapabilityVector16 = 7, + CapabilityFloat16Buffer = 8, + CapabilityFloat16 = 9, + CapabilityFloat64 = 10, + CapabilityInt64 = 11, + CapabilityInt64Atomics = 12, + CapabilityImageBasic = 13, + CapabilityImageReadWrite = 14, + CapabilityImageMipmap = 15, + CapabilityPipes = 17, + CapabilityGroups = 18, + CapabilityDeviceEnqueue = 19, + CapabilityLiteralSampler = 20, + CapabilityAtomicStorage = 21, + CapabilityInt16 = 22, + CapabilityTessellationPointSize = 23, + CapabilityGeometryPointSize = 24, + CapabilityImageGatherExtended = 25, + CapabilityStorageImageMultisample = 27, + CapabilityUniformBufferArrayDynamicIndexing = 28, + CapabilitySampledImageArrayDynamicIndexing = 29, + CapabilityStorageBufferArrayDynamicIndexing = 30, + CapabilityStorageImageArrayDynamicIndexing = 31, + CapabilityClipDistance = 32, + CapabilityCullDistance = 33, + CapabilityImageCubeArray = 34, + CapabilitySampleRateShading = 35, + CapabilityImageRect = 36, + CapabilitySampledRect = 37, + CapabilityGenericPointer = 38, + CapabilityInt8 = 39, + CapabilityInputAttachment = 40, + CapabilitySparseResidency = 41, + CapabilityMinLod = 42, + CapabilitySampled1D = 43, + CapabilityImage1D = 44, + CapabilitySampledCubeArray = 45, + CapabilitySampledBuffer = 46, + CapabilityImageBuffer = 47, + CapabilityImageMSArray = 48, + CapabilityStorageImageExtendedFormats = 49, + CapabilityImageQuery = 50, + CapabilityDerivativeControl = 51, + CapabilityInterpolationFunction = 52, + CapabilityTransformFeedback = 53, + CapabilityGeometryStreams = 54, + CapabilityStorageImageReadWithoutFormat = 55, + CapabilityStorageImageWriteWithoutFormat = 56, + CapabilityMultiViewport = 57, + CapabilitySubgroupDispatch = 58, + CapabilityNamedBarrier = 59, + CapabilityPipeStorage = 60, + CapabilityGroupNonUniform = 61, + CapabilityGroupNonUniformVote = 62, + CapabilityGroupNonUniformArithmetic = 63, + CapabilityGroupNonUniformBallot = 64, + CapabilityGroupNonUniformShuffle = 65, + CapabilityGroupNonUniformShuffleRelative = 66, + CapabilityGroupNonUniformClustered = 67, + CapabilityGroupNonUniformQuad = 68, + CapabilityShaderLayer = 69, + CapabilityShaderViewportIndex = 70, + CapabilityUniformDecoration = 71, + CapabilityCoreBuiltinsARM = 4165, + CapabilityTileImageColorReadAccessEXT = 4166, + CapabilityTileImageDepthReadAccessEXT = 4167, + CapabilityTileImageStencilReadAccessEXT = 4168, + CapabilityFragmentShadingRateKHR = 4422, + CapabilitySubgroupBallotKHR = 4423, + CapabilityDrawParameters = 4427, + CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, + CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, + CapabilitySubgroupVoteKHR = 4431, + CapabilityStorageBuffer16BitAccess = 4433, + CapabilityStorageUniformBufferBlock16 = 4433, + CapabilityStorageUniform16 = 4434, + CapabilityUniformAndStorageBuffer16BitAccess = 4434, + CapabilityStoragePushConstant16 = 4435, + CapabilityStorageInputOutput16 = 4436, + CapabilityDeviceGroup = 4437, + CapabilityMultiView = 4439, + CapabilityVariablePointersStorageBuffer = 4441, + CapabilityVariablePointers = 4442, + CapabilityAtomicStorageOps = 4445, + CapabilitySampleMaskPostDepthCoverage = 4447, + CapabilityStorageBuffer8BitAccess = 4448, + CapabilityUniformAndStorageBuffer8BitAccess = 4449, + CapabilityStoragePushConstant8 = 4450, + CapabilityDenormPreserve = 4464, + CapabilityDenormFlushToZero = 4465, + CapabilitySignedZeroInfNanPreserve = 4466, + CapabilityRoundingModeRTE = 4467, + CapabilityRoundingModeRTZ = 4468, + CapabilityRayQueryProvisionalKHR = 4471, + CapabilityRayQueryKHR = 4472, + CapabilityRayTraversalPrimitiveCullingKHR = 4478, + CapabilityRayTracingKHR = 4479, + CapabilityTextureSampleWeightedQCOM = 4484, + CapabilityTextureBoxFilterQCOM = 4485, + CapabilityTextureBlockMatchQCOM = 4486, + CapabilityFloat16ImageAMD = 5008, + CapabilityImageGatherBiasLodAMD = 5009, + CapabilityFragmentMaskAMD = 5010, + CapabilityStencilExportEXT = 5013, + CapabilityImageReadWriteLodAMD = 5015, + CapabilityInt64ImageEXT = 5016, + CapabilityShaderClockKHR = 5055, + CapabilitySampleMaskOverrideCoverageNV = 5249, + CapabilityGeometryShaderPassthroughNV = 5251, + CapabilityShaderViewportIndexLayerEXT = 5254, + CapabilityShaderViewportIndexLayerNV = 5254, + CapabilityShaderViewportMaskNV = 5255, + CapabilityShaderStereoViewNV = 5259, + CapabilityPerViewAttributesNV = 5260, + CapabilityFragmentFullyCoveredEXT = 5265, + CapabilityMeshShadingNV = 5266, + CapabilityImageFootprintNV = 5282, + CapabilityMeshShadingEXT = 5283, + CapabilityFragmentBarycentricKHR = 5284, + CapabilityFragmentBarycentricNV = 5284, + CapabilityComputeDerivativeGroupQuadsNV = 5288, + CapabilityFragmentDensityEXT = 5291, + CapabilityShadingRateNV = 5291, + CapabilityGroupNonUniformPartitionedNV = 5297, + CapabilityShaderNonUniform = 5301, + CapabilityShaderNonUniformEXT = 5301, + CapabilityRuntimeDescriptorArray = 5302, + CapabilityRuntimeDescriptorArrayEXT = 5302, + CapabilityInputAttachmentArrayDynamicIndexing = 5303, + CapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, + CapabilityUniformTexelBufferArrayDynamicIndexing = 5304, + CapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, + CapabilityStorageTexelBufferArrayDynamicIndexing = 5305, + CapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, + CapabilityUniformBufferArrayNonUniformIndexing = 5306, + CapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, + CapabilitySampledImageArrayNonUniformIndexing = 5307, + CapabilitySampledImageArrayNonUniformIndexingEXT = 5307, + CapabilityStorageBufferArrayNonUniformIndexing = 5308, + CapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, + CapabilityStorageImageArrayNonUniformIndexing = 5309, + CapabilityStorageImageArrayNonUniformIndexingEXT = 5309, + CapabilityInputAttachmentArrayNonUniformIndexing = 5310, + CapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, + CapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, + CapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, + CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, + CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, + CapabilityRayTracingPositionFetchKHR = 5336, + CapabilityRayTracingNV = 5340, + CapabilityRayTracingMotionBlurNV = 5341, + CapabilityVulkanMemoryModel = 5345, + CapabilityVulkanMemoryModelKHR = 5345, + CapabilityVulkanMemoryModelDeviceScope = 5346, + CapabilityVulkanMemoryModelDeviceScopeKHR = 5346, + CapabilityPhysicalStorageBufferAddresses = 5347, + CapabilityPhysicalStorageBufferAddressesEXT = 5347, + CapabilityComputeDerivativeGroupLinearNV = 5350, + CapabilityRayTracingProvisionalKHR = 5353, + CapabilityCooperativeMatrixNV = 5357, + CapabilityFragmentShaderSampleInterlockEXT = 5363, + CapabilityFragmentShaderShadingRateInterlockEXT = 5372, + CapabilityShaderSMBuiltinsNV = 5373, + CapabilityFragmentShaderPixelInterlockEXT = 5378, + CapabilityDemoteToHelperInvocation = 5379, + CapabilityDemoteToHelperInvocationEXT = 5379, + CapabilityDisplacementMicromapNV = 5380, + CapabilityRayTracingDisplacementMicromapNV = 5409, + CapabilityRayTracingOpacityMicromapEXT = 5381, + CapabilityShaderInvocationReorderNV = 5383, + CapabilityBindlessTextureNV = 5390, + CapabilityRayQueryPositionFetchKHR = 5391, + CapabilitySubgroupShuffleINTEL = 5568, + CapabilitySubgroupBufferBlockIOINTEL = 5569, + CapabilitySubgroupImageBlockIOINTEL = 5570, + CapabilitySubgroupImageMediaBlockIOINTEL = 5579, + CapabilityRoundToInfinityINTEL = 5582, + CapabilityFloatingPointModeINTEL = 5583, + CapabilityIntegerFunctions2INTEL = 5584, + CapabilityFunctionPointersINTEL = 5603, + CapabilityIndirectReferencesINTEL = 5604, + CapabilityAsmINTEL = 5606, + CapabilityAtomicFloat32MinMaxEXT = 5612, + CapabilityAtomicFloat64MinMaxEXT = 5613, + CapabilityAtomicFloat16MinMaxEXT = 5616, + CapabilityVectorComputeINTEL = 5617, + CapabilityVectorAnyINTEL = 5619, + CapabilityExpectAssumeKHR = 5629, + CapabilitySubgroupAvcMotionEstimationINTEL = 5696, + CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, + CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + CapabilityVariableLengthArrayINTEL = 5817, + CapabilityFunctionFloatControlINTEL = 5821, + CapabilityFPGAMemoryAttributesINTEL = 5824, + CapabilityFPFastMathModeINTEL = 5837, + CapabilityArbitraryPrecisionIntegersINTEL = 5844, + CapabilityArbitraryPrecisionFloatingPointINTEL = 5845, + CapabilityUnstructuredLoopControlsINTEL = 5886, + CapabilityFPGALoopControlsINTEL = 5888, + CapabilityKernelAttributesINTEL = 5892, + CapabilityFPGAKernelAttributesINTEL = 5897, + CapabilityFPGAMemoryAccessesINTEL = 5898, + CapabilityFPGAClusterAttributesINTEL = 5904, + CapabilityLoopFuseINTEL = 5906, + CapabilityFPGADSPControlINTEL = 5908, + CapabilityMemoryAccessAliasingINTEL = 5910, + CapabilityFPGAInvocationPipeliningAttributesINTEL = 5916, + CapabilityFPGABufferLocationINTEL = 5920, + CapabilityArbitraryPrecisionFixedPointINTEL = 5922, + CapabilityUSMStorageClassesINTEL = 5935, + CapabilityRuntimeAlignedAttributeINTEL = 5939, + CapabilityIOPipesINTEL = 5943, + CapabilityBlockingPipesINTEL = 5945, + CapabilityFPGARegINTEL = 5948, + CapabilityDotProductInputAll = 6016, + CapabilityDotProductInputAllKHR = 6016, + CapabilityDotProductInput4x8Bit = 6017, + CapabilityDotProductInput4x8BitKHR = 6017, + CapabilityDotProductInput4x8BitPacked = 6018, + CapabilityDotProductInput4x8BitPackedKHR = 6018, + CapabilityDotProduct = 6019, + CapabilityDotProductKHR = 6019, + CapabilityRayCullMaskKHR = 6020, + CapabilityCooperativeMatrixKHR = 6022, + CapabilityBitInstructions = 6025, + CapabilityGroupNonUniformRotateKHR = 6026, + CapabilityAtomicFloat32AddEXT = 6033, + CapabilityAtomicFloat64AddEXT = 6034, + CapabilityLongConstantCompositeINTEL = 6089, + CapabilityOptNoneINTEL = 6094, + CapabilityAtomicFloat16AddEXT = 6095, + CapabilityDebugInfoModuleINTEL = 6114, + CapabilitySplitBarrierINTEL = 6141, + CapabilityFPGAArgumentInterfacesINTEL = 6174, + CapabilityGroupUniformArithmeticKHR = 6400, + CapabilityMax = 0x7fffffff, +}; + +enum RayFlagsShift { + RayFlagsOpaqueKHRShift = 0, + RayFlagsNoOpaqueKHRShift = 1, + RayFlagsTerminateOnFirstHitKHRShift = 2, + RayFlagsSkipClosestHitShaderKHRShift = 3, + RayFlagsCullBackFacingTrianglesKHRShift = 4, + RayFlagsCullFrontFacingTrianglesKHRShift = 5, + RayFlagsCullOpaqueKHRShift = 6, + RayFlagsCullNoOpaqueKHRShift = 7, + RayFlagsSkipTrianglesKHRShift = 8, + RayFlagsSkipAABBsKHRShift = 9, + RayFlagsForceOpacityMicromap2StateEXTShift = 10, + RayFlagsMax = 0x7fffffff, +}; + +enum RayFlagsMask { + RayFlagsMaskNone = 0, + RayFlagsOpaqueKHRMask = 0x00000001, + RayFlagsNoOpaqueKHRMask = 0x00000002, + RayFlagsTerminateOnFirstHitKHRMask = 0x00000004, + RayFlagsSkipClosestHitShaderKHRMask = 0x00000008, + RayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, + RayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, + RayFlagsCullOpaqueKHRMask = 0x00000040, + RayFlagsCullNoOpaqueKHRMask = 0x00000080, + RayFlagsSkipTrianglesKHRMask = 0x00000100, + RayFlagsSkipAABBsKHRMask = 0x00000200, + RayFlagsForceOpacityMicromap2StateEXTMask = 0x00000400, +}; + +enum RayQueryIntersection { + RayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, + RayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, + RayQueryIntersectionMax = 0x7fffffff, +}; + +enum RayQueryCommittedIntersectionType { + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, + RayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, + RayQueryCommittedIntersectionTypeMax = 0x7fffffff, +}; + +enum RayQueryCandidateIntersectionType { + RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, + RayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, + RayQueryCandidateIntersectionTypeMax = 0x7fffffff, +}; + +enum FragmentShadingRateShift { + FragmentShadingRateVertical2PixelsShift = 0, + FragmentShadingRateVertical4PixelsShift = 1, + FragmentShadingRateHorizontal2PixelsShift = 2, + FragmentShadingRateHorizontal4PixelsShift = 3, + FragmentShadingRateMax = 0x7fffffff, +}; + +enum FragmentShadingRateMask { + FragmentShadingRateMaskNone = 0, + FragmentShadingRateVertical2PixelsMask = 0x00000001, + FragmentShadingRateVertical4PixelsMask = 0x00000002, + FragmentShadingRateHorizontal2PixelsMask = 0x00000004, + FragmentShadingRateHorizontal4PixelsMask = 0x00000008, +}; + +enum FPDenormMode { + FPDenormModePreserve = 0, + FPDenormModeFlushToZero = 1, + FPDenormModeMax = 0x7fffffff, +}; + +enum FPOperationMode { + FPOperationModeIEEE = 0, + FPOperationModeALT = 1, + FPOperationModeMax = 0x7fffffff, +}; + +enum QuantizationModes { + QuantizationModesTRN = 0, + QuantizationModesTRN_ZERO = 1, + QuantizationModesRND = 2, + QuantizationModesRND_ZERO = 3, + QuantizationModesRND_INF = 4, + QuantizationModesRND_MIN_INF = 5, + QuantizationModesRND_CONV = 6, + QuantizationModesRND_CONV_ODD = 7, + QuantizationModesMax = 0x7fffffff, +}; + +enum OverflowModes { + OverflowModesWRAP = 0, + OverflowModesSAT = 1, + OverflowModesSAT_ZERO = 2, + OverflowModesSAT_SYM = 3, + OverflowModesMax = 0x7fffffff, +}; + +enum PackedVectorFormat { + PackedVectorFormatPackedVectorFormat4x8Bit = 0, + PackedVectorFormatPackedVectorFormat4x8BitKHR = 0, + PackedVectorFormatMax = 0x7fffffff, +}; + +enum CooperativeMatrixOperandsShift { + CooperativeMatrixOperandsMatrixASignedComponentsKHRShift = 0, + CooperativeMatrixOperandsMatrixBSignedComponentsKHRShift = 1, + CooperativeMatrixOperandsMatrixCSignedComponentsKHRShift = 2, + CooperativeMatrixOperandsMatrixResultSignedComponentsKHRShift = 3, + CooperativeMatrixOperandsSaturatingAccumulationKHRShift = 4, + CooperativeMatrixOperandsMax = 0x7fffffff, +}; + +enum CooperativeMatrixOperandsMask { + CooperativeMatrixOperandsMaskNone = 0, + CooperativeMatrixOperandsMatrixASignedComponentsKHRMask = 0x00000001, + CooperativeMatrixOperandsMatrixBSignedComponentsKHRMask = 0x00000002, + CooperativeMatrixOperandsMatrixCSignedComponentsKHRMask = 0x00000004, + CooperativeMatrixOperandsMatrixResultSignedComponentsKHRMask = 0x00000008, + CooperativeMatrixOperandsSaturatingAccumulationKHRMask = 0x00000010, +}; + +enum CooperativeMatrixLayout { + CooperativeMatrixLayoutRowMajorKHR = 0, + CooperativeMatrixLayoutColumnMajorKHR = 1, + CooperativeMatrixLayoutMax = 0x7fffffff, +}; + +enum CooperativeMatrixUse { + CooperativeMatrixUseMatrixAKHR = 0, + CooperativeMatrixUseMatrixBKHR = 1, + CooperativeMatrixUseMatrixAccumulatorKHR = 2, + CooperativeMatrixUseMax = 0x7fffffff, +}; + +enum Op { + OpNop = 0, + OpUndef = 1, + OpSourceContinued = 2, + OpSource = 3, + OpSourceExtension = 4, + OpName = 5, + OpMemberName = 6, + OpString = 7, + OpLine = 8, + OpExtension = 10, + OpExtInstImport = 11, + OpExtInst = 12, + OpMemoryModel = 14, + OpEntryPoint = 15, + OpExecutionMode = 16, + OpCapability = 17, + OpTypeVoid = 19, + OpTypeBool = 20, + OpTypeInt = 21, + OpTypeFloat = 22, + OpTypeVector = 23, + OpTypeMatrix = 24, + OpTypeImage = 25, + OpTypeSampler = 26, + OpTypeSampledImage = 27, + OpTypeArray = 28, + OpTypeRuntimeArray = 29, + OpTypeStruct = 30, + OpTypeOpaque = 31, + OpTypePointer = 32, + OpTypeFunction = 33, + OpTypeEvent = 34, + OpTypeDeviceEvent = 35, + OpTypeReserveId = 36, + OpTypeQueue = 37, + OpTypePipe = 38, + OpTypeForwardPointer = 39, + OpConstantTrue = 41, + OpConstantFalse = 42, + OpConstant = 43, + OpConstantComposite = 44, + OpConstantSampler = 45, + OpConstantNull = 46, + OpSpecConstantTrue = 48, + OpSpecConstantFalse = 49, + OpSpecConstant = 50, + OpSpecConstantComposite = 51, + OpSpecConstantOp = 52, + OpFunction = 54, + OpFunctionParameter = 55, + OpFunctionEnd = 56, + OpFunctionCall = 57, + OpVariable = 59, + OpImageTexelPointer = 60, + OpLoad = 61, + OpStore = 62, + OpCopyMemory = 63, + OpCopyMemorySized = 64, + OpAccessChain = 65, + OpInBoundsAccessChain = 66, + OpPtrAccessChain = 67, + OpArrayLength = 68, + OpGenericPtrMemSemantics = 69, + OpInBoundsPtrAccessChain = 70, + OpDecorate = 71, + OpMemberDecorate = 72, + OpDecorationGroup = 73, + OpGroupDecorate = 74, + OpGroupMemberDecorate = 75, + OpVectorExtractDynamic = 77, + OpVectorInsertDynamic = 78, + OpVectorShuffle = 79, + OpCompositeConstruct = 80, + OpCompositeExtract = 81, + OpCompositeInsert = 82, + OpCopyObject = 83, + OpTranspose = 84, + OpSampledImage = 86, + OpImageSampleImplicitLod = 87, + OpImageSampleExplicitLod = 88, + OpImageSampleDrefImplicitLod = 89, + OpImageSampleDrefExplicitLod = 90, + OpImageSampleProjImplicitLod = 91, + OpImageSampleProjExplicitLod = 92, + OpImageSampleProjDrefImplicitLod = 93, + OpImageSampleProjDrefExplicitLod = 94, + OpImageFetch = 95, + OpImageGather = 96, + OpImageDrefGather = 97, + OpImageRead = 98, + OpImageWrite = 99, + OpImage = 100, + OpImageQueryFormat = 101, + OpImageQueryOrder = 102, + OpImageQuerySizeLod = 103, + OpImageQuerySize = 104, + OpImageQueryLod = 105, + OpImageQueryLevels = 106, + OpImageQuerySamples = 107, + OpConvertFToU = 109, + OpConvertFToS = 110, + OpConvertSToF = 111, + OpConvertUToF = 112, + OpUConvert = 113, + OpSConvert = 114, + OpFConvert = 115, + OpQuantizeToF16 = 116, + OpConvertPtrToU = 117, + OpSatConvertSToU = 118, + OpSatConvertUToS = 119, + OpConvertUToPtr = 120, + OpPtrCastToGeneric = 121, + OpGenericCastToPtr = 122, + OpGenericCastToPtrExplicit = 123, + OpBitcast = 124, + OpSNegate = 126, + OpFNegate = 127, + OpIAdd = 128, + OpFAdd = 129, + OpISub = 130, + OpFSub = 131, + OpIMul = 132, + OpFMul = 133, + OpUDiv = 134, + OpSDiv = 135, + OpFDiv = 136, + OpUMod = 137, + OpSRem = 138, + OpSMod = 139, + OpFRem = 140, + OpFMod = 141, + OpVectorTimesScalar = 142, + OpMatrixTimesScalar = 143, + OpVectorTimesMatrix = 144, + OpMatrixTimesVector = 145, + OpMatrixTimesMatrix = 146, + OpOuterProduct = 147, + OpDot = 148, + OpIAddCarry = 149, + OpISubBorrow = 150, + OpUMulExtended = 151, + OpSMulExtended = 152, + OpAny = 154, + OpAll = 155, + OpIsNan = 156, + OpIsInf = 157, + OpIsFinite = 158, + OpIsNormal = 159, + OpSignBitSet = 160, + OpLessOrGreater = 161, + OpOrdered = 162, + OpUnordered = 163, + OpLogicalEqual = 164, + OpLogicalNotEqual = 165, + OpLogicalOr = 166, + OpLogicalAnd = 167, + OpLogicalNot = 168, + OpSelect = 169, + OpIEqual = 170, + OpINotEqual = 171, + OpUGreaterThan = 172, + OpSGreaterThan = 173, + OpUGreaterThanEqual = 174, + OpSGreaterThanEqual = 175, + OpULessThan = 176, + OpSLessThan = 177, + OpULessThanEqual = 178, + OpSLessThanEqual = 179, + OpFOrdEqual = 180, + OpFUnordEqual = 181, + OpFOrdNotEqual = 182, + OpFUnordNotEqual = 183, + OpFOrdLessThan = 184, + OpFUnordLessThan = 185, + OpFOrdGreaterThan = 186, + OpFUnordGreaterThan = 187, + OpFOrdLessThanEqual = 188, + OpFUnordLessThanEqual = 189, + OpFOrdGreaterThanEqual = 190, + OpFUnordGreaterThanEqual = 191, + OpShiftRightLogical = 194, + OpShiftRightArithmetic = 195, + OpShiftLeftLogical = 196, + OpBitwiseOr = 197, + OpBitwiseXor = 198, + OpBitwiseAnd = 199, + OpNot = 200, + OpBitFieldInsert = 201, + OpBitFieldSExtract = 202, + OpBitFieldUExtract = 203, + OpBitReverse = 204, + OpBitCount = 205, + OpDPdx = 207, + OpDPdy = 208, + OpFwidth = 209, + OpDPdxFine = 210, + OpDPdyFine = 211, + OpFwidthFine = 212, + OpDPdxCoarse = 213, + OpDPdyCoarse = 214, + OpFwidthCoarse = 215, + OpEmitVertex = 218, + OpEndPrimitive = 219, + OpEmitStreamVertex = 220, + OpEndStreamPrimitive = 221, + OpControlBarrier = 224, + OpMemoryBarrier = 225, + OpAtomicLoad = 227, + OpAtomicStore = 228, + OpAtomicExchange = 229, + OpAtomicCompareExchange = 230, + OpAtomicCompareExchangeWeak = 231, + OpAtomicIIncrement = 232, + OpAtomicIDecrement = 233, + OpAtomicIAdd = 234, + OpAtomicISub = 235, + OpAtomicSMin = 236, + OpAtomicUMin = 237, + OpAtomicSMax = 238, + OpAtomicUMax = 239, + OpAtomicAnd = 240, + OpAtomicOr = 241, + OpAtomicXor = 242, + OpPhi = 245, + OpLoopMerge = 246, + OpSelectionMerge = 247, + OpLabel = 248, + OpBranch = 249, + OpBranchConditional = 250, + OpSwitch = 251, + OpKill = 252, + OpReturn = 253, + OpReturnValue = 254, + OpUnreachable = 255, + OpLifetimeStart = 256, + OpLifetimeStop = 257, + OpGroupAsyncCopy = 259, + OpGroupWaitEvents = 260, + OpGroupAll = 261, + OpGroupAny = 262, + OpGroupBroadcast = 263, + OpGroupIAdd = 264, + OpGroupFAdd = 265, + OpGroupFMin = 266, + OpGroupUMin = 267, + OpGroupSMin = 268, + OpGroupFMax = 269, + OpGroupUMax = 270, + OpGroupSMax = 271, + OpReadPipe = 274, + OpWritePipe = 275, + OpReservedReadPipe = 276, + OpReservedWritePipe = 277, + OpReserveReadPipePackets = 278, + OpReserveWritePipePackets = 279, + OpCommitReadPipe = 280, + OpCommitWritePipe = 281, + OpIsValidReserveId = 282, + OpGetNumPipePackets = 283, + OpGetMaxPipePackets = 284, + OpGroupReserveReadPipePackets = 285, + OpGroupReserveWritePipePackets = 286, + OpGroupCommitReadPipe = 287, + OpGroupCommitWritePipe = 288, + OpEnqueueMarker = 291, + OpEnqueueKernel = 292, + OpGetKernelNDrangeSubGroupCount = 293, + OpGetKernelNDrangeMaxSubGroupSize = 294, + OpGetKernelWorkGroupSize = 295, + OpGetKernelPreferredWorkGroupSizeMultiple = 296, + OpRetainEvent = 297, + OpReleaseEvent = 298, + OpCreateUserEvent = 299, + OpIsValidEvent = 300, + OpSetUserEventStatus = 301, + OpCaptureEventProfilingInfo = 302, + OpGetDefaultQueue = 303, + OpBuildNDRange = 304, + OpImageSparseSampleImplicitLod = 305, + OpImageSparseSampleExplicitLod = 306, + OpImageSparseSampleDrefImplicitLod = 307, + OpImageSparseSampleDrefExplicitLod = 308, + OpImageSparseSampleProjImplicitLod = 309, + OpImageSparseSampleProjExplicitLod = 310, + OpImageSparseSampleProjDrefImplicitLod = 311, + OpImageSparseSampleProjDrefExplicitLod = 312, + OpImageSparseFetch = 313, + OpImageSparseGather = 314, + OpImageSparseDrefGather = 315, + OpImageSparseTexelsResident = 316, + OpNoLine = 317, + OpAtomicFlagTestAndSet = 318, + OpAtomicFlagClear = 319, + OpImageSparseRead = 320, + OpSizeOf = 321, + OpTypePipeStorage = 322, + OpConstantPipeStorage = 323, + OpCreatePipeFromPipeStorage = 324, + OpGetKernelLocalSizeForSubgroupCount = 325, + OpGetKernelMaxNumSubgroups = 326, + OpTypeNamedBarrier = 327, + OpNamedBarrierInitialize = 328, + OpMemoryNamedBarrier = 329, + OpModuleProcessed = 330, + OpExecutionModeId = 331, + OpDecorateId = 332, + OpGroupNonUniformElect = 333, + OpGroupNonUniformAll = 334, + OpGroupNonUniformAny = 335, + OpGroupNonUniformAllEqual = 336, + OpGroupNonUniformBroadcast = 337, + OpGroupNonUniformBroadcastFirst = 338, + OpGroupNonUniformBallot = 339, + OpGroupNonUniformInverseBallot = 340, + OpGroupNonUniformBallotBitExtract = 341, + OpGroupNonUniformBallotBitCount = 342, + OpGroupNonUniformBallotFindLSB = 343, + OpGroupNonUniformBallotFindMSB = 344, + OpGroupNonUniformShuffle = 345, + OpGroupNonUniformShuffleXor = 346, + OpGroupNonUniformShuffleUp = 347, + OpGroupNonUniformShuffleDown = 348, + OpGroupNonUniformIAdd = 349, + OpGroupNonUniformFAdd = 350, + OpGroupNonUniformIMul = 351, + OpGroupNonUniformFMul = 352, + OpGroupNonUniformSMin = 353, + OpGroupNonUniformUMin = 354, + OpGroupNonUniformFMin = 355, + OpGroupNonUniformSMax = 356, + OpGroupNonUniformUMax = 357, + OpGroupNonUniformFMax = 358, + OpGroupNonUniformBitwiseAnd = 359, + OpGroupNonUniformBitwiseOr = 360, + OpGroupNonUniformBitwiseXor = 361, + OpGroupNonUniformLogicalAnd = 362, + OpGroupNonUniformLogicalOr = 363, + OpGroupNonUniformLogicalXor = 364, + OpGroupNonUniformQuadBroadcast = 365, + OpGroupNonUniformQuadSwap = 366, + OpCopyLogical = 400, + OpPtrEqual = 401, + OpPtrNotEqual = 402, + OpPtrDiff = 403, + OpColorAttachmentReadEXT = 4160, + OpDepthAttachmentReadEXT = 4161, + OpStencilAttachmentReadEXT = 4162, + OpTerminateInvocation = 4416, + OpSubgroupBallotKHR = 4421, + OpSubgroupFirstInvocationKHR = 4422, + OpSubgroupAllKHR = 4428, + OpSubgroupAnyKHR = 4429, + OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, + OpSubgroupReadInvocationKHR = 4432, + OpTraceRayKHR = 4445, + OpExecuteCallableKHR = 4446, + OpConvertUToAccelerationStructureKHR = 4447, + OpIgnoreIntersectionKHR = 4448, + OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, + OpTypeCooperativeMatrixKHR = 4456, + OpCooperativeMatrixLoadKHR = 4457, + OpCooperativeMatrixStoreKHR = 4458, + OpCooperativeMatrixMulAddKHR = 4459, + OpCooperativeMatrixLengthKHR = 4460, + OpTypeRayQueryKHR = 4472, + OpRayQueryInitializeKHR = 4473, + OpRayQueryTerminateKHR = 4474, + OpRayQueryGenerateIntersectionKHR = 4475, + OpRayQueryConfirmIntersectionKHR = 4476, + OpRayQueryProceedKHR = 4477, + OpRayQueryGetIntersectionTypeKHR = 4479, + OpImageSampleWeightedQCOM = 4480, + OpImageBoxFilterQCOM = 4481, + OpImageBlockMatchSSDQCOM = 4482, + OpImageBlockMatchSADQCOM = 4483, + OpGroupIAddNonUniformAMD = 5000, + OpGroupFAddNonUniformAMD = 5001, + OpGroupFMinNonUniformAMD = 5002, + OpGroupUMinNonUniformAMD = 5003, + OpGroupSMinNonUniformAMD = 5004, + OpGroupFMaxNonUniformAMD = 5005, + OpGroupUMaxNonUniformAMD = 5006, + OpGroupSMaxNonUniformAMD = 5007, + OpFragmentMaskFetchAMD = 5011, + OpFragmentFetchAMD = 5012, + OpReadClockKHR = 5056, + OpHitObjectRecordHitMotionNV = 5249, + OpHitObjectRecordHitWithIndexMotionNV = 5250, + OpHitObjectRecordMissMotionNV = 5251, + OpHitObjectGetWorldToObjectNV = 5252, + OpHitObjectGetObjectToWorldNV = 5253, + OpHitObjectGetObjectRayDirectionNV = 5254, + OpHitObjectGetObjectRayOriginNV = 5255, + OpHitObjectTraceRayMotionNV = 5256, + OpHitObjectGetShaderRecordBufferHandleNV = 5257, + OpHitObjectGetShaderBindingTableRecordIndexNV = 5258, + OpHitObjectRecordEmptyNV = 5259, + OpHitObjectTraceRayNV = 5260, + OpHitObjectRecordHitNV = 5261, + OpHitObjectRecordHitWithIndexNV = 5262, + OpHitObjectRecordMissNV = 5263, + OpHitObjectExecuteShaderNV = 5264, + OpHitObjectGetCurrentTimeNV = 5265, + OpHitObjectGetAttributesNV = 5266, + OpHitObjectGetHitKindNV = 5267, + OpHitObjectGetPrimitiveIndexNV = 5268, + OpHitObjectGetGeometryIndexNV = 5269, + OpHitObjectGetInstanceIdNV = 5270, + OpHitObjectGetInstanceCustomIndexNV = 5271, + OpHitObjectGetWorldRayDirectionNV = 5272, + OpHitObjectGetWorldRayOriginNV = 5273, + OpHitObjectGetRayTMaxNV = 5274, + OpHitObjectGetRayTMinNV = 5275, + OpHitObjectIsEmptyNV = 5276, + OpHitObjectIsHitNV = 5277, + OpHitObjectIsMissNV = 5278, + OpReorderThreadWithHitObjectNV = 5279, + OpReorderThreadWithHintNV = 5280, + OpTypeHitObjectNV = 5281, + OpImageSampleFootprintNV = 5283, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, + OpGroupNonUniformPartitionNV = 5296, + OpWritePackedPrimitiveIndices4x8NV = 5299, + OpFetchMicroTriangleVertexPositionNV = 5300, + OpFetchMicroTriangleVertexBarycentricNV = 5301, + OpReportIntersectionKHR = 5334, + OpReportIntersectionNV = 5334, + OpIgnoreIntersectionNV = 5335, + OpTerminateRayNV = 5336, + OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, + OpRayQueryGetIntersectionTriangleVertexPositionsKHR = 5340, + OpTypeAccelerationStructureKHR = 5341, + OpTypeAccelerationStructureNV = 5341, + OpExecuteCallableNV = 5344, + OpTypeCooperativeMatrixNV = 5358, + OpCooperativeMatrixLoadNV = 5359, + OpCooperativeMatrixStoreNV = 5360, + OpCooperativeMatrixMulAddNV = 5361, + OpCooperativeMatrixLengthNV = 5362, + OpBeginInvocationInterlockEXT = 5364, + OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocation = 5380, + OpDemoteToHelperInvocationEXT = 5380, + OpIsHelperInvocationEXT = 5381, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, + OpSubgroupShuffleINTEL = 5571, + OpSubgroupShuffleDownINTEL = 5572, + OpSubgroupShuffleUpINTEL = 5573, + OpSubgroupShuffleXorINTEL = 5574, + OpSubgroupBlockReadINTEL = 5575, + OpSubgroupBlockWriteINTEL = 5576, + OpSubgroupImageBlockReadINTEL = 5577, + OpSubgroupImageBlockWriteINTEL = 5578, + OpSubgroupImageMediaBlockReadINTEL = 5580, + OpSubgroupImageMediaBlockWriteINTEL = 5581, + OpUCountLeadingZerosINTEL = 5585, + OpUCountTrailingZerosINTEL = 5586, + OpAbsISubINTEL = 5587, + OpAbsUSubINTEL = 5588, + OpIAddSatINTEL = 5589, + OpUAddSatINTEL = 5590, + OpIAverageINTEL = 5591, + OpUAverageINTEL = 5592, + OpIAverageRoundedINTEL = 5593, + OpUAverageRoundedINTEL = 5594, + OpISubSatINTEL = 5595, + OpUSubSatINTEL = 5596, + OpIMul32x16INTEL = 5597, + OpUMul32x16INTEL = 5598, + OpConstantFunctionPointerINTEL = 5600, + OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, + OpDecorateString = 5632, + OpDecorateStringGOOGLE = 5632, + OpMemberDecorateString = 5633, + OpMemberDecorateStringGOOGLE = 5633, + OpVmeImageINTEL = 5699, + OpTypeVmeImageINTEL = 5700, + OpTypeAvcImePayloadINTEL = 5701, + OpTypeAvcRefPayloadINTEL = 5702, + OpTypeAvcSicPayloadINTEL = 5703, + OpTypeAvcMcePayloadINTEL = 5704, + OpTypeAvcMceResultINTEL = 5705, + OpTypeAvcImeResultINTEL = 5706, + OpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, + OpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, + OpTypeAvcImeSingleReferenceStreaminINTEL = 5709, + OpTypeAvcImeDualReferenceStreaminINTEL = 5710, + OpTypeAvcRefResultINTEL = 5711, + OpTypeAvcSicResultINTEL = 5712, + OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, + OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, + OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, + OpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, + OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, + OpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, + OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, + OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, + OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, + OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, + OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, + OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, + OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, + OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, + OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, + OpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, + OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, + OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, + OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, + OpSubgroupAvcMceConvertToImePayloadINTEL = 5732, + OpSubgroupAvcMceConvertToImeResultINTEL = 5733, + OpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, + OpSubgroupAvcMceConvertToRefResultINTEL = 5735, + OpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, + OpSubgroupAvcMceConvertToSicResultINTEL = 5737, + OpSubgroupAvcMceGetMotionVectorsINTEL = 5738, + OpSubgroupAvcMceGetInterDistortionsINTEL = 5739, + OpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, + OpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, + OpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, + OpSubgroupAvcMceGetInterDirectionsINTEL = 5743, + OpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, + OpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, + OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, + OpSubgroupAvcImeInitializeINTEL = 5747, + OpSubgroupAvcImeSetSingleReferenceINTEL = 5748, + OpSubgroupAvcImeSetDualReferenceINTEL = 5749, + OpSubgroupAvcImeRefWindowSizeINTEL = 5750, + OpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, + OpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, + OpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, + OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, + OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, + OpSubgroupAvcImeSetWeightedSadINTEL = 5756, + OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, + OpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, + OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, + OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, + OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, + OpSubgroupAvcImeConvertToMceResultINTEL = 5765, + OpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, + OpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, + OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, + OpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, + OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, + OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, + OpSubgroupAvcImeGetBorderReachedINTEL = 5776, + OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, + OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, + OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, + OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, + OpSubgroupAvcFmeInitializeINTEL = 5781, + OpSubgroupAvcBmeInitializeINTEL = 5782, + OpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, + OpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, + OpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, + OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, + OpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, + OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, + OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, + OpSubgroupAvcRefConvertToMceResultINTEL = 5790, + OpSubgroupAvcSicInitializeINTEL = 5791, + OpSubgroupAvcSicConfigureSkcINTEL = 5792, + OpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, + OpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, + OpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, + OpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, + OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, + OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, + OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, + OpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, + OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, + OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, + OpSubgroupAvcSicEvaluateIpeINTEL = 5803, + OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, + OpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, + OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, + OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, + OpSubgroupAvcSicConvertToMceResultINTEL = 5808, + OpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, + OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, + OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, + OpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, + OpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, + OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, + OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, + OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, + OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, + OpReadPipeBlockingINTEL = 5946, + OpWritePipeBlockingINTEL = 5947, + OpFPGARegINTEL = 5949, + OpRayQueryGetRayTMinKHR = 6016, + OpRayQueryGetRayFlagsKHR = 6017, + OpRayQueryGetIntersectionTKHR = 6018, + OpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, + OpRayQueryGetIntersectionInstanceIdKHR = 6020, + OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, + OpRayQueryGetIntersectionGeometryIndexKHR = 6022, + OpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, + OpRayQueryGetIntersectionBarycentricsKHR = 6024, + OpRayQueryGetIntersectionFrontFaceKHR = 6025, + OpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, + OpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, + OpRayQueryGetIntersectionObjectRayOriginKHR = 6028, + OpRayQueryGetWorldRayDirectionKHR = 6029, + OpRayQueryGetWorldRayOriginKHR = 6030, + OpRayQueryGetIntersectionObjectToWorldKHR = 6031, + OpRayQueryGetIntersectionWorldToObjectKHR = 6032, + OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, + OpMax = 0x7fffffff, +}; + +#ifdef SPV_ENABLE_UTILITY_CODE +#ifndef __cplusplus +#include +#endif +inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { + *hasResult = *hasResultType = false; + switch (opcode) { + default: /* unknown opcode */ break; + case OpNop: *hasResult = false; *hasResultType = false; break; + case OpUndef: *hasResult = true; *hasResultType = true; break; + case OpSourceContinued: *hasResult = false; *hasResultType = false; break; + case OpSource: *hasResult = false; *hasResultType = false; break; + case OpSourceExtension: *hasResult = false; *hasResultType = false; break; + case OpName: *hasResult = false; *hasResultType = false; break; + case OpMemberName: *hasResult = false; *hasResultType = false; break; + case OpString: *hasResult = true; *hasResultType = false; break; + case OpLine: *hasResult = false; *hasResultType = false; break; + case OpExtension: *hasResult = false; *hasResultType = false; break; + case OpExtInstImport: *hasResult = true; *hasResultType = false; break; + case OpExtInst: *hasResult = true; *hasResultType = true; break; + case OpMemoryModel: *hasResult = false; *hasResultType = false; break; + case OpEntryPoint: *hasResult = false; *hasResultType = false; break; + case OpExecutionMode: *hasResult = false; *hasResultType = false; break; + case OpCapability: *hasResult = false; *hasResultType = false; break; + case OpTypeVoid: *hasResult = true; *hasResultType = false; break; + case OpTypeBool: *hasResult = true; *hasResultType = false; break; + case OpTypeInt: *hasResult = true; *hasResultType = false; break; + case OpTypeFloat: *hasResult = true; *hasResultType = false; break; + case OpTypeVector: *hasResult = true; *hasResultType = false; break; + case OpTypeMatrix: *hasResult = true; *hasResultType = false; break; + case OpTypeImage: *hasResult = true; *hasResultType = false; break; + case OpTypeSampler: *hasResult = true; *hasResultType = false; break; + case OpTypeSampledImage: *hasResult = true; *hasResultType = false; break; + case OpTypeArray: *hasResult = true; *hasResultType = false; break; + case OpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; + case OpTypeStruct: *hasResult = true; *hasResultType = false; break; + case OpTypeOpaque: *hasResult = true; *hasResultType = false; break; + case OpTypePointer: *hasResult = true; *hasResultType = false; break; + case OpTypeFunction: *hasResult = true; *hasResultType = false; break; + case OpTypeEvent: *hasResult = true; *hasResultType = false; break; + case OpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; + case OpTypeReserveId: *hasResult = true; *hasResultType = false; break; + case OpTypeQueue: *hasResult = true; *hasResultType = false; break; + case OpTypePipe: *hasResult = true; *hasResultType = false; break; + case OpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; + case OpConstantTrue: *hasResult = true; *hasResultType = true; break; + case OpConstantFalse: *hasResult = true; *hasResultType = true; break; + case OpConstant: *hasResult = true; *hasResultType = true; break; + case OpConstantComposite: *hasResult = true; *hasResultType = true; break; + case OpConstantSampler: *hasResult = true; *hasResultType = true; break; + case OpConstantNull: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; + case OpSpecConstant: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; + case OpSpecConstantOp: *hasResult = true; *hasResultType = true; break; + case OpFunction: *hasResult = true; *hasResultType = true; break; + case OpFunctionParameter: *hasResult = true; *hasResultType = true; break; + case OpFunctionEnd: *hasResult = false; *hasResultType = false; break; + case OpFunctionCall: *hasResult = true; *hasResultType = true; break; + case OpVariable: *hasResult = true; *hasResultType = true; break; + case OpImageTexelPointer: *hasResult = true; *hasResultType = true; break; + case OpLoad: *hasResult = true; *hasResultType = true; break; + case OpStore: *hasResult = false; *hasResultType = false; break; + case OpCopyMemory: *hasResult = false; *hasResultType = false; break; + case OpCopyMemorySized: *hasResult = false; *hasResultType = false; break; + case OpAccessChain: *hasResult = true; *hasResultType = true; break; + case OpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; + case OpPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case OpArrayLength: *hasResult = true; *hasResultType = true; break; + case OpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; + case OpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; + case OpDecorate: *hasResult = false; *hasResultType = false; break; + case OpMemberDecorate: *hasResult = false; *hasResultType = false; break; + case OpDecorationGroup: *hasResult = true; *hasResultType = false; break; + case OpGroupDecorate: *hasResult = false; *hasResultType = false; break; + case OpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; + case OpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; + case OpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; + case OpVectorShuffle: *hasResult = true; *hasResultType = true; break; + case OpCompositeConstruct: *hasResult = true; *hasResultType = true; break; + case OpCompositeExtract: *hasResult = true; *hasResultType = true; break; + case OpCompositeInsert: *hasResult = true; *hasResultType = true; break; + case OpCopyObject: *hasResult = true; *hasResultType = true; break; + case OpTranspose: *hasResult = true; *hasResultType = true; break; + case OpSampledImage: *hasResult = true; *hasResultType = true; break; + case OpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageFetch: *hasResult = true; *hasResultType = true; break; + case OpImageGather: *hasResult = true; *hasResultType = true; break; + case OpImageDrefGather: *hasResult = true; *hasResultType = true; break; + case OpImageRead: *hasResult = true; *hasResultType = true; break; + case OpImageWrite: *hasResult = false; *hasResultType = false; break; + case OpImage: *hasResult = true; *hasResultType = true; break; + case OpImageQueryFormat: *hasResult = true; *hasResultType = true; break; + case OpImageQueryOrder: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySize: *hasResult = true; *hasResultType = true; break; + case OpImageQueryLod: *hasResult = true; *hasResultType = true; break; + case OpImageQueryLevels: *hasResult = true; *hasResultType = true; break; + case OpImageQuerySamples: *hasResult = true; *hasResultType = true; break; + case OpConvertFToU: *hasResult = true; *hasResultType = true; break; + case OpConvertFToS: *hasResult = true; *hasResultType = true; break; + case OpConvertSToF: *hasResult = true; *hasResultType = true; break; + case OpConvertUToF: *hasResult = true; *hasResultType = true; break; + case OpUConvert: *hasResult = true; *hasResultType = true; break; + case OpSConvert: *hasResult = true; *hasResultType = true; break; + case OpFConvert: *hasResult = true; *hasResultType = true; break; + case OpQuantizeToF16: *hasResult = true; *hasResultType = true; break; + case OpConvertPtrToU: *hasResult = true; *hasResultType = true; break; + case OpSatConvertSToU: *hasResult = true; *hasResultType = true; break; + case OpSatConvertUToS: *hasResult = true; *hasResultType = true; break; + case OpConvertUToPtr: *hasResult = true; *hasResultType = true; break; + case OpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; + case OpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; + case OpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; + case OpBitcast: *hasResult = true; *hasResultType = true; break; + case OpSNegate: *hasResult = true; *hasResultType = true; break; + case OpFNegate: *hasResult = true; *hasResultType = true; break; + case OpIAdd: *hasResult = true; *hasResultType = true; break; + case OpFAdd: *hasResult = true; *hasResultType = true; break; + case OpISub: *hasResult = true; *hasResultType = true; break; + case OpFSub: *hasResult = true; *hasResultType = true; break; + case OpIMul: *hasResult = true; *hasResultType = true; break; + case OpFMul: *hasResult = true; *hasResultType = true; break; + case OpUDiv: *hasResult = true; *hasResultType = true; break; + case OpSDiv: *hasResult = true; *hasResultType = true; break; + case OpFDiv: *hasResult = true; *hasResultType = true; break; + case OpUMod: *hasResult = true; *hasResultType = true; break; + case OpSRem: *hasResult = true; *hasResultType = true; break; + case OpSMod: *hasResult = true; *hasResultType = true; break; + case OpFRem: *hasResult = true; *hasResultType = true; break; + case OpFMod: *hasResult = true; *hasResultType = true; break; + case OpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; + case OpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; + case OpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; + case OpOuterProduct: *hasResult = true; *hasResultType = true; break; + case OpDot: *hasResult = true; *hasResultType = true; break; + case OpIAddCarry: *hasResult = true; *hasResultType = true; break; + case OpISubBorrow: *hasResult = true; *hasResultType = true; break; + case OpUMulExtended: *hasResult = true; *hasResultType = true; break; + case OpSMulExtended: *hasResult = true; *hasResultType = true; break; + case OpAny: *hasResult = true; *hasResultType = true; break; + case OpAll: *hasResult = true; *hasResultType = true; break; + case OpIsNan: *hasResult = true; *hasResultType = true; break; + case OpIsInf: *hasResult = true; *hasResultType = true; break; + case OpIsFinite: *hasResult = true; *hasResultType = true; break; + case OpIsNormal: *hasResult = true; *hasResultType = true; break; + case OpSignBitSet: *hasResult = true; *hasResultType = true; break; + case OpLessOrGreater: *hasResult = true; *hasResultType = true; break; + case OpOrdered: *hasResult = true; *hasResultType = true; break; + case OpUnordered: *hasResult = true; *hasResultType = true; break; + case OpLogicalEqual: *hasResult = true; *hasResultType = true; break; + case OpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; + case OpLogicalOr: *hasResult = true; *hasResultType = true; break; + case OpLogicalAnd: *hasResult = true; *hasResultType = true; break; + case OpLogicalNot: *hasResult = true; *hasResultType = true; break; + case OpSelect: *hasResult = true; *hasResultType = true; break; + case OpIEqual: *hasResult = true; *hasResultType = true; break; + case OpINotEqual: *hasResult = true; *hasResultType = true; break; + case OpUGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpSGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpULessThan: *hasResult = true; *hasResultType = true; break; + case OpSLessThan: *hasResult = true; *hasResultType = true; break; + case OpULessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpSLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdLessThan: *hasResult = true; *hasResultType = true; break; + case OpFUnordLessThan: *hasResult = true; *hasResultType = true; break; + case OpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; + case OpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; + case OpShiftRightLogical: *hasResult = true; *hasResultType = true; break; + case OpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; + case OpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; + case OpBitwiseOr: *hasResult = true; *hasResultType = true; break; + case OpBitwiseXor: *hasResult = true; *hasResultType = true; break; + case OpBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case OpNot: *hasResult = true; *hasResultType = true; break; + case OpBitFieldInsert: *hasResult = true; *hasResultType = true; break; + case OpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; + case OpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; + case OpBitReverse: *hasResult = true; *hasResultType = true; break; + case OpBitCount: *hasResult = true; *hasResultType = true; break; + case OpDPdx: *hasResult = true; *hasResultType = true; break; + case OpDPdy: *hasResult = true; *hasResultType = true; break; + case OpFwidth: *hasResult = true; *hasResultType = true; break; + case OpDPdxFine: *hasResult = true; *hasResultType = true; break; + case OpDPdyFine: *hasResult = true; *hasResultType = true; break; + case OpFwidthFine: *hasResult = true; *hasResultType = true; break; + case OpDPdxCoarse: *hasResult = true; *hasResultType = true; break; + case OpDPdyCoarse: *hasResult = true; *hasResultType = true; break; + case OpFwidthCoarse: *hasResult = true; *hasResultType = true; break; + case OpEmitVertex: *hasResult = false; *hasResultType = false; break; + case OpEndPrimitive: *hasResult = false; *hasResultType = false; break; + case OpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; + case OpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; + case OpControlBarrier: *hasResult = false; *hasResultType = false; break; + case OpMemoryBarrier: *hasResult = false; *hasResultType = false; break; + case OpAtomicLoad: *hasResult = true; *hasResultType = true; break; + case OpAtomicStore: *hasResult = false; *hasResultType = false; break; + case OpAtomicExchange: *hasResult = true; *hasResultType = true; break; + case OpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; + case OpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; + case OpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; + case OpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; + case OpAtomicIAdd: *hasResult = true; *hasResultType = true; break; + case OpAtomicISub: *hasResult = true; *hasResultType = true; break; + case OpAtomicSMin: *hasResult = true; *hasResultType = true; break; + case OpAtomicUMin: *hasResult = true; *hasResultType = true; break; + case OpAtomicSMax: *hasResult = true; *hasResultType = true; break; + case OpAtomicUMax: *hasResult = true; *hasResultType = true; break; + case OpAtomicAnd: *hasResult = true; *hasResultType = true; break; + case OpAtomicOr: *hasResult = true; *hasResultType = true; break; + case OpAtomicXor: *hasResult = true; *hasResultType = true; break; + case OpPhi: *hasResult = true; *hasResultType = true; break; + case OpLoopMerge: *hasResult = false; *hasResultType = false; break; + case OpSelectionMerge: *hasResult = false; *hasResultType = false; break; + case OpLabel: *hasResult = true; *hasResultType = false; break; + case OpBranch: *hasResult = false; *hasResultType = false; break; + case OpBranchConditional: *hasResult = false; *hasResultType = false; break; + case OpSwitch: *hasResult = false; *hasResultType = false; break; + case OpKill: *hasResult = false; *hasResultType = false; break; + case OpReturn: *hasResult = false; *hasResultType = false; break; + case OpReturnValue: *hasResult = false; *hasResultType = false; break; + case OpUnreachable: *hasResult = false; *hasResultType = false; break; + case OpLifetimeStart: *hasResult = false; *hasResultType = false; break; + case OpLifetimeStop: *hasResult = false; *hasResultType = false; break; + case OpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; + case OpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; + case OpGroupAll: *hasResult = true; *hasResultType = true; break; + case OpGroupAny: *hasResult = true; *hasResultType = true; break; + case OpGroupBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupIAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupFAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupFMin: *hasResult = true; *hasResultType = true; break; + case OpGroupUMin: *hasResult = true; *hasResultType = true; break; + case OpGroupSMin: *hasResult = true; *hasResultType = true; break; + case OpGroupFMax: *hasResult = true; *hasResultType = true; break; + case OpGroupUMax: *hasResult = true; *hasResultType = true; break; + case OpGroupSMax: *hasResult = true; *hasResultType = true; break; + case OpReadPipe: *hasResult = true; *hasResultType = true; break; + case OpWritePipe: *hasResult = true; *hasResultType = true; break; + case OpReservedReadPipe: *hasResult = true; *hasResultType = true; break; + case OpReservedWritePipe: *hasResult = true; *hasResultType = true; break; + case OpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case OpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case OpCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case OpCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case OpIsValidReserveId: *hasResult = true; *hasResultType = true; break; + case OpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; + case OpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; + case OpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; + case OpEnqueueMarker: *hasResult = true; *hasResultType = true; break; + case OpEnqueueKernel: *hasResult = true; *hasResultType = true; break; + case OpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; + case OpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; + case OpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; + case OpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; + case OpRetainEvent: *hasResult = false; *hasResultType = false; break; + case OpReleaseEvent: *hasResult = false; *hasResultType = false; break; + case OpCreateUserEvent: *hasResult = true; *hasResultType = true; break; + case OpIsValidEvent: *hasResult = true; *hasResultType = true; break; + case OpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; + case OpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; + case OpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; + case OpBuildNDRange: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; + case OpImageSparseFetch: *hasResult = true; *hasResultType = true; break; + case OpImageSparseGather: *hasResult = true; *hasResultType = true; break; + case OpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; + case OpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; + case OpNoLine: *hasResult = false; *hasResultType = false; break; + case OpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; + case OpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; + case OpImageSparseRead: *hasResult = true; *hasResultType = true; break; + case OpSizeOf: *hasResult = true; *hasResultType = true; break; + case OpTypePipeStorage: *hasResult = true; *hasResultType = false; break; + case OpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; + case OpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; + case OpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; + case OpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; + case OpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; + case OpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; + case OpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; + case OpModuleProcessed: *hasResult = false; *hasResultType = false; break; + case OpExecutionModeId: *hasResult = false; *hasResultType = false; break; + case OpDecorateId: *hasResult = false; *hasResultType = false; break; + case OpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; + case OpCopyLogical: *hasResult = true; *hasResultType = true; break; + case OpPtrEqual: *hasResult = true; *hasResultType = true; break; + case OpPtrNotEqual: *hasResult = true; *hasResultType = true; break; + case OpPtrDiff: *hasResult = true; *hasResultType = true; break; + case OpColorAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case OpDepthAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case OpStencilAttachmentReadEXT: *hasResult = true; *hasResultType = true; break; + case OpTerminateInvocation: *hasResult = false; *hasResultType = false; break; + case OpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; + case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; + case OpTraceRayKHR: *hasResult = false; *hasResultType = false; break; + case OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; + case OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; + case OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case OpSDot: *hasResult = true; *hasResultType = true; break; + case OpUDot: *hasResult = true; *hasResultType = true; break; + case OpSUDot: *hasResult = true; *hasResultType = true; break; + case OpSDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpUDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpSUDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpTypeCooperativeMatrixKHR: *hasResult = true; *hasResultType = false; break; + case OpCooperativeMatrixLoadKHR: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixStoreKHR: *hasResult = false; *hasResultType = false; break; + case OpCooperativeMatrixMulAddKHR: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixLengthKHR: *hasResult = true; *hasResultType = true; break; + case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; + case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; + case OpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; + case OpImageSampleWeightedQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBoxFilterQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchSSDQCOM: *hasResult = true; *hasResultType = true; break; + case OpImageBlockMatchSADQCOM: *hasResult = true; *hasResultType = true; break; + case OpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; + case OpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; + case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; + case OpReadClockKHR: *hasResult = true; *hasResultType = true; break; + case OpHitObjectRecordHitMotionNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordHitWithIndexMotionNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordMissMotionNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectGetWorldToObjectNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetObjectToWorldNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetObjectRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetObjectRayOriginNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectGetShaderRecordBufferHandleNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetShaderBindingTableRecordIndexNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectRecordEmptyNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectTraceRayNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordHitNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordHitWithIndexNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectRecordMissNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectExecuteShaderNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectGetCurrentTimeNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetAttributesNV: *hasResult = false; *hasResultType = false; break; + case OpHitObjectGetHitKindNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetPrimitiveIndexNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetGeometryIndexNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetInstanceIdNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetInstanceCustomIndexNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetWorldRayDirectionNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetWorldRayOriginNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetRayTMaxNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectGetRayTMinNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectIsEmptyNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectIsHitNV: *hasResult = true; *hasResultType = true; break; + case OpHitObjectIsMissNV: *hasResult = true; *hasResultType = true; break; + case OpReorderThreadWithHitObjectNV: *hasResult = false; *hasResultType = false; break; + case OpReorderThreadWithHintNV: *hasResult = false; *hasResultType = false; break; + case OpTypeHitObjectNV: *hasResult = true; *hasResultType = false; break; + case OpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case OpEmitMeshTasksEXT: *hasResult = false; *hasResultType = false; break; + case OpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break; + case OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; + case OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; + case OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; + case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; + case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break; + case OpTraceNV: *hasResult = false; *hasResultType = false; break; + case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break; + case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; + case OpRayQueryGetIntersectionTriangleVertexPositionsKHR: *hasResult = true; *hasResultType = true; break; + case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; + case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; + case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; + case OpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; + case OpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; + case OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; + case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; + case OpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; + case OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case OpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; + case OpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; + case OpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; + case OpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; + case OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; + case OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; + case OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; + case OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; + case OpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case OpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; + case OpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; + case OpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAverageINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAverageINTEL: *hasResult = true; *hasResultType = true; break; + case OpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case OpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; + case OpISubSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; + case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; + case OpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; + case OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; + case OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; + case OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; + case OpExpectKHR: *hasResult = true; *hasResultType = true; break; + case OpDecorateString: *hasResult = false; *hasResultType = false; break; + case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; + case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; + case OpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; + case OpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; + case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; + case OpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; + case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case OpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; + case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; + case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; + case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; + case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; + case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; + case OpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; + case OpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; + } +} +#endif /* SPV_ENABLE_UTILITY_CODE */ + +// Overload bitwise operators for mask bit combining + +inline ImageOperandsMask operator|(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) | unsigned(b)); } +inline ImageOperandsMask operator&(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) & unsigned(b)); } +inline ImageOperandsMask operator^(ImageOperandsMask a, ImageOperandsMask b) { return ImageOperandsMask(unsigned(a) ^ unsigned(b)); } +inline ImageOperandsMask operator~(ImageOperandsMask a) { return ImageOperandsMask(~unsigned(a)); } +inline FPFastMathModeMask operator|(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) | unsigned(b)); } +inline FPFastMathModeMask operator&(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) & unsigned(b)); } +inline FPFastMathModeMask operator^(FPFastMathModeMask a, FPFastMathModeMask b) { return FPFastMathModeMask(unsigned(a) ^ unsigned(b)); } +inline FPFastMathModeMask operator~(FPFastMathModeMask a) { return FPFastMathModeMask(~unsigned(a)); } +inline SelectionControlMask operator|(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) | unsigned(b)); } +inline SelectionControlMask operator&(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) & unsigned(b)); } +inline SelectionControlMask operator^(SelectionControlMask a, SelectionControlMask b) { return SelectionControlMask(unsigned(a) ^ unsigned(b)); } +inline SelectionControlMask operator~(SelectionControlMask a) { return SelectionControlMask(~unsigned(a)); } +inline LoopControlMask operator|(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) | unsigned(b)); } +inline LoopControlMask operator&(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) & unsigned(b)); } +inline LoopControlMask operator^(LoopControlMask a, LoopControlMask b) { return LoopControlMask(unsigned(a) ^ unsigned(b)); } +inline LoopControlMask operator~(LoopControlMask a) { return LoopControlMask(~unsigned(a)); } +inline FunctionControlMask operator|(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) | unsigned(b)); } +inline FunctionControlMask operator&(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) & unsigned(b)); } +inline FunctionControlMask operator^(FunctionControlMask a, FunctionControlMask b) { return FunctionControlMask(unsigned(a) ^ unsigned(b)); } +inline FunctionControlMask operator~(FunctionControlMask a) { return FunctionControlMask(~unsigned(a)); } +inline MemorySemanticsMask operator|(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) | unsigned(b)); } +inline MemorySemanticsMask operator&(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) & unsigned(b)); } +inline MemorySemanticsMask operator^(MemorySemanticsMask a, MemorySemanticsMask b) { return MemorySemanticsMask(unsigned(a) ^ unsigned(b)); } +inline MemorySemanticsMask operator~(MemorySemanticsMask a) { return MemorySemanticsMask(~unsigned(a)); } +inline MemoryAccessMask operator|(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) | unsigned(b)); } +inline MemoryAccessMask operator&(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) & unsigned(b)); } +inline MemoryAccessMask operator^(MemoryAccessMask a, MemoryAccessMask b) { return MemoryAccessMask(unsigned(a) ^ unsigned(b)); } +inline MemoryAccessMask operator~(MemoryAccessMask a) { return MemoryAccessMask(~unsigned(a)); } +inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) | unsigned(b)); } +inline KernelProfilingInfoMask operator&(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) & unsigned(b)); } +inline KernelProfilingInfoMask operator^(KernelProfilingInfoMask a, KernelProfilingInfoMask b) { return KernelProfilingInfoMask(unsigned(a) ^ unsigned(b)); } +inline KernelProfilingInfoMask operator~(KernelProfilingInfoMask a) { return KernelProfilingInfoMask(~unsigned(a)); } +inline RayFlagsMask operator|(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) | unsigned(b)); } +inline RayFlagsMask operator&(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) & unsigned(b)); } +inline RayFlagsMask operator^(RayFlagsMask a, RayFlagsMask b) { return RayFlagsMask(unsigned(a) ^ unsigned(b)); } +inline RayFlagsMask operator~(RayFlagsMask a) { return RayFlagsMask(~unsigned(a)); } +inline FragmentShadingRateMask operator|(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) | unsigned(b)); } +inline FragmentShadingRateMask operator&(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) & unsigned(b)); } +inline FragmentShadingRateMask operator^(FragmentShadingRateMask a, FragmentShadingRateMask b) { return FragmentShadingRateMask(unsigned(a) ^ unsigned(b)); } +inline FragmentShadingRateMask operator~(FragmentShadingRateMask a) { return FragmentShadingRateMask(~unsigned(a)); } +inline CooperativeMatrixOperandsMask operator|(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) | unsigned(b)); } +inline CooperativeMatrixOperandsMask operator&(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) & unsigned(b)); } +inline CooperativeMatrixOperandsMask operator^(CooperativeMatrixOperandsMask a, CooperativeMatrixOperandsMask b) { return CooperativeMatrixOperandsMask(unsigned(a) ^ unsigned(b)); } +inline CooperativeMatrixOperandsMask operator~(CooperativeMatrixOperandsMask a) { return CooperativeMatrixOperandsMask(~unsigned(a)); } + +} // end namespace spv + +#endif // #ifndef spirv_HPP + diff --git a/src/libraries/glslang/SPIRV/spvIR.h b/src/libraries/glslang/SPIRV/spvIR.h index 486e80d00..8849f42e7 100644 --- a/src/libraries/glslang/SPIRV/spvIR.h +++ b/src/libraries/glslang/SPIRV/spvIR.h @@ -97,6 +97,8 @@ class Instruction { explicit Instruction(Op opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), block(nullptr) { } virtual ~Instruction() {} void addIdOperand(Id id) { + // ids can't be 0 + assert(id); operands.push_back(id); idOperand.push_back(true); } @@ -111,27 +113,23 @@ class Instruction { void addStringOperand(const char* str) { - unsigned int word; - char* wordString = (char*)&word; - char* wordPtr = wordString; - int charCount = 0; + unsigned int word = 0; + unsigned int shiftAmount = 0; char c; + do { c = *(str++); - *(wordPtr++) = c; - ++charCount; - if (charCount == 4) { + word |= ((unsigned int)c) << shiftAmount; + shiftAmount += 8; + if (shiftAmount == 32) { addImmediateOperand(word); - wordPtr = wordString; - charCount = 0; + word = 0; + shiftAmount = 0; } } while (c != 0); // deal with partial last word - if (charCount > 0) { - // pad with 0s - for (; charCount < 4; ++charCount) - *(wordPtr++) = 0; + if (shiftAmount > 0) { addImmediateOperand(word); } } @@ -325,7 +323,7 @@ void inReadableOrder(Block* root, std::function& getBlocks() const { return blocks; } void addLocalVariable(std::unique_ptr inst); Id getReturnType() const { return functionInstruction.getTypeId(); } + Id getFuncId() const { return functionInstruction.getResultId(); } + Id getFuncTypeId() const { return functionInstruction.getIdOperand(1); } void setReturnPrecision(Decoration precision) { if (precision == DecorationRelaxedPrecision) @@ -361,6 +361,14 @@ class Function { Decoration getReturnPrecision() const { return reducedPrecisionReturn ? DecorationRelaxedPrecision : NoPrecision; } + void setDebugLineInfo(Id fileName, int line, int column) { + lineInstruction = std::unique_ptr{new Instruction(OpLine)}; + lineInstruction->addIdOperand(fileName); + lineInstruction->addImmediateOperand(line); + lineInstruction->addImmediateOperand(column); + } + bool hasDebugLineInfo() const { return lineInstruction != nullptr; } + void setImplicitThis() { implicitThis = true; } bool hasImplicitThis() const { return implicitThis; } @@ -377,6 +385,11 @@ class Function { void dump(std::vector& out) const { + // OpLine + if (lineInstruction != nullptr) { + lineInstruction->dump(out); + } + // OpFunction functionInstruction.dump(out); @@ -390,17 +403,23 @@ class Function { end.dump(out); } + LinkageType getLinkType() const { return linkType; } + const char* getExportName() const { return exportName.c_str(); } + protected: Function(const Function&); Function& operator=(Function&); Module& parent; + std::unique_ptr lineInstruction; Instruction functionInstruction; std::vector parameterInstructions; std::vector blocks; bool implicitThis; // true if this is a member function expecting to be passed a 'this' as the first argument bool reducedPrecisionReturn; std::set reducedPrecisionParams; // list of parameter indexes that need a relaxed precision arg + LinkageType linkType; + std::string exportName; }; // @@ -460,9 +479,11 @@ class Module { // 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), - reducedPrecisionReturn(false) +__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, LinkageType linkage, const std::string& name, Module& parent) + : parent(parent), lineInstruction(nullptr), + functionInstruction(id, resultType, OpFunction), implicitThis(false), + reducedPrecisionReturn(false), + linkType(linkage) { // OpFunction functionInstruction.addImmediateOperand(FunctionControlMaskNone); @@ -478,6 +499,11 @@ __inline Function::Function(Id id, Id resultType, Id functionType, Id firstParam parent.mapInstruction(param); parameterInstructions.push_back(param); } + + // If importing/exporting, save the function name (without the mangled parameters) for the linkage decoration + if (linkType != LinkageTypeMax) { + exportName = name.substr(0, name.find_first_of('(')); + } } __inline void Function::addLocalVariable(std::unique_ptr inst) diff --git a/src/libraries/glslang/OGLCompilersDLL/InitializeDll.h b/src/libraries/glslang/glslang/ExtensionHeaders/GL_EXT_shader_realtime_clock.glsl similarity index 79% rename from src/libraries/glslang/OGLCompilersDLL/InitializeDll.h rename to src/libraries/glslang/glslang/ExtensionHeaders/GL_EXT_shader_realtime_clock.glsl index 661cee4d2..7cf545d94 100644 --- a/src/libraries/glslang/OGLCompilersDLL/InitializeDll.h +++ b/src/libraries/glslang/glslang/ExtensionHeaders/GL_EXT_shader_realtime_clock.glsl @@ -1,5 +1,9 @@ // // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2013-2016 LunarG, Inc. +// Copyright (C) 2016-2020 Google, Inc. +// Modifications Copyright(C) 2021 Advanced Micro Devices, Inc.All rights reserved. +// // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -31,19 +35,4 @@ // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // -#ifndef __INITIALIZEDLL_H -#define __INITIALIZEDLL_H - -#include "../glslang/OSDependent/osinclude.h" - -namespace glslang { - -bool InitProcess(); -bool InitThread(); -bool DetachThread(); // not called from standalone, perhaps other tools rely on parts of it -bool DetachProcess(); // not called from standalone, perhaps other tools rely on parts of it - -} // end namespace glslang - -#endif // __INITIALIZEDLL_H diff --git a/src/libraries/glslang/glslang/GenericCodeGen/CodeGen.cpp b/src/libraries/glslang/glslang/GenericCodeGen/CodeGen.cpp index b3c7226df..1ef244962 100644 --- a/src/libraries/glslang/glslang/GenericCodeGen/CodeGen.cpp +++ b/src/libraries/glslang/glslang/GenericCodeGen/CodeGen.cpp @@ -41,10 +41,9 @@ // class TGenericCompiler : public TCompiler { public: - TGenericCompiler(EShLanguage l, int dOptions) : TCompiler(l, infoSink), debugOptions(dOptions) { } + TGenericCompiler(EShLanguage l) : TCompiler(l, infoSink) {} virtual bool compile(TIntermNode* root, int version = 0, EProfile profile = ENoProfile); TInfoSink infoSink; - int debugOptions; }; // @@ -52,10 +51,7 @@ class TGenericCompiler : public TCompiler { // compile object used by higher level code. It returns // a subclass of TCompiler. // -TCompiler* ConstructCompiler(EShLanguage language, int debugOptions) -{ - return new TGenericCompiler(language, debugOptions); -} +TCompiler* ConstructCompiler(EShLanguage language, int) { return new TGenericCompiler(language); } // // Delete the compiler made by ConstructCompiler diff --git a/src/libraries/glslang/glslang/GenericCodeGen/Link.cpp b/src/libraries/glslang/glslang/GenericCodeGen/Link.cpp index c38db0f69..5df39b814 100644 --- a/src/libraries/glslang/glslang/GenericCodeGen/Link.cpp +++ b/src/libraries/glslang/glslang/GenericCodeGen/Link.cpp @@ -44,11 +44,10 @@ // class TGenericLinker : public TLinker { public: - TGenericLinker(EShExecutable e, int dOptions) : TLinker(e, infoSink), debugOptions(dOptions) { } + TGenericLinker(EShExecutable e) : TLinker(e, infoSink) {} bool link(TCompilerList&, TUniformMap*) { return true; } void getAttributeBindings(ShBindingTable const **) const { } TInfoSink infoSink; - int debugOptions; }; // @@ -60,10 +59,7 @@ class TUniformLinkedMap : public TUniformMap { virtual int getLocation(const char*) { return 0; } }; -TShHandleBase* ConstructLinker(EShExecutable executable, int debugOptions) -{ - return new TGenericLinker(executable, debugOptions); -} +TShHandleBase* ConstructLinker(EShExecutable executable, int) { return new TGenericLinker(executable); } void DeleteLinker(TShHandleBase* linker) { @@ -82,7 +78,7 @@ void DeleteUniformMap(TUniformMap* map) TShHandleBase* ConstructBindings() { - return 0; + return nullptr; } void DeleteBindingList(TShHandleBase* bindingList) diff --git a/src/libraries/glslang/glslang/Include/BaseTypes.h b/src/libraries/glslang/glslang/Include/BaseTypes.h old mode 100644 new mode 100755 index c8203c223..64bffa892 --- a/src/libraries/glslang/glslang/Include/BaseTypes.h +++ b/src/libraries/glslang/glslang/Include/BaseTypes.h @@ -65,10 +65,10 @@ enum TBasicType { EbtAccStruct, EbtReference, EbtRayQuery, -#ifndef GLSLANG_WEB + EbtHitObjectNV, + EbtCoopmat, // SPIR-V type defined by spirv_type EbtSpirvType, -#endif // HLSL types that live only temporarily. EbtString, @@ -95,15 +95,16 @@ enum TStorageQualifier { EvqUniform, // read only, shared with app EvqBuffer, // read/write, shared with app EvqShared, // compute shader's read/write 'shared' qualifier -#ifndef GLSLANG_WEB EvqSpirvStorageClass, // spirv_storage_class -#endif EvqPayload, EvqPayloadIn, EvqHitAttr, EvqCallableData, EvqCallableDataIn, + EvqHitObjectAttrNV, + + EvqtaskPayloadSharedEXT, // parameters EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter @@ -128,6 +129,9 @@ enum TStorageQualifier { // built-ins written by fragment shader EvqFragColor, EvqFragDepth, + EvqFragStencil, + + EvqTileImageEXT, // end of list EvqLast @@ -263,6 +267,7 @@ enum TBuiltInVariable { EbvObjectRayDirection, EbvRayTmin, EbvRayTmax, + EbvCullMask, EbvHitT, EbvHitKind, EbvObjectToWorld, @@ -274,6 +279,8 @@ enum TBuiltInVariable { // barycentrics EbvBaryCoordNV, EbvBaryCoordNoPerspNV, + EbvBaryCoordEXT, + EbvBaryCoordNoPerspEXT, // mesh shaders EbvTaskCountNV, EbvPrimitiveCountNV, @@ -284,6 +291,17 @@ enum TBuiltInVariable { EbvMeshViewCountNV, EbvMeshViewIndicesNV, + EbvMicroTrianglePositionNV, + EbvMicroTriangleBaryNV, + EbvHitKindFrontFacingMicroTriangleNV, + EbvHitKindBackFacingMicroTriangleNV, + + //GL_EXT_mesh_shader + EbvPrimitivePointIndicesEXT, + EbvPrimitiveLineIndicesEXT, + EbvPrimitiveTriangleIndicesEXT, + EbvCullPrimitiveEXT, + // sm builtins EbvWarpsPerSM, EbvSMCount, @@ -305,6 +323,15 @@ enum TBuiltInVariable { EbvByteAddressBuffer, EbvRWByteAddressBuffer, + // ARM specific core builtins + EbvCoreCountARM, + EbvCoreIDARM, + EbvCoreMaxIDARM, + EbvWarpIDARM, + EbvWarpMaxIDARM, + + EbvPositionFetch, + EbvLast }; @@ -317,10 +344,6 @@ enum TPrecisionQualifier { 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 __inline const char* GetStorageQualifierString(TStorageQualifier q) { @@ -329,9 +352,7 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q) case EvqGlobal: return "global"; break; case EvqConst: return "const"; break; case EvqConstReadOnly: return "const (read only)"; break; -#ifndef GLSLANG_WEB case EvqSpirvStorageClass: return "spirv_storage_class"; break; -#endif case EvqVaryingIn: return "in"; break; case EvqVaryingOut: return "out"; break; case EvqUniform: return "uniform"; break; @@ -350,11 +371,14 @@ __inline const char* GetStorageQualifierString(TStorageQualifier q) case EvqPointCoord: return "gl_PointCoord"; break; case EvqFragColor: return "fragColor"; break; case EvqFragDepth: return "gl_FragDepth"; break; + case EvqFragStencil: return "gl_FragStencilRefARB"; break; case EvqPayload: return "rayPayloadNV"; break; case EvqPayloadIn: return "rayPayloadInNV"; break; case EvqHitAttr: return "hitAttributeNV"; break; case EvqCallableData: return "callableDataNV"; break; case EvqCallableDataIn: return "callableDataInNV"; break; + case EvqtaskPayloadSharedEXT: return "taskPayloadSharedEXT"; break; + case EvqHitObjectAttrNV:return "hitObjectAttributeNV"; break; default: return "unknown qualifier"; } } @@ -478,8 +502,10 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvWorldToObject: return "WorldToObjectNV"; case EbvCurrentRayTimeNV: return "CurrentRayTimeNV"; - case EbvBaryCoordNV: return "BaryCoordNV"; - case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspNV"; + case EbvBaryCoordEXT: + case EbvBaryCoordNV: return "BaryCoordKHR"; + case EbvBaryCoordNoPerspEXT: + case EbvBaryCoordNoPerspNV: return "BaryCoordNoPerspKHR"; case EbvTaskCountNV: return "TaskCountNV"; case EbvPrimitiveCountNV: return "PrimitiveCountNV"; @@ -489,6 +515,11 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvLayerPerViewNV: return "LayerPerViewNV"; case EbvMeshViewCountNV: return "MeshViewCountNV"; case EbvMeshViewIndicesNV: return "MeshViewIndicesNV"; + // GL_EXT_mesh_shader + case EbvPrimitivePointIndicesEXT: return "PrimitivePointIndicesEXT"; + case EbvPrimitiveLineIndicesEXT: return "PrimitiveLineIndicesEXT"; + case EbvPrimitiveTriangleIndicesEXT: return "PrimitiveTriangleIndicesEXT"; + case EbvCullPrimitiveEXT: return "CullPrimitiveEXT"; case EbvWarpsPerSM: return "WarpsPerSMNV"; case EbvSMCount: return "SMCountNV"; @@ -498,6 +529,9 @@ __inline const char* GetBuiltInVariableString(TBuiltInVariable v) case EbvShadingRateKHR: return "ShadingRateKHR"; case EbvPrimitiveShadingRateKHR: return "PrimitiveShadingRateKHR"; + case EbvHitKindFrontFacingMicroTriangleNV: return "HitKindFrontFacingMicroTriangleNV"; + case EbvHitKindBackFacingMicroTriangleNV: return "HitKindBackFacingMicroTriangleNV"; + default: return "unknown built-in variable"; } } @@ -512,7 +546,6 @@ __inline const char* GetPrecisionQualifierString(TPrecisionQualifier p) default: return "unknown precision qualifier"; } } -#endif __inline bool isTypeSignedInt(TBasicType type) { diff --git a/src/libraries/glslang/glslang/Include/Common.h b/src/libraries/glslang/glslang/Include/Common.h index 9042a1aa2..af7dfe625 100644 --- a/src/libraries/glslang/glslang/Include/Common.h +++ b/src/libraries/glslang/glslang/Include/Common.h @@ -44,6 +44,7 @@ #else #include #endif +#include #include #include #include @@ -54,7 +55,7 @@ #include #include -#if defined(__ANDROID__) || (defined(_MSC_VER) && _MSC_VER < 1700) +#if defined(__ANDROID__) #include namespace std { template @@ -66,7 +67,7 @@ std::string to_string(const T& val) { } #endif -#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) || MINGW_HAS_SECURE_API +#if defined(MINGW_HAS_SECURE_API) && MINGW_HAS_SECURE_API #include #ifndef snprintf #define snprintf sprintf_s @@ -82,22 +83,6 @@ std::string to_string(const T& val) { #define UINT_PTR uintptr_t #endif -#if defined(_MSC_VER) && _MSC_VER < 1800 - #include - inline long long int strtoll (const char* str, char** endptr, int base) - { - return _strtoi64(str, endptr, base); - } - inline unsigned long long int strtoull (const char* str, char** endptr, int base) - { - return _strtoui64(str, endptr, base); - } - inline long long int atoll (const char* str) - { - return strtoll(str, NULL, 10); - } -#endif - #if defined(_MSC_VER) #define strdup _strdup #endif @@ -218,7 +203,7 @@ template T Max(const T a, const T b) { return a > b ? a : b; } // // Create a TString object from an integer. // -#if defined _MSC_VER || MINGW_HAS_SECURE_API +#if defined(_MSC_VER) || (defined(MINGW_HAS_SECURE_API) && MINGW_HAS_SECURE_API) inline const TString String(const int i, const int base = 10) { char text[16]; // 32 bit ints are at most 10 digits in base 10 @@ -307,34 +292,6 @@ template int IntLog2(T n) return result; } -inline bool IsInfinity(double x) { -#ifdef _MSC_VER - switch (_fpclass(x)) { - case _FPCLASS_NINF: - case _FPCLASS_PINF: - return true; - default: - return false; - } -#else - return std::isinf(x); -#endif -} - -inline bool IsNan(double x) { -#ifdef _MSC_VER - switch (_fpclass(x)) { - case _FPCLASS_SNAN: - case _FPCLASS_QNAN: - return true; - default: - return false; - } -#else - return std::isnan(x); -#endif -} - } // end namespace glslang #endif // _COMMON_INCLUDED_ diff --git a/src/libraries/glslang/glslang/Include/ConstantUnion.h b/src/libraries/glslang/glslang/Include/ConstantUnion.h index c4ffb8577..da4737b65 100644 --- a/src/libraries/glslang/glslang/Include/ConstantUnion.h +++ b/src/libraries/glslang/glslang/Include/ConstantUnion.h @@ -234,7 +234,6 @@ class TConstUnion { break; -#ifndef GLSLANG_WEB case EbtInt16: if (constant.i16Const == i16Const) return true; @@ -265,7 +264,6 @@ class TConstUnion { return true; break; -#endif default: assert(false && "Default missing"); } @@ -347,7 +345,6 @@ class TConstUnion { return true; return false; -#ifndef GLSLANG_WEB case EbtInt8: if (i8Const > constant.i8Const) return true; @@ -378,7 +375,6 @@ class TConstUnion { return true; return false; -#endif default: assert(false && "Default missing"); return false; @@ -389,7 +385,6 @@ class TConstUnion { { assert(type == constant.type); switch (type) { -#ifndef GLSLANG_WEB case EbtInt8: if (i8Const < constant.i8Const) return true; @@ -419,7 +414,6 @@ class TConstUnion { return true; return false; -#endif case EbtDouble: if (dConst < constant.dConst) return true; @@ -449,14 +443,12 @@ class TConstUnion { 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 EbtInt16: returnValue.setI16Const(i16Const + constant.i16Const); break; case EbtInt64: returnValue.setI64Const(i64Const + constant.i64Const); break; case EbtUint8: returnValue.setU8Const(u8Const + constant.u8Const); break; case EbtUint16: returnValue.setU16Const(u16Const + constant.u16Const); break; case EbtUint64: returnValue.setU64Const(u64Const + constant.u64Const); break; -#endif default: assert(false && "Default missing"); } @@ -471,14 +463,12 @@ class TConstUnion { 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 EbtInt16: returnValue.setI16Const(i16Const - constant.i16Const); break; case EbtInt64: returnValue.setI64Const(i64Const - constant.i64Const); break; case EbtUint8: returnValue.setU8Const(u8Const - constant.u8Const); break; case EbtUint16: returnValue.setU16Const(u16Const - constant.u16Const); break; case EbtUint64: returnValue.setU64Const(u64Const - constant.u64Const); break; -#endif default: assert(false && "Default missing"); } @@ -493,14 +483,12 @@ class TConstUnion { 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 EbtInt16: returnValue.setI16Const(i16Const * constant.i16Const); break; case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break; case EbtUint8: returnValue.setU8Const(u8Const * constant.u8Const); break; case EbtUint16: returnValue.setU16Const(u16Const * constant.u16Const); break; case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break; -#endif default: assert(false && "Default missing"); } @@ -514,14 +502,12 @@ class TConstUnion { 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 EbtInt16: returnValue.setI8Const(i8Const % constant.i16Const); break; + case EbtInt16: returnValue.setI16Const(i16Const % constant.i16Const); break; case EbtInt64: returnValue.setI64Const(i64Const % constant.i64Const); break; case EbtUint8: returnValue.setU8Const(u8Const % constant.u8Const); break; case EbtUint16: returnValue.setU16Const(u16Const % constant.u16Const); break; case EbtUint64: returnValue.setU64Const(u64Const % constant.u64Const); break; -#endif default: assert(false && "Default missing"); } @@ -532,7 +518,6 @@ class TConstUnion { { TConstUnion returnValue; switch (type) { -#ifndef GLSLANG_WEB case EbtInt8: switch (constant.type) { case EbtInt8: returnValue.setI8Const(i8Const >> constant.i8Const); break; @@ -585,19 +570,16 @@ class TConstUnion { default: assert(false && "Default missing"); } 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; @@ -605,18 +587,15 @@ class TConstUnion { 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; -#ifndef GLSLANG_WEB case EbtInt64: switch (constant.type) { case EbtInt8: returnValue.setI64Const(i64Const >> constant.i8Const); break; @@ -643,7 +622,6 @@ class TConstUnion { default: assert(false && "Default missing"); } break; -#endif default: assert(false && "Default missing"); } @@ -654,7 +632,6 @@ class TConstUnion { { TConstUnion returnValue; switch (type) { -#ifndef GLSLANG_WEB case EbtInt8: switch (constant.type) { case EbtInt8: returnValue.setI8Const(i8Const << constant.i8Const); break; @@ -733,19 +710,16 @@ class TConstUnion { default: assert(false && "Default missing"); } 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; @@ -753,14 +727,12 @@ class TConstUnion { 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; @@ -777,14 +749,12 @@ class TConstUnion { 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 EbtUint8: returnValue.setU8Const(u8Const & constant.u8Const); break; case EbtInt16: returnValue.setI16Const(i16Const & constant.i16Const); break; case EbtUint16: returnValue.setU16Const(u16Const & constant.u16Const); break; case EbtInt64: returnValue.setI64Const(i64Const & constant.i64Const); break; case EbtUint64: returnValue.setU64Const(u64Const & constant.u64Const); break; -#endif default: assert(false && "Default missing"); } @@ -798,14 +768,12 @@ class TConstUnion { 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 EbtUint8: returnValue.setU8Const(u8Const | constant.u8Const); break; case EbtInt16: returnValue.setI16Const(i16Const | constant.i16Const); break; case EbtUint16: returnValue.setU16Const(u16Const | constant.u16Const); break; case EbtInt64: returnValue.setI64Const(i64Const | constant.i64Const); break; case EbtUint64: returnValue.setU64Const(u64Const | constant.u64Const); break; -#endif default: assert(false && "Default missing"); } @@ -819,14 +787,12 @@ class TConstUnion { 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 EbtUint8: returnValue.setU8Const(u8Const ^ constant.u8Const); break; case EbtInt16: returnValue.setI16Const(i16Const ^ constant.i16Const); break; case EbtUint16: returnValue.setU16Const(u16Const ^ constant.u16Const); break; case EbtInt64: returnValue.setI64Const(i64Const ^ constant.i64Const); break; case EbtUint64: returnValue.setU64Const(u64Const ^ constant.u64Const); break; -#endif default: assert(false && "Default missing"); } @@ -839,14 +805,12 @@ class TConstUnion { switch (type) { case EbtInt: returnValue.setIConst(~iConst); break; case EbtUint: returnValue.setUConst(~uConst); break; -#ifndef GLSLANG_WEB case EbtInt8: returnValue.setI8Const(~i8Const); break; case EbtUint8: returnValue.setU8Const(~u8Const); break; case EbtInt16: returnValue.setI16Const(~i16Const); break; case EbtUint16: returnValue.setU16Const(~u16Const); break; case EbtInt64: returnValue.setI64Const(~i64Const); break; case EbtUint64: returnValue.setU64Const(~u64Const); break; -#endif default: assert(false && "Default missing"); } diff --git a/src/libraries/glslang/glslang/Include/InitializeGlobals.h b/src/libraries/glslang/glslang/Include/InitializeGlobals.h index 95d0a40e9..b7fdd7aab 100644 --- a/src/libraries/glslang/glslang/Include/InitializeGlobals.h +++ b/src/libraries/glslang/glslang/Include/InitializeGlobals.h @@ -37,7 +37,7 @@ namespace glslang { -bool InitializePoolIndex(); +inline bool InitializePoolIndex() { return true; } // DEPRECATED: No need to call } // end namespace glslang diff --git a/src/libraries/glslang/glslang/Include/PoolAlloc.h b/src/libraries/glslang/glslang/Include/PoolAlloc.h index 1f5cac76d..e84ac52cd 100644 --- a/src/libraries/glslang/glslang/Include/PoolAlloc.h +++ b/src/libraries/glslang/glslang/Include/PoolAlloc.h @@ -37,7 +37,7 @@ #ifndef _POOLALLOC_INCLUDED_ #define _POOLALLOC_INCLUDED_ -#ifdef _DEBUG +#ifndef NDEBUG # define GUARD_BLOCKS // define to enable guard block sanity checking #endif @@ -74,7 +74,7 @@ namespace glslang { class TAllocation { public: - TAllocation(size_t size, unsigned char* mem, TAllocation* prev = 0) : + TAllocation(size_t size, unsigned char* mem, TAllocation* prev = nullptr) : size(size), mem(mem), prevAlloc(prev) { // Allocations are bracketed: // [allocationHeader][initialGuardBlock][userData][finalGuardBlock] @@ -118,11 +118,16 @@ class TAllocation { unsigned char* mem; // beginning of our allocation (pts to header) TAllocation* prevAlloc; // prior allocation in the chain - const static unsigned char guardBlockBeginVal; - const static unsigned char guardBlockEndVal; - const static unsigned char userDataFill; + static inline constexpr unsigned char guardBlockBeginVal = 0xfb; + static inline constexpr unsigned char guardBlockEndVal = 0xfe; + static inline constexpr unsigned char userDataFill = 0xcd; + +# ifdef GUARD_BLOCKS + static inline constexpr size_t guardBlockSize = 16; +# else + static inline constexpr size_t guardBlockSize = 0; +# endif - const static size_t guardBlockSize; # ifdef GUARD_BLOCKS inline static size_t headerSize() { return sizeof(TAllocation); } # else @@ -171,7 +176,7 @@ class TPoolAllocator { void popAll(); // - // Call allocate() to actually acquire memory. Returns 0 if no memory + // Call allocate() to actually acquire memory. Returns nullptr if no memory // available, otherwise a properly aligned pointer to 'numBytes' of memory. // void* allocate(size_t numBytes); @@ -189,7 +194,7 @@ class TPoolAllocator { struct tHeader { tHeader(tHeader* nextPage, size_t pageCount) : #ifdef GUARD_BLOCKS - lastAllocation(0), + lastAllocation(nullptr), #endif nextPage(nextPage), pageCount(pageCount) { } diff --git a/src/libraries/glslang/glslang/Include/ResourceLimits.h b/src/libraries/glslang/glslang/Include/ResourceLimits.h index b670cf163..b36c8d627 100644 --- a/src/libraries/glslang/glslang/Include/ResourceLimits.h +++ b/src/libraries/glslang/glslang/Include/ResourceLimits.h @@ -142,6 +142,15 @@ struct TBuiltInResource { int maxTaskWorkGroupSizeY_NV; int maxTaskWorkGroupSizeZ_NV; int maxMeshViewCountNV; + int maxMeshOutputVerticesEXT; + int maxMeshOutputPrimitivesEXT; + int maxMeshWorkGroupSizeX_EXT; + int maxMeshWorkGroupSizeY_EXT; + int maxMeshWorkGroupSizeZ_EXT; + int maxTaskWorkGroupSizeX_EXT; + int maxTaskWorkGroupSizeY_EXT; + int maxTaskWorkGroupSizeZ_EXT; + int maxMeshViewCountEXT; int maxDualSourceDrawBuffersEXT; TLimits limits; diff --git a/src/libraries/glslang/glslang/Include/ShHandle.h b/src/libraries/glslang/glslang/Include/ShHandle.h index df07bd8ed..dee47c0df 100644 --- a/src/libraries/glslang/glslang/Include/ShHandle.h +++ b/src/libraries/glslang/glslang/Include/ShHandle.h @@ -58,9 +58,9 @@ class TShHandleBase { public: TShHandleBase() { pool = new glslang::TPoolAllocator; } virtual ~TShHandleBase() { delete pool; } - virtual TCompiler* getAsCompiler() { return 0; } - virtual TLinker* getAsLinker() { return 0; } - virtual TUniformMap* getAsUniformMap() { return 0; } + virtual TCompiler* getAsCompiler() { return nullptr; } + virtual TLinker* getAsLinker() { return nullptr; } + virtual TUniformMap* getAsUniformMap() { return nullptr; } virtual glslang::TPoolAllocator* getPool() const { return pool; } private: glslang::TPoolAllocator* pool; @@ -123,11 +123,11 @@ class TLinker : public TShHandleBase { infoSink(iSink), executable(e), haveReturnableObjectCode(false), - appAttributeBindings(0), - fixedAttributeBindings(0), - excludedAttributes(0), + appAttributeBindings(nullptr), + fixedAttributeBindings(nullptr), + excludedAttributes(nullptr), excludedCount(0), - uniformBindings(0) { } + uniformBindings(nullptr) { } virtual TLinker* getAsLinker() { return this; } virtual ~TLinker() { } virtual bool link(TCompilerList&, TUniformMap*) = 0; @@ -137,7 +137,7 @@ class TLinker : public TShHandleBase { virtual void getAttributeBindings(ShBindingTable const **t) const = 0; virtual void setExcludedAttributes(const int* attributes, int count) { excludedAttributes = attributes; excludedCount = count; } virtual ShBindingTable* getUniformBindings() const { return uniformBindings; } - virtual const void* getObjectCode() const { return 0; } // a real compiler would be returning object code here + virtual const void* getObjectCode() const { return nullptr; } // a real compiler would be returning object code here virtual TInfoSink& getInfoSink() { return infoSink; } TInfoSink& infoSink; protected: diff --git a/src/libraries/glslang/glslang/Include/SpirvIntrinsics.h b/src/libraries/glslang/glslang/Include/SpirvIntrinsics.h index 3c7d72ce9..0082a4d4e 100644 --- a/src/libraries/glslang/glslang/Include/SpirvIntrinsics.h +++ b/src/libraries/glslang/glslang/Include/SpirvIntrinsics.h @@ -35,12 +35,11 @@ #pragma once -#ifndef GLSLANG_WEB - // // GL_EXT_spirv_intrinsics // #include "Common.h" +#include namespace glslang { @@ -98,12 +97,27 @@ struct TSpirvInstruction { struct TSpirvTypeParameter { POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) - TSpirvTypeParameter(const TIntermConstantUnion* arg) { constant = arg; } + TSpirvTypeParameter(const TIntermConstantUnion* arg) { value = arg; } + TSpirvTypeParameter(const TType* arg) { value = arg; } - bool operator==(const TSpirvTypeParameter& rhs) const { return constant == rhs.constant; } + const TIntermConstantUnion* getAsConstant() const + { + if (value.index() == 0) + return std::get(value); + return nullptr; + } + const TType* getAsType() const + { + if (value.index() == 1) + return std::get(value); + return nullptr; + } + + bool operator==(const TSpirvTypeParameter& rhs) const; bool operator!=(const TSpirvTypeParameter& rhs) const { return !operator==(rhs); } - const TIntermConstantUnion* constant; + // Parameter value: constant expression or type specifier + std::variant value; }; typedef TVector TSpirvTypeParameters; @@ -124,5 +138,3 @@ struct TSpirvType { }; } // end namespace glslang - -#endif // GLSLANG_WEB diff --git a/src/libraries/glslang/glslang/Include/Types.h b/src/libraries/glslang/glslang/Include/Types.h index 9c1f960ed..1fb59e5bf 100644 --- a/src/libraries/glslang/glslang/Include/Types.h +++ b/src/libraries/glslang/glslang/Include/Types.h @@ -72,6 +72,7 @@ enum TSamplerDim { EsdRect, EsdBuffer, EsdSubpass, // goes only with non-sampled image (image is true) + EsdAttachmentEXT, EsdNumDims }; @@ -85,19 +86,6 @@ struct TSampler { // misnomer now; includes images, textures without sampler, bool combined : 1; // true means texture is combined with a sampler, false means texture with no sampler bool sampler : 1; // true means a pure sampler, other fields should be clear() -#ifdef GLSLANG_WEB - bool is1D() const { return false; } - bool isBuffer() const { return false; } - bool isRect() const { return false; } - bool isSubpass() const { return false; } - bool isCombined() const { return true; } - bool isImage() const { return false; } - bool isImageClass() const { return false; } - bool isMultiSample() const { return false; } - bool isExternal() const { return false; } - void setExternal(bool e) { } - bool isYuv() const { return false; } -#else unsigned int vectorSize : 3; // vector return type size. // Some languages support structures as sample results. Storing the whole structure in the // TSampler is too large, so there is an index to a separate table. @@ -122,14 +110,14 @@ struct TSampler { // misnomer now; includes images, textures without sampler, bool isBuffer() const { return dim == EsdBuffer; } bool isRect() const { return dim == EsdRect; } bool isSubpass() const { return dim == EsdSubpass; } + bool isAttachmentEXT() const { return dim == EsdAttachmentEXT; } bool isCombined() const { return combined; } - bool isImage() const { return image && !isSubpass(); } + bool isImage() const { return image && !isSubpass() && !isAttachmentEXT();} bool isImageClass() const { return image; } bool isMultiSample() const { return ms; } bool isExternal() const { return external; } void setExternal(bool e) { external = e; } bool isYuv() const { return yuv; } -#endif bool isTexture() const { return !sampler && !image; } bool isPureSampler() const { return sampler; } @@ -149,10 +137,8 @@ struct TSampler { // misnomer now; includes images, textures without sampler, image = false; combined = false; sampler = false; -#ifndef GLSLANG_WEB external = false; yuv = false; -#endif #ifdef ENABLE_HLSL clearReturnStruct(); @@ -204,7 +190,6 @@ struct TSampler { // misnomer now; includes images, textures without sampler, shadow = s; } -#ifndef GLSLANG_WEB // make a subpass input attachment void setSubpass(TBasicType t, bool m = false) { @@ -214,7 +199,15 @@ struct TSampler { // misnomer now; includes images, textures without sampler, dim = EsdSubpass; ms = m; } -#endif + + // make an AttachmentEXT + void setAttachmentEXT(TBasicType t) + { + clear(); + type = t; + image = true; + dim = EsdAttachmentEXT; + } bool operator==(const TSampler& right) const { @@ -252,7 +245,6 @@ struct TSampler { // misnomer now; includes images, textures without sampler, switch (type) { case EbtInt: s.append("i"); break; case EbtUint: s.append("u"); break; -#ifndef GLSLANG_WEB case EbtFloat16: s.append("f16"); break; case EbtInt8: s.append("i8"); break; case EbtUint16: s.append("u8"); break; @@ -260,11 +252,12 @@ struct TSampler { // misnomer now; includes images, textures without sampler, case EbtUint8: s.append("u16"); break; case EbtInt64: s.append("i64"); break; case EbtUint64: s.append("u64"); break; -#endif default: break; } if (isImageClass()) { - if (isSubpass()) + if (isAttachmentEXT()) + s.append("attachmentEXT"); + else if (isSubpass()) s.append("subpass"); else s.append("image"); @@ -284,12 +277,11 @@ struct TSampler { // misnomer now; includes images, textures without sampler, case Esd2D: s.append("2D"); break; case Esd3D: s.append("3D"); break; case EsdCube: s.append("Cube"); break; -#ifndef GLSLANG_WEB - case Esd1D: s.append("1D"); break; - case EsdRect: s.append("2DRect"); break; - case EsdBuffer: s.append("Buffer"); break; - case EsdSubpass: s.append("Input"); break; -#endif + case Esd1D: s.append("1D"); break; + case EsdRect: s.append("2DRect"); break; + case EsdBuffer: s.append("Buffer"); break; + case EsdSubpass: s.append("Input"); break; + case EsdAttachmentEXT: s.append(""); break; default: break; // some compilers want this } if (isMultiSample()) @@ -429,6 +421,12 @@ enum TLayoutFormat { ElfR16ui, ElfR8ui, ElfR64ui, + ElfExtSizeGuard, // to help with comparisons + ElfSize1x8, + ElfSize1x16, + ElfSize1x32, + ElfSize2x32, + ElfSize4x32, ElfCount }; @@ -443,6 +441,18 @@ enum TLayoutDepth { EldCount }; +enum TLayoutStencil { + ElsNone, + ElsRefUnchangedFrontAMD, + ElsRefGreaterFrontAMD, + ElsRefLessFrontAMD, + ElsRefUnchangedBackAMD, + ElsRefGreaterBackAMD, + ElsRefLessBackAMD, + + ElsCount +}; + enum TBlendEquationShift { // No 'EBlendNone': // These are used as bit-shift amounts. A mask of such shifts will have type 'int', @@ -500,12 +510,10 @@ class TQualifier { invariant = false; makeTemporary(); declaredBuiltIn = EbvNone; -#ifndef GLSLANG_WEB noContraction = false; nullInit = false; spirvByReference = false; spirvLiteral = false; -#endif defaultBlock = false; } @@ -522,21 +530,17 @@ class TQualifier { nullInit = false; defaultBlock = false; clearLayout(); -#ifndef GLSLANG_WEB spirvStorageClass = -1; spirvDecorate = nullptr; spirvByReference = false; spirvLiteral = false; -#endif } void clearInterstage() { clearInterpolation(); -#ifndef GLSLANG_WEB patch = false; sample = false; -#endif } void clearInterpolation() @@ -544,19 +548,17 @@ class TQualifier { centroid = false; smooth = false; flat = false; -#ifndef GLSLANG_WEB nopersp = false; explicitInterp = false; pervertexNV = false; perPrimitiveNV = false; perViewNV = false; perTaskNV = false; -#endif + pervertexEXT = false; } void clearMemory() { -#ifndef GLSLANG_WEB coherent = false; devicecoherent = false; queuefamilycoherent = false; @@ -568,7 +570,6 @@ class TQualifier { restrict = false; readonly = false; writeonly = false; -#endif } const char* semanticName; @@ -587,34 +588,11 @@ class TQualifier { bool explicitOffset : 1; bool defaultBlock : 1; // default blocks with matching names have structures merged when linking -#ifdef GLSLANG_WEB - bool isWriteOnly() const { return false; } - bool isReadOnly() const { return false; } - bool isRestrict() const { return false; } - bool isCoherent() const { return false; } - bool isVolatile() const { return false; } - bool isSample() const { return false; } - bool isMemory() const { return false; } - bool isMemoryQualifierImageAndSSBOOnly() const { return false; } - bool bufferReferenceNeedsVulkanMemoryModel() const { return false; } - bool isInterpolation() const { return flat || smooth; } - bool isExplicitInterpolation() const { return false; } - bool isAuxiliary() const { return centroid; } - bool isPatch() const { return false; } - bool isNoContraction() const { return false; } - void setNoContraction() { } - bool isPervertexNV() const { return false; } - void setNullInit() { } - bool isNullInit() const { return false; } - void setSpirvByReference() { } - bool isSpirvByReference() { return false; } - void setSpirvLiteral() { } - bool isSpirvLiteral() { return false; } -#else bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects bool nopersp : 1; bool explicitInterp : 1; bool pervertexNV : 1; + bool pervertexEXT : 1; bool perPrimitiveNV : 1; bool perViewNV : 1; bool perTaskNV : 1; @@ -663,19 +641,19 @@ class TQualifier { } bool isAuxiliary() const { - return centroid || patch || sample || pervertexNV; + return centroid || patch || sample || pervertexNV || pervertexEXT; } bool isPatch() const { return patch; } bool isNoContraction() const { return noContraction; } void setNoContraction() { noContraction = true; } bool isPervertexNV() const { return pervertexNV; } + bool isPervertexEXT() const { return pervertexEXT; } void setNullInit() { nullInit = true; } bool isNullInit() const { return nullInit; } void setSpirvByReference() { spirvByReference = true; } bool isSpirvByReference() const { return spirvByReference; } void setSpirvLiteral() { spirvLiteral = true; } bool isSpirvLiteral() const { return spirvLiteral; } -#endif bool isPipeInput() const { @@ -701,6 +679,7 @@ class TQualifier { case EvqVaryingOut: case EvqFragColor: case EvqFragDepth: + case EvqFragStencil: return true; default: return false; @@ -768,6 +747,7 @@ class TQualifier { case EvqVaryingOut: case EvqFragColor: case EvqFragDepth: + case EvqFragStencil: return true; default: return false; @@ -804,9 +784,7 @@ class TQualifier { } void setBlockStorage(TBlockStorageClass newBacking) { -#ifndef GLSLANG_WEB layoutPushConstant = (newBacking == EbsPushConstant); -#endif switch (newBacking) { case EbsUniform : if (layoutPacking == ElpStd430) { @@ -815,35 +793,32 @@ class TQualifier { } storage = EvqUniform; break; - case EbsStorageBuffer : + case EbsStorageBuffer : storage = EvqBuffer; break; -#ifndef GLSLANG_WEB case EbsPushConstant : storage = EvqUniform; layoutSet = TQualifier::layoutSetEnd; layoutBinding = TQualifier::layoutBindingEnd; break; -#endif default: break; } } -#ifdef GLSLANG_WEB - bool isPerView() const { return false; } - bool isTaskMemory() const { return false; } - bool isArrayedIo(EShLanguage language) const { return false; } -#else bool isPerPrimitive() const { return perPrimitiveNV; } bool isPerView() const { return perViewNV; } bool isTaskMemory() const { return perTaskNV; } + bool isTaskPayload() const { return storage == EvqtaskPayloadSharedEXT; } bool isAnyPayload() const { return storage == EvqPayload || storage == EvqPayloadIn; } bool isAnyCallable() const { return storage == EvqCallableData || storage == EvqCallableDataIn; } + bool isHitObjectAttrNV() const { + return storage == EvqHitObjectAttrNV; + } // True if this type of IO is supposed to be arrayed with extra level for per-vertex data bool isArrayedIo(EShLanguage language) const @@ -856,22 +831,20 @@ class TQualifier { case EShLangTessEvaluation: return ! patch && isPipeInput(); case EShLangFragment: - return pervertexNV && isPipeInput(); - case EShLangMeshNV: + return (pervertexNV || pervertexEXT) && isPipeInput(); + case EShLangMesh: return ! perTaskNV && isPipeOutput(); default: return false; } } -#endif // Implementing an embedded layout-qualifier class here, since C++ can't have a real class bitfield void clearLayout() // all layout { clearUniformLayout(); -#ifndef GLSLANG_WEB layoutPushConstant = false; layoutBufferReference = false; layoutPassthrough = false; @@ -879,9 +852,11 @@ class TQualifier { // -2048 as the default value indicating layoutSecondaryViewportRelative is not set layoutSecondaryViewportRelativeOffset = -2048; layoutShaderRecord = false; + layoutHitObjectShaderRecordNV = false; + layoutBindlessSampler = false; + layoutBindlessImage = false; layoutBufferReferenceAlign = layoutBufferReferenceAlignEnd; layoutFormat = ElfNone; -#endif clearInterstageLayout(); @@ -891,14 +866,11 @@ class TQualifier { { layoutLocation = layoutLocationEnd; layoutComponent = layoutComponentEnd; -#ifndef GLSLANG_WEB layoutIndex = layoutIndexEnd; clearStreamLayout(); clearXfbLayout(); -#endif } -#ifndef GLSLANG_WEB void clearStreamLayout() { layoutStream = layoutStreamEnd; @@ -909,7 +881,6 @@ class TQualifier { layoutXfbStride = layoutXfbStrideEnd; layoutXfbOffset = layoutXfbOffsetEnd; } -#endif bool hasNonXfbLayout() const { @@ -965,7 +936,6 @@ class TQualifier { unsigned int layoutSpecConstantId : 11; static const unsigned int layoutSpecConstantIdEnd = 0x7FF; -#ifndef GLSLANG_WEB // stored as log2 of the actual alignment value unsigned int layoutBufferReferenceAlign : 6; static const unsigned int layoutBufferReferenceAlignEnd = 0x3F; @@ -978,11 +948,14 @@ class TQualifier { bool layoutViewportRelative; int layoutSecondaryViewportRelativeOffset; bool layoutShaderRecord; + bool layoutHitObjectShaderRecordNV; // GL_EXT_spirv_intrinsics int spirvStorageClass; TSpirvDecorate* spirvDecorate; -#endif + + bool layoutBindlessSampler; + bool layoutBindlessImage; bool hasUniformLayout() const { @@ -1002,9 +975,7 @@ class TQualifier { layoutSet = layoutSetEnd; layoutBinding = layoutBindingEnd; -#ifndef GLSLANG_WEB layoutAttachment = layoutAttachmentEnd; -#endif } bool hasMatrix() const @@ -1037,26 +1008,6 @@ class TQualifier { { return layoutBinding != layoutBindingEnd; } -#ifdef GLSLANG_WEB - bool hasOffset() const { return false; } - bool isNonPerspective() const { return false; } - bool hasIndex() const { return false; } - unsigned getIndex() const { return 0; } - bool hasComponent() const { return false; } - bool hasStream() const { return false; } - bool hasFormat() const { return false; } - bool hasXfb() const { return false; } - bool hasXfbBuffer() const { return false; } - bool hasXfbStride() const { return false; } - bool hasXfbOffset() const { return false; } - bool hasAttachment() const { return false; } - TLayoutFormat getFormat() const { return ElfNone; } - bool isPushConstant() const { return false; } - bool isShaderRecord() const { return false; } - bool hasBufferReference() const { return false; } - bool hasBufferReferenceAlign() const { return false; } - bool isNonUniform() const { return false; } -#else bool hasOffset() const { return layoutOffset != layoutNotSet; @@ -1104,6 +1055,7 @@ class TQualifier { TLayoutFormat getFormat() const { return layoutFormat; } bool isPushConstant() const { return layoutPushConstant; } bool isShaderRecord() const { return layoutShaderRecord; } + bool hasHitObjectShaderRecordNV() const { return layoutHitObjectShaderRecordNV; } bool hasBufferReference() const { return layoutBufferReference; } bool hasBufferReferenceAlign() const { @@ -1113,16 +1065,24 @@ class TQualifier { { return nonUniform; } + bool isBindlessSampler() const + { + return layoutBindlessSampler; + } + bool isBindlessImage() const + { + return layoutBindlessImage; + } // GL_EXT_spirv_intrinsics - bool hasSprivDecorate() const { return spirvDecorate != nullptr; } + bool hasSpirvDecorate() const { return spirvDecorate != nullptr; } void setSpirvDecorate(int decoration, const TIntermAggregate* args = nullptr); void setSpirvDecorateId(int decoration, const TIntermAggregate* args); void setSpirvDecorateString(int decoration, const TIntermAggregate* args); const TSpirvDecorate& getSpirvDecorate() const { assert(spirvDecorate); return *spirvDecorate; } TSpirvDecorate& getSpirvDecorate() { assert(spirvDecorate); return *spirvDecorate; } TString getSpirvDecorateQualifierString() const; -#endif + bool hasSpecConstantId() const { // Not the same thing as being a specialization constant, this @@ -1156,12 +1116,10 @@ class TQualifier { { switch (packing) { case ElpStd140: return "std140"; -#ifndef GLSLANG_WEB case ElpPacked: return "packed"; case ElpShared: return "shared"; case ElpStd430: return "std430"; case ElpScalar: return "scalar"; -#endif default: return "none"; } } @@ -1173,9 +1131,6 @@ class TQualifier { default: return "none"; } } -#ifdef GLSLANG_WEB - static const char* getLayoutFormatString(TLayoutFormat f) { return "none"; } -#else static const char* getLayoutFormatString(TLayoutFormat f) { switch (f) { @@ -1222,6 +1177,11 @@ class TQualifier { case ElfR8ui: return "r8ui"; case ElfR64ui: return "r64ui"; case ElfR64i: return "r64i"; + case ElfSize1x8: return "size1x8"; + case ElfSize1x16: return "size1x16"; + case ElfSize1x32: return "size1x32"; + case ElfSize2x32: return "size2x32"; + case ElfSize4x32: return "size4x32"; default: return "none"; } } @@ -1235,6 +1195,18 @@ class TQualifier { default: return "none"; } } + static const char* getLayoutStencilString(TLayoutStencil s) + { + switch (s) { + case ElsRefUnchangedFrontAMD: return "stencil_ref_unchanged_front_amd"; + case ElsRefGreaterFrontAMD: return "stencil_ref_greater_front_amd"; + case ElsRefLessFrontAMD: return "stencil_ref_less_front_amd"; + case ElsRefUnchangedBackAMD: return "stencil_ref_unchanged_back_amd"; + case ElsRefGreaterBackAMD: return "stencil_ref_greater_back_amd"; + case ElsRefLessBackAMD: return "stencil_ref_less_back_amd"; + default: return "none"; + } + } static const char* getBlendEquationString(TBlendEquationShift e) { switch (e) { @@ -1312,7 +1284,6 @@ class TQualifier { default: return "none"; } } -#endif }; // Qualifiers that don't need to be keep per object. They have shader scope, not object scope. @@ -1329,10 +1300,14 @@ struct TShaderQualifiers { int localSize[3]; // compute shader bool localSizeNotDefault[3]; // compute shader int localSizeSpecId[3]; // compute shader specialization id for gl_WorkGroupSize -#ifndef GLSLANG_WEB bool earlyFragmentTests; // fragment input bool postDepthCoverage; // fragment input + bool earlyAndLateFragmentTestsAMD; //fragment input + bool nonCoherentColorAttachmentReadEXT; // fragment input + bool nonCoherentDepthAttachmentReadEXT; // fragment input + bool nonCoherentStencilAttachmentReadEXT; // fragment input TLayoutDepth layoutDepth; + TLayoutStencil layoutStencil; bool blendEquation; // true if any blend equation was specified int numViews; // multiview extenstions TInterlockOrdering interlockOrdering; @@ -1342,9 +1317,7 @@ struct TShaderQualifiers { int primitives; // mesh shader "max_primitives"DerivativeGroupLinear; // true if layout derivative_group_linearNV set bool layoutPrimitiveCulling; // true if layout primitive_culling set TLayoutDepth getDepth() const { return layoutDepth; } -#else - TLayoutDepth getDepth() const { return EldNone; } -#endif + TLayoutStencil getStencil() const { return layoutStencil; } void init() { @@ -1365,10 +1338,14 @@ struct TShaderQualifiers { localSizeSpecId[0] = TQualifier::layoutNotSet; localSizeSpecId[1] = TQualifier::layoutNotSet; localSizeSpecId[2] = TQualifier::layoutNotSet; -#ifndef GLSLANG_WEB earlyFragmentTests = false; + earlyAndLateFragmentTestsAMD = false; postDepthCoverage = false; + nonCoherentColorAttachmentReadEXT = false; + nonCoherentDepthAttachmentReadEXT = false; + nonCoherentStencilAttachmentReadEXT = false; layoutDepth = EldNone; + layoutStencil = ElsNone; blendEquation = false; numViews = TQualifier::layoutNotSet; layoutOverrideCoverage = false; @@ -1377,14 +1354,9 @@ struct TShaderQualifiers { layoutPrimitiveCulling = false; primitives = TQualifier::layoutNotSet; interlockOrdering = EioNone; -#endif } -#ifdef GLSLANG_WEB - bool hasBlendEquation() const { return false; } -#else bool hasBlendEquation() const { return blendEquation; } -#endif // Merge in characteristics from the 'src' qualifier. They can override when // set, but never erase when not set. @@ -1417,13 +1389,22 @@ struct TShaderQualifiers { if (src.localSizeSpecId[i] != TQualifier::layoutNotSet) localSizeSpecId[i] = src.localSizeSpecId[i]; } -#ifndef GLSLANG_WEB if (src.earlyFragmentTests) earlyFragmentTests = true; + if (src.earlyAndLateFragmentTestsAMD) + earlyAndLateFragmentTestsAMD = true; if (src.postDepthCoverage) postDepthCoverage = true; + if (src.nonCoherentColorAttachmentReadEXT) + nonCoherentColorAttachmentReadEXT = true; + if (src.nonCoherentDepthAttachmentReadEXT) + nonCoherentDepthAttachmentReadEXT = true; + if (src.nonCoherentStencilAttachmentReadEXT) + nonCoherentStencilAttachmentReadEXT = true; if (src.layoutDepth) layoutDepth = src.layoutDepth; + if (src.layoutStencil) + layoutStencil = src.layoutStencil; if (src.blendEquation) blendEquation = src.blendEquation; if (src.numViews != TQualifier::layoutNotSet) @@ -1440,10 +1421,22 @@ struct TShaderQualifiers { interlockOrdering = src.interlockOrdering; if (src.layoutPrimitiveCulling) layoutPrimitiveCulling = src.layoutPrimitiveCulling; -#endif } }; +class TTypeParameters { +public: + POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) + + TTypeParameters() : basicType(EbtVoid), arraySizes(nullptr) {} + + TBasicType basicType; + TArraySizes *arraySizes; + + bool operator==(const TTypeParameters& rhs) const { return basicType == rhs.basicType && *arraySizes == *rhs.arraySizes; } + bool operator!=(const TTypeParameters& rhs) const { return basicType != rhs.basicType || *arraySizes != *rhs.arraySizes; } +}; + // // TPublicType is just temporarily used while parsing and not quite the same // information kept per node in TType. Due to the bison stack, it can't have @@ -1458,39 +1451,35 @@ class TPublicType { TSampler sampler; TQualifier qualifier; TShaderQualifiers shaderQualifiers; - int vectorSize : 4; - int matrixCols : 4; - int matrixRows : 4; - bool coopmat : 1; + uint32_t vectorSize : 4; + uint32_t matrixCols : 4; + uint32_t matrixRows : 4; + bool coopmatNV : 1; + bool coopmatKHR : 1; TArraySizes* arraySizes; const TType* userDef; TSourceLoc loc; - TArraySizes* typeParameters; -#ifndef GLSLANG_WEB + TTypeParameters* typeParameters; // SPIR-V type defined by spirv_type directive TSpirvType* spirvType; -#endif -#ifdef GLSLANG_WEB - bool isCoopmat() const { return false; } -#else - bool isCoopmat() const { return coopmat; } -#endif + bool isCoopmat() const { return coopmatNV || coopmatKHR; } + bool isCoopmatNV() const { return coopmatNV; } + bool isCoopmatKHR() const { return coopmatKHR; } void initType(const TSourceLoc& l) { basicType = EbtVoid; - vectorSize = 1; + vectorSize = 1u; matrixRows = 0; matrixCols = 0; arraySizes = nullptr; userDef = nullptr; loc = l; typeParameters = nullptr; - coopmat = false; -#ifndef GLSLANG_WEB + coopmatNV = false; + coopmatKHR = false; spirvType = nullptr; -#endif } void initQualifiers(bool global = false) @@ -1512,29 +1501,31 @@ class TPublicType { { matrixRows = 0; matrixCols = 0; - vectorSize = s; + assert(s >= 0); + vectorSize = static_cast(s) & 0b1111; } void setMatrix(int c, int r) { - matrixRows = r; - matrixCols = c; + assert(r >= 0); + matrixRows = static_cast(r) & 0b1111; + assert(c >= 0); + matrixCols = static_cast(c) & 0b1111; vectorSize = 0; } bool isScalar() const { - return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr; + return matrixCols == 0u && vectorSize == 1u && arraySizes == nullptr && userDef == nullptr; } -#ifndef GLSLANG_WEB // GL_EXT_spirv_intrinsics void setSpirvType(const TSpirvInstruction& spirvInst, const TSpirvTypeParameters* typeParams = nullptr); -#endif // "Image" is a superset of "Subpass" - bool isImage() const { return basicType == EbtSampler && sampler.isImage(); } - bool isSubpass() const { return basicType == EbtSampler && sampler.isSubpass(); } + bool isImage() const { return basicType == EbtSampler && sampler.isImage(); } + bool isSubpass() const { return basicType == EbtSampler && sampler.isSubpass(); } + bool isAttachmentEXT() const { return basicType == EbtSampler && sampler.isAttachmentEXT(); } }; // @@ -1547,12 +1538,14 @@ class TType { // for "empty" type (no args) or simple scalar/vector/matrix explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0, bool isVector = false) : - basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false), - arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr) -#ifndef GLSLANG_WEB - , spirvType(nullptr) -#endif + basicType(t), vectorSize(static_cast(vs) & 0b1111), matrixCols(static_cast(mc) & 0b1111), matrixRows(static_cast(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), + arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr), + spirvType(nullptr) { + assert(vs >= 0); + assert(mc >= 0); + assert(mr >= 0); + sampler.clear(); qualifier.clear(); qualifier.storage = q; @@ -1561,12 +1554,14 @@ class TType { // for explicit precision qualifier TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0, bool isVector = false) : - basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), coopmat(false), - arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr) -#ifndef GLSLANG_WEB - , spirvType(nullptr) -#endif + basicType(t), vectorSize(static_cast(vs) & 0b1111), matrixCols(static_cast(mc) & 0b1111), matrixRows(static_cast(mr) & 0b1111), vector1(isVector && vs == 1), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), + arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr), + spirvType(nullptr) { + assert(vs >= 0); + assert(mc >= 0); + assert(mr >= 0); + sampler.clear(); qualifier.clear(); qualifier.storage = q; @@ -1577,11 +1572,9 @@ class TType { // for turning a TPublicType into a TType, using a shallow copy explicit TType(const TPublicType& p) : basicType(p.basicType), - vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmat(p.coopmat), - arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters) -#ifndef GLSLANG_WEB - , spirvType(p.spirvType) -#endif + vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false), coopmatNV(p.coopmatNV), coopmatKHR(p.coopmatKHR), coopmatKHRuse(0), coopmatKHRUseValid(false), + arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(p.typeParameters), + spirvType(p.spirvType) { if (basicType == EbtSampler) sampler = p.sampler; @@ -1597,28 +1590,42 @@ class TType { } typeName = NewPoolTString(p.userDef->getTypeName().c_str()); } - if (p.isCoopmat() && p.typeParameters && p.typeParameters->getNumDims() > 0) { - int numBits = p.typeParameters->getDimSize(0); + if (p.isCoopmatNV() && p.typeParameters && p.typeParameters->arraySizes->getNumDims() > 0) { + int numBits = p.typeParameters->arraySizes->getDimSize(0); if (p.basicType == EbtFloat && numBits == 16) { basicType = EbtFloat16; qualifier.precision = EpqNone; } else if (p.basicType == EbtUint && numBits == 8) { basicType = EbtUint8; qualifier.precision = EpqNone; + } else if (p.basicType == EbtUint && numBits == 16) { + basicType = EbtUint16; + qualifier.precision = EpqNone; } else if (p.basicType == EbtInt && numBits == 8) { basicType = EbtInt8; qualifier.precision = EpqNone; + } else if (p.basicType == EbtInt && numBits == 16) { + basicType = EbtInt16; + qualifier.precision = EpqNone; + } + } + if (p.isCoopmatKHR() && p.typeParameters && p.typeParameters->arraySizes->getNumDims() > 0) { + basicType = p.typeParameters->basicType; + + if (p.typeParameters->arraySizes->getNumDims() == 4) { + const int dimSize = p.typeParameters->arraySizes->getDimSize(3); + assert(dimSize >= 0); + coopmatKHRuse = static_cast(dimSize) & 0b111; + coopmatKHRUseValid = true; + p.typeParameters->arraySizes->removeLastSize(); } } } // for construction of sampler types TType(const TSampler& sampler, TStorageQualifier q = EvqUniform, TArraySizes* as = nullptr) : - basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false), + basicType(EbtSampler), vectorSize(1u), matrixCols(0u), matrixRows(0u), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr), - sampler(sampler), typeParameters(nullptr) -#ifndef GLSLANG_WEB - , spirvType(nullptr) -#endif + sampler(sampler), typeParameters(nullptr), spirvType(nullptr) { qualifier.clear(); qualifier.storage = q; @@ -1660,18 +1667,19 @@ class TType { vectorSize = 1; vector1 = false; } else if (isCoopMat()) { - coopmat = false; + coopmatNV = false; + coopmatKHR = false; + coopmatKHRuse = 0; + coopmatKHRUseValid = false; typeParameters = nullptr; } } } // for making structures, ... TType(TTypeList* userDef, const TString& n) : - basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false), - arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr) -#ifndef GLSLANG_WEB - , spirvType(nullptr) -#endif + basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), + arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr), + spirvType(nullptr) { sampler.clear(); qualifier.clear(); @@ -1679,25 +1687,22 @@ class TType { } // For interface blocks TType(TTypeList* userDef, const TString& n, const TQualifier& q) : - basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmat(false), - qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr) -#ifndef GLSLANG_WEB - , spirvType(nullptr) -#endif + basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), + qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr), typeParameters(nullptr), + spirvType(nullptr) { sampler.clear(); typeName = NewPoolTString(n.c_str()); } // for block reference (first parameter must be EbtReference) explicit TType(TBasicType t, const TType &p, const TString& n) : - basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), - arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr) -#ifndef GLSLANG_WEB - , spirvType(nullptr) -#endif + basicType(t), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false), coopmatNV(false), coopmatKHR(false), coopmatKHRuse(0), coopmatKHRUseValid(false), + arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr), typeParameters(nullptr), + spirvType(nullptr) { assert(t == EbtReference); typeName = NewPoolTString(n.c_str()); + sampler.clear(); qualifier.clear(); qualifier.storage = p.qualifier.storage; referentType = p.clone(); @@ -1725,10 +1730,11 @@ class TType { referentType = copyOf.referentType; } typeParameters = copyOf.typeParameters; -#ifndef GLSLANG_WEB spirvType = copyOf.spirvType; -#endif - coopmat = copyOf.isCoopMat(); + coopmatNV = copyOf.isCoopMatNV(); + coopmatKHR = copyOf.isCoopMatKHR(); + coopmatKHRuse = copyOf.coopmatKHRuse; + coopmatKHRUseValid = copyOf.coopmatKHRUseValid; } // Make complete copy of the whole type graph rooted at 'copyOf'. @@ -1758,7 +1764,7 @@ class TType { void makeVector() { vector1 = true; } - virtual void hideMember() { basicType = EbtVoid; vectorSize = 1; } + virtual void hideMember() { basicType = EbtVoid; vectorSize = 1u; } virtual bool hiddenMember() const { return basicType == EbtVoid; } virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); } @@ -1798,35 +1804,33 @@ class TType { virtual TQualifier& getQualifier() { return qualifier; } virtual const TQualifier& getQualifier() const { return qualifier; } - virtual int getVectorSize() const { return vectorSize; } // returns 1 for either scalar or vector of size 1, valid for both - virtual int getMatrixCols() const { return matrixCols; } - virtual int getMatrixRows() const { return matrixRows; } + virtual int getVectorSize() const { return static_cast(vectorSize); } // returns 1 for either scalar or vector of size 1, valid for both + virtual int getMatrixCols() const { return static_cast(matrixCols); } + virtual int getMatrixRows() const { return static_cast(matrixRows); } virtual int getOuterArraySize() const { return arraySizes->getOuterSize(); } virtual TIntermTyped* getOuterArrayNode() const { return arraySizes->getOuterNode(); } virtual int getCumulativeArraySize() const { return arraySizes->getCumulativeSize(); } -#ifdef GLSLANG_WEB - bool isArrayOfArrays() const { return false; } -#else bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; } -#endif virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); } virtual const TArraySizes* getArraySizes() const { return arraySizes; } virtual TArraySizes* getArraySizes() { return arraySizes; } virtual TType* getReferentType() const { return referentType; } - virtual const TArraySizes* getTypeParameters() const { return typeParameters; } - virtual TArraySizes* getTypeParameters() { return typeParameters; } + virtual const TTypeParameters* getTypeParameters() const { return typeParameters; } + virtual TTypeParameters* getTypeParameters() { return typeParameters; } virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); } virtual bool isScalarOrVec1() const { return isScalar() || vector1; } virtual bool isScalarOrVector() const { return !isMatrix() && !isStruct() && !isArray(); } - virtual bool isVector() const { return vectorSize > 1 || vector1; } + virtual bool isVector() const { return vectorSize > 1u || vector1; } virtual bool isMatrix() const { return matrixCols ? true : false; } virtual bool isArray() const { return arraySizes != nullptr; } virtual bool isSizedArray() const { return isArray() && arraySizes->isSized(); } virtual bool isUnsizedArray() const { return isArray() && !arraySizes->isSized(); } + virtual bool isImplicitlySizedArray() const { return isArray() && arraySizes->isImplicitlySized(); } virtual bool isArrayVariablyIndexed() const { assert(isArray()); return arraySizes->isVariablyIndexed(); } virtual void setArrayVariablyIndexed() { assert(isArray()); arraySizes->setVariablyIndexed(); } virtual void updateImplicitArraySize(int size) { assert(isArray()); arraySizes->updateImplicitSize(size); } + virtual void setImplicitlySized(bool isImplicitSized) { arraySizes->setImplicitlySized(isImplicitSized); } virtual bool isStruct() const { return basicType == EbtStruct || basicType == EbtBlock; } virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16; } virtual bool isIntegerDomain() const @@ -1848,30 +1852,26 @@ class TType { return false; } virtual bool isOpaque() const { return basicType == EbtSampler -#ifndef GLSLANG_WEB || basicType == EbtAtomicUint || basicType == EbtAccStruct || basicType == EbtRayQuery -#endif - ; } + || basicType == EbtHitObjectNV; } virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; } - // "Image" is a superset of "Subpass" - virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); } + virtual bool isAttachmentEXT() const { return basicType == EbtSampler && getSampler().isAttachmentEXT(); } + virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); } virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); } virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); } + virtual bool isBindlessImage() const { return isImage() && qualifier.layoutBindlessImage; } + virtual bool isBindlessTexture() const { return isTexture() && qualifier.layoutBindlessSampler; } // Check the block-name convention of creating a block without populating it's members: virtual bool isUnusableName() const { return isStruct() && structure == nullptr; } virtual bool isParameterized() const { return typeParameters != nullptr; } -#ifdef GLSLANG_WEB - bool isAtomic() const { return false; } - bool isCoopMat() const { return false; } - bool isReference() const { return false; } - bool isSpirvType() const { return false; } -#else bool isAtomic() const { return basicType == EbtAtomicUint; } - bool isCoopMat() const { return coopmat; } + bool isCoopMat() const { return coopmatNV || coopmatKHR; } + bool isCoopMatNV() const { return coopmatNV; } + bool isCoopMatKHR() const { return coopmatKHR; } bool isReference() const { return getBasicType() == EbtReference; } bool isSpirvType() const { return getBasicType() == EbtSpirvType; } -#endif + int getCoopMatKHRuse() const { return static_cast(coopmatKHRuse); } // return true if this type contains any subtype which satisfies the given predicate. template @@ -1914,6 +1914,11 @@ class TType { return contains([](const TType* t) { return t->isOpaque(); } ); } + virtual bool containsSampler() const + { + return contains([](const TType* t) { return t->isTexture() || t->isImage(); }); + } + // Recursively checks if the type contains a built-in variable virtual bool containsBuiltIn() const { @@ -1952,15 +1957,6 @@ class TType { return contains([](const TType* t) { return t->isArray() && t->arraySizes->isOuterSpecialization(); } ); } -#ifdef GLSLANG_WEB - bool containsDouble() const { return false; } - bool contains16BitFloat() const { return false; } - bool contains64BitInt() const { return false; } - bool contains16BitInt() const { return false; } - bool contains8BitInt() const { return false; } - bool containsCoopMat() const { return false; } - bool containsReference() const { return false; } -#else bool containsDouble() const { return containsBasicType(EbtDouble); @@ -1983,13 +1979,12 @@ class TType { } bool containsCoopMat() const { - return contains([](const TType* t) { return t->coopmat; } ); + return contains([](const TType* t) { return t->coopmatNV || t->coopmatKHR; } ); } bool containsReference() const { return containsBasicType(EbtReference); } -#endif // Array editing methods. Array descriptors can be shared across // type instances. This allows all uses of the same array @@ -2047,8 +2042,12 @@ class TType { // an explicit array. void adoptImplicitArraySizes(bool skipNonvariablyIndexed) { - if (isUnsizedArray() && !(skipNonvariablyIndexed || isArrayVariablyIndexed())) + if (isUnsizedArray() && + (qualifier.builtIn == EbvSampleMask || + !(skipNonvariablyIndexed || isArrayVariablyIndexed()))) { changeOuterArraySize(getImplicitArraySize()); + setImplicitlySized(true); + } // For multi-dim per-view arrays, set unsized inner dimension size to 1 if (qualifier.isPerView() && arraySizes && arraySizes->isInnerUnsized()) arraySizes->clearInnerUnsized(); @@ -2061,43 +2060,12 @@ class TType { } } - - void updateTypeParameters(const TType& type) - { - // For when we may already be sharing existing array descriptors, - // keeping the pointers the same, just updating the contents. - assert(typeParameters != nullptr); - assert(type.typeParameters != nullptr); - *typeParameters = *type.typeParameters; - } - void copyTypeParameters(const TArraySizes& s) + void copyTypeParameters(const TTypeParameters& s) { // For setting a fresh new set of type parameters, not yet worrying about sharing. - typeParameters = new TArraySizes; + typeParameters = new TTypeParameters; *typeParameters = s; } - void transferTypeParameters(TArraySizes* s) - { - // For setting an already allocated set of sizes that this type can use - // (no copy made). - typeParameters = s; - } - void clearTypeParameters() - { - typeParameters = nullptr; - } - - // Add inner array sizes, to any existing sizes, via copy; the - // sizes passed in can still be reused for other purposes. - void copyTypeParametersInnerSizes(const TArraySizes* s) - { - if (s != nullptr) { - if (typeParameters == nullptr) - copyTypeParameters(*s); - else - typeParameters->addInnerSizes(*s); - } - } const char* getBasicString() const { @@ -2111,7 +2079,6 @@ class TType { case EbtInt: return "int"; case EbtUint: return "uint"; case EbtSampler: return "sampler/image"; -#ifndef GLSLANG_WEB case EbtVoid: return "void"; case EbtDouble: return "double"; case EbtFloat16: return "float16_t"; @@ -2130,19 +2097,13 @@ class TType { case EbtReference: return "reference"; case EbtString: return "string"; case EbtSpirvType: return "spirv_type"; -#endif + case EbtCoopmat: return "coopmat"; default: return "unknown type"; } } -#ifdef GLSLANG_WEB - TString getCompleteString() const { return ""; } - const char* getStorageQualifierString() const { return ""; } - const char* getBuiltInVariableString() const { return ""; } - const char* getPrecisionQualifierString() const { return ""; } - TString getBasicTypeString() const { return ""; } -#else - TString getCompleteString() const + TString getCompleteString(bool syntactic = false, bool getQualifiers = true, bool getPrecision = true, + bool getType = true, TString name = "", TString structName = "") const { TString typeString; @@ -2150,232 +2111,354 @@ class TType { const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); }; const auto appendInt = [&](int i) { typeString.append(std::to_string(i).c_str()); }; - if (qualifier.hasSprivDecorate()) + if (getQualifiers) { + if (qualifier.hasSpirvDecorate()) appendStr(qualifier.getSpirvDecorateQualifierString().c_str()); - if (qualifier.hasLayout()) { + if (qualifier.hasLayout()) { // To reduce noise, skip this if the only layout is an xfb_buffer // with no triggering xfb_offset. TQualifier noXfbBuffer = qualifier; noXfbBuffer.layoutXfbBuffer = TQualifier::layoutXfbBufferEnd; if (noXfbBuffer.hasLayout()) { - appendStr("layout("); - if (qualifier.hasAnyLocation()) { - appendStr(" location="); - appendUint(qualifier.layoutLocation); - if (qualifier.hasComponent()) { - appendStr(" component="); - appendUint(qualifier.layoutComponent); - } - if (qualifier.hasIndex()) { - appendStr(" index="); - appendUint(qualifier.layoutIndex); - } - } - if (qualifier.hasSet()) { - appendStr(" set="); - appendUint(qualifier.layoutSet); - } - if (qualifier.hasBinding()) { - appendStr(" binding="); - appendUint(qualifier.layoutBinding); - } - if (qualifier.hasStream()) { - appendStr(" stream="); - appendUint(qualifier.layoutStream); - } - if (qualifier.hasMatrix()) { - appendStr(" "); - appendStr(TQualifier::getLayoutMatrixString(qualifier.layoutMatrix)); - } - if (qualifier.hasPacking()) { - appendStr(" "); - appendStr(TQualifier::getLayoutPackingString(qualifier.layoutPacking)); - } - if (qualifier.hasOffset()) { - appendStr(" offset="); - appendInt(qualifier.layoutOffset); + appendStr("layout("); + if (qualifier.hasAnyLocation()) { + appendStr(" location="); + appendUint(qualifier.layoutLocation); + if (qualifier.hasComponent()) { + appendStr(" component="); + appendUint(qualifier.layoutComponent); } - if (qualifier.hasAlign()) { - appendStr(" align="); - appendInt(qualifier.layoutAlign); + if (qualifier.hasIndex()) { + appendStr(" index="); + appendUint(qualifier.layoutIndex); } - if (qualifier.hasFormat()) { - appendStr(" "); - appendStr(TQualifier::getLayoutFormatString(qualifier.layoutFormat)); - } - if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset()) { - appendStr(" xfb_buffer="); - appendUint(qualifier.layoutXfbBuffer); - } - if (qualifier.hasXfbOffset()) { - appendStr(" xfb_offset="); - appendUint(qualifier.layoutXfbOffset); - } - if (qualifier.hasXfbStride()) { - appendStr(" xfb_stride="); - appendUint(qualifier.layoutXfbStride); - } - if (qualifier.hasAttachment()) { - appendStr(" input_attachment_index="); - appendUint(qualifier.layoutAttachment); - } - if (qualifier.hasSpecConstantId()) { - appendStr(" constant_id="); - appendUint(qualifier.layoutSpecConstantId); - } - if (qualifier.layoutPushConstant) - appendStr(" push_constant"); - if (qualifier.layoutBufferReference) - appendStr(" buffer_reference"); - if (qualifier.hasBufferReferenceAlign()) { - appendStr(" buffer_reference_align="); - appendUint(1u << qualifier.layoutBufferReferenceAlign); - } - - if (qualifier.layoutPassthrough) - appendStr(" passthrough"); - if (qualifier.layoutViewportRelative) - appendStr(" layoutViewportRelative"); - if (qualifier.layoutSecondaryViewportRelativeOffset != -2048) { - appendStr(" layoutSecondaryViewportRelativeOffset="); - appendInt(qualifier.layoutSecondaryViewportRelativeOffset); - } - if (qualifier.layoutShaderRecord) - appendStr(" shaderRecordNV"); - - appendStr(")"); + } + if (qualifier.hasSet()) { + appendStr(" set="); + appendUint(qualifier.layoutSet); + } + if (qualifier.hasBinding()) { + appendStr(" binding="); + appendUint(qualifier.layoutBinding); + } + if (qualifier.hasStream()) { + appendStr(" stream="); + appendUint(qualifier.layoutStream); + } + if (qualifier.hasMatrix()) { + appendStr(" "); + appendStr(TQualifier::getLayoutMatrixString(qualifier.layoutMatrix)); + } + if (qualifier.hasPacking()) { + appendStr(" "); + appendStr(TQualifier::getLayoutPackingString(qualifier.layoutPacking)); + } + if (qualifier.hasOffset()) { + appendStr(" offset="); + appendInt(qualifier.layoutOffset); + } + if (qualifier.hasAlign()) { + appendStr(" align="); + appendInt(qualifier.layoutAlign); + } + if (qualifier.hasFormat()) { + appendStr(" "); + appendStr(TQualifier::getLayoutFormatString(qualifier.layoutFormat)); + } + if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset()) { + appendStr(" xfb_buffer="); + appendUint(qualifier.layoutXfbBuffer); + } + if (qualifier.hasXfbOffset()) { + appendStr(" xfb_offset="); + appendUint(qualifier.layoutXfbOffset); + } + if (qualifier.hasXfbStride()) { + appendStr(" xfb_stride="); + appendUint(qualifier.layoutXfbStride); + } + if (qualifier.hasAttachment()) { + appendStr(" input_attachment_index="); + appendUint(qualifier.layoutAttachment); + } + if (qualifier.hasSpecConstantId()) { + appendStr(" constant_id="); + appendUint(qualifier.layoutSpecConstantId); + } + if (qualifier.layoutPushConstant) + appendStr(" push_constant"); + if (qualifier.layoutBufferReference) + appendStr(" buffer_reference"); + if (qualifier.hasBufferReferenceAlign()) { + appendStr(" buffer_reference_align="); + appendUint(1u << qualifier.layoutBufferReferenceAlign); + } + + if (qualifier.layoutPassthrough) + appendStr(" passthrough"); + if (qualifier.layoutViewportRelative) + appendStr(" layoutViewportRelative"); + if (qualifier.layoutSecondaryViewportRelativeOffset != -2048) { + appendStr(" layoutSecondaryViewportRelativeOffset="); + appendInt(qualifier.layoutSecondaryViewportRelativeOffset); + } + + if (qualifier.layoutShaderRecord) + appendStr(" shaderRecordNV"); + if (qualifier.layoutHitObjectShaderRecordNV) + appendStr(" hitobjectshaderrecordnv"); + + if (qualifier.layoutBindlessSampler) + appendStr(" layoutBindlessSampler"); + if (qualifier.layoutBindlessImage) + appendStr(" layoutBindlessImage"); + + appendStr(")"); } - } + } - if (qualifier.invariant) + if (qualifier.invariant) appendStr(" invariant"); - if (qualifier.noContraction) + if (qualifier.noContraction) appendStr(" noContraction"); - if (qualifier.centroid) + if (qualifier.centroid) appendStr(" centroid"); - if (qualifier.smooth) + if (qualifier.smooth) appendStr(" smooth"); - if (qualifier.flat) + if (qualifier.flat) appendStr(" flat"); - if (qualifier.nopersp) + if (qualifier.nopersp) appendStr(" noperspective"); - if (qualifier.explicitInterp) + if (qualifier.explicitInterp) appendStr(" __explicitInterpAMD"); - if (qualifier.pervertexNV) + if (qualifier.pervertexNV) appendStr(" pervertexNV"); - if (qualifier.perPrimitiveNV) + if (qualifier.pervertexEXT) + appendStr(" pervertexEXT"); + if (qualifier.perPrimitiveNV) appendStr(" perprimitiveNV"); - if (qualifier.perViewNV) + if (qualifier.perViewNV) appendStr(" perviewNV"); - if (qualifier.perTaskNV) + if (qualifier.perTaskNV) appendStr(" taskNV"); - if (qualifier.patch) + if (qualifier.patch) appendStr(" patch"); - if (qualifier.sample) + if (qualifier.sample) appendStr(" sample"); - if (qualifier.coherent) + if (qualifier.coherent) appendStr(" coherent"); - if (qualifier.devicecoherent) + if (qualifier.devicecoherent) appendStr(" devicecoherent"); - if (qualifier.queuefamilycoherent) + if (qualifier.queuefamilycoherent) appendStr(" queuefamilycoherent"); - if (qualifier.workgroupcoherent) + if (qualifier.workgroupcoherent) appendStr(" workgroupcoherent"); - if (qualifier.subgroupcoherent) + if (qualifier.subgroupcoherent) appendStr(" subgroupcoherent"); - if (qualifier.shadercallcoherent) + if (qualifier.shadercallcoherent) appendStr(" shadercallcoherent"); - if (qualifier.nonprivate) + if (qualifier.nonprivate) appendStr(" nonprivate"); - if (qualifier.volatil) + if (qualifier.volatil) appendStr(" volatile"); - if (qualifier.restrict) + if (qualifier.restrict) appendStr(" restrict"); - if (qualifier.readonly) + if (qualifier.readonly) appendStr(" readonly"); - if (qualifier.writeonly) + if (qualifier.writeonly) appendStr(" writeonly"); - if (qualifier.specConstant) + if (qualifier.specConstant) appendStr(" specialization-constant"); - if (qualifier.nonUniform) + if (qualifier.nonUniform) appendStr(" nonuniform"); - if (qualifier.isNullInit()) + if (qualifier.isNullInit()) appendStr(" null-init"); - if (qualifier.isSpirvByReference()) + if (qualifier.isSpirvByReference()) appendStr(" spirv_by_reference"); - if (qualifier.isSpirvLiteral()) + if (qualifier.isSpirvLiteral()) appendStr(" spirv_literal"); - appendStr(" "); - appendStr(getStorageQualifierString()); - if (isArray()) { - for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) { + appendStr(" "); + appendStr(getStorageQualifierString()); + } + if (getType) { + if (syntactic) { + if (getPrecision && qualifier.precision != EpqNone) { + appendStr(" "); + appendStr(getPrecisionQualifierString()); + } + if (isVector() || isMatrix()) { + appendStr(" "); + switch (basicType) { + case EbtDouble: + appendStr("d"); + break; + case EbtInt: + appendStr("i"); + break; + case EbtUint: + appendStr("u"); + break; + case EbtBool: + appendStr("b"); + break; + case EbtFloat: + default: + break; + } + if (isVector()) { + appendStr("vec"); + appendInt(vectorSize); + } else { + appendStr("mat"); + appendInt(matrixCols); + appendStr("x"); + appendInt(matrixRows); + } + } else if (isStruct() && structure) { + appendStr(" "); + appendStr(structName.c_str()); + appendStr("{"); + bool hasHiddenMember = true; + for (size_t i = 0; i < structure->size(); ++i) { + if (!(*structure)[i].type->hiddenMember()) { + if (!hasHiddenMember) + appendStr(", "); + typeString.append((*structure)[i].type->getCompleteString(syntactic, getQualifiers, getPrecision, getType, (*structure)[i].type->getFieldName())); + hasHiddenMember = false; + } + } + appendStr("}"); + } else { + appendStr(" "); + switch (basicType) { + case EbtDouble: + appendStr("double"); + break; + case EbtInt: + appendStr("int"); + break; + case EbtUint: + appendStr("uint"); + break; + case EbtBool: + appendStr("bool"); + break; + case EbtFloat: + appendStr("float"); + break; + default: + appendStr("unexpected"); + break; + } + } + if (name.length() > 0) { + appendStr(" "); + appendStr(name.c_str()); + } + if (isArray()) { + for (int i = 0; i < (int)arraySizes->getNumDims(); ++i) { int size = arraySizes->getDimSize(i); if (size == UnsizedArraySize && i == 0 && arraySizes->isVariablyIndexed()) - appendStr(" runtime-sized array of"); + appendStr("[]"); else { - if (size == UnsizedArraySize) { - appendStr(" unsized"); - if (i == 0) { - appendStr(" "); - appendInt(arraySizes->getImplicitSize()); - } - } else { - appendStr(" "); - appendInt(arraySizes->getDimSize(i)); + if (size == UnsizedArraySize) { + appendStr("["); + if (i == 0) + appendInt(arraySizes->getImplicitSize()); + appendStr("]"); + } + else { + appendStr("["); + appendInt(arraySizes->getDimSize(i)); + appendStr("]"); + } + } + } + } + } + else { + if (isArray()) { + for (int i = 0; i < (int)arraySizes->getNumDims(); ++i) { + int size = arraySizes->getDimSize(i); + if (size == UnsizedArraySize && i == 0 && arraySizes->isVariablyIndexed()) + appendStr(" runtime-sized array of"); + else { + if (size == UnsizedArraySize) { + appendStr(" unsized"); + if (i == 0) { + appendStr(" "); + appendInt(arraySizes->getImplicitSize()); } - appendStr("-element array of"); + } + else { + appendStr(" "); + appendInt(arraySizes->getDimSize(i)); + } + appendStr("-element array of"); } + } } - } - if (isParameterized()) { - appendStr("<"); - for(int i = 0; i < (int)typeParameters->getNumDims(); ++i) { - appendInt(typeParameters->getDimSize(i)); - if (i != (int)typeParameters->getNumDims() - 1) - appendStr(", "); + if (isParameterized()) { + if (isCoopMatKHR()) { + appendStr(" "); + appendStr("coopmat"); + } + + appendStr("<"); + for (int i = 0; i < (int)typeParameters->arraySizes->getNumDims(); ++i) { + appendInt(typeParameters->arraySizes->getDimSize(i)); + if (i != (int)typeParameters->arraySizes->getNumDims() - 1) + appendStr(", "); + } + if (coopmatKHRUseValid) { + appendStr(", "); + appendInt(coopmatKHRuse); + } + appendStr(">"); + } + if (getPrecision && qualifier.precision != EpqNone) { + appendStr(" "); + appendStr(getPrecisionQualifierString()); + } + if (isMatrix()) { + appendStr(" "); + appendInt(matrixCols); + appendStr("X"); + appendInt(matrixRows); + appendStr(" matrix of"); + } + else if (isVector()) { + appendStr(" "); + appendInt(vectorSize); + appendStr("-component vector of"); } - appendStr(">"); - } - if (qualifier.precision != EpqNone) { - appendStr(" "); - appendStr(getPrecisionQualifierString()); - } - if (isMatrix()) { - appendStr(" "); - appendInt(matrixCols); - appendStr("X"); - appendInt(matrixRows); - appendStr(" matrix of"); - } else if (isVector()) { - appendStr(" "); - appendInt(vectorSize); - appendStr("-component vector of"); - } - - appendStr(" "); - typeString.append(getBasicTypeString()); - if (qualifier.builtIn != EbvNone) { appendStr(" "); - appendStr(getBuiltInVariableString()); - } + typeString.append(getBasicTypeString()); - // Add struct/block members - if (isStruct() && structure) { - appendStr("{"); - bool hasHiddenMember = true; - for (size_t i = 0; i < structure->size(); ++i) { - if (! (*structure)[i].type->hiddenMember()) { - if (!hasHiddenMember) - appendStr(", "); - typeString.append((*structure)[i].type->getCompleteString()); - typeString.append(" "); - typeString.append((*structure)[i].type->getFieldName()); - hasHiddenMember = false; + if (qualifier.builtIn != EbvNone) { + appendStr(" "); + appendStr(getBuiltInVariableString()); + } + + // Add struct/block members + if (isStruct() && structure) { + appendStr("{"); + bool hasHiddenMember = true; + for (size_t i = 0; i < structure->size(); ++i) { + if (!(*structure)[i].type->hiddenMember()) { + if (!hasHiddenMember) + appendStr(", "); + typeString.append((*structure)[i].type->getCompleteString()); + typeString.append(" "); + typeString.append((*structure)[i].type->getFieldName()); + hasHiddenMember = false; } + } + appendStr("}"); } - appendStr("}"); + } } return typeString; @@ -2392,16 +2475,19 @@ class TType { const char* getStorageQualifierString() const { return GetStorageQualifierString(qualifier.storage); } const char* getBuiltInVariableString() const { return GetBuiltInVariableString(qualifier.builtIn); } const char* getPrecisionQualifierString() const { return GetPrecisionQualifierString(qualifier.precision); } -#endif const TTypeList* getStruct() const { assert(isStruct()); return structure; } void setStruct(TTypeList* s) { assert(isStruct()); structure = s; } TTypeList* getWritableStruct() const { assert(isStruct()); return structure; } // This should only be used when known to not be sharing with other threads void setBasicType(const TBasicType& t) { basicType = t; } - + void setVectorSize(int s) { + assert(s >= 0); + vectorSize = static_cast(s) & 0b1111; + } + int computeNumComponents() const { - int components = 0; + uint32_t components = 0; if (getBasicType() == EbtStruct || getBasicType() == EbtBlock) { for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++) @@ -2415,7 +2501,7 @@ class TType { components *= arraySizes->getCumulativeSize(); } - return components; + return static_cast(components); } // append this type's mangled name to the passed in 'name' @@ -2444,13 +2530,27 @@ class TType { // type definitions, and member names to be considered the same type. // This rule applies recursively for nested or embedded types." // - bool sameStructType(const TType& right) const + // If type mismatch in structure, return member indices through lpidx and rpidx. + // If matching members for either block are exhausted, return -1 for exhausted + // block and the index of the unmatched member. Otherwise return {-1,-1}. + // + bool sameStructType(const TType& right, int* lpidx = nullptr, int* rpidx = nullptr) const { + // Initialize error to general type mismatch. + if (lpidx != nullptr) { + *lpidx = -1; + *rpidx = -1; + } + // Most commonly, they are both nullptr, or the same pointer to the same actual structure + // TODO: Why return true when neither types are structures? if ((!isStruct() && !right.isStruct()) || (isStruct() && right.isStruct() && structure == right.structure)) return true; + if (!isStruct() || !right.isStruct()) + return false; + // Structure names have to match if (*typeName != *right.typeName) return false; @@ -2460,12 +2560,17 @@ class TType { bool isGLPerVertex = *typeName == "gl_PerVertex"; // Both being nullptr was caught above, now they both have to be structures of the same number of elements - if (!isStruct() || !right.isStruct() || - (structure->size() != right.structure->size() && !isGLPerVertex)) + if (lpidx == nullptr && + (structure->size() != right.structure->size() && !isGLPerVertex)) { return false; + } // Compare the names and types of all the members, which have to match for (size_t li = 0, ri = 0; li < structure->size() || ri < right.structure->size(); ++li, ++ri) { + if (lpidx != nullptr) { + *lpidx = static_cast(li); + *rpidx = static_cast(ri); + } if (li < structure->size() && ri < right.structure->size()) { if ((*structure)[li].type->getFieldName() == (*right.structure)[ri].type->getFieldName()) { if (*(*structure)[li].type != *(*right.structure)[ri].type) @@ -2495,11 +2600,19 @@ class TType { } // If we get here, then there should only be inconsistently declared members left } else if (li < structure->size()) { - if (!(*structure)[li].type->hiddenMember() && !isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName())) + if (!(*structure)[li].type->hiddenMember() && !isInconsistentGLPerVertexMember((*structure)[li].type->getFieldName())) { + if (lpidx != nullptr) { + *rpidx = -1; + } return false; + } } else { - if (!(*right.structure)[ri].type->hiddenMember() && !isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName())) + if (!(*right.structure)[ri].type->hiddenMember() && !isInconsistentGLPerVertexMember((*right.structure)[ri].type->getFieldName())) { + if (lpidx != nullptr) { + *lpidx = -1; + } return false; + } } } @@ -2523,17 +2636,25 @@ class TType { return *referentType == *right.referentType; } - // See if two types match, in all aspects except arrayness - bool sameElementType(const TType& right) const + // See if two types match, in all aspects except arrayness + // If mismatch in structure members, return member indices in lpidx and rpidx. + bool sameElementType(const TType& right, int* lpidx = nullptr, int* rpidx = nullptr) const { - return basicType == right.basicType && sameElementShape(right); + if (lpidx != nullptr) { + *lpidx = -1; + *rpidx = -1; + } + return basicType == right.basicType && sameElementShape(right, lpidx, rpidx); } // See if two type's arrayness match bool sameArrayness(const TType& right) const { return ((arraySizes == nullptr && right.arraySizes == nullptr) || - (arraySizes != nullptr && right.arraySizes != nullptr && *arraySizes == *right.arraySizes)); + (arraySizes != nullptr && right.arraySizes != nullptr && + (*arraySizes == *right.arraySizes || + (arraySizes->isImplicitlySized() && right.arraySizes->isDefaultImplicitlySized()) || + (right.arraySizes->isImplicitlySized() && arraySizes->isDefaultImplicitlySized())))); } // See if two type's arrayness match in everything except their outer dimension @@ -2550,25 +2671,29 @@ class TType { (typeParameters != nullptr && right.typeParameters != nullptr && *typeParameters == *right.typeParameters)); } -#ifndef GLSLANG_WEB // See if two type's SPIR-V type contents match bool sameSpirvType(const TType& right) const { return ((spirvType == nullptr && right.spirvType == nullptr) || (spirvType != nullptr && right.spirvType != nullptr && *spirvType == *right.spirvType)); } -#endif // See if two type's elements match in all ways except basic type - bool sameElementShape(const TType& right) const + // If mismatch in structure members, return member indices in lpidx and rpidx. + bool sameElementShape(const TType& right, int* lpidx = nullptr, int* rpidx = nullptr) const { - return sampler == right.sampler && + if (lpidx != nullptr) { + *lpidx = -1; + *rpidx = -1; + } + return ((basicType != EbtSampler && right.basicType != EbtSampler) || sampler == right.sampler) && vectorSize == right.vectorSize && matrixCols == right.matrixCols && matrixRows == right.matrixRows && vector1 == right.vector1 && - isCoopMat() == right.isCoopMat() && - sameStructType(right) && + isCoopMatNV() == right.isCoopMatNV() && + isCoopMatKHR() == right.isCoopMatKHR() && + sameStructType(right, lpidx, rpidx) && sameReferenceType(right); } @@ -2576,32 +2701,69 @@ class TType { // an OK function parameter bool coopMatParameterOK(const TType& right) const { - return isCoopMat() && right.isCoopMat() && (getBasicType() == right.getBasicType()) && - typeParameters == nullptr && right.typeParameters != nullptr; + if (isCoopMatNV()) { + return right.isCoopMatNV() && (getBasicType() == right.getBasicType()) && typeParameters == nullptr && + right.typeParameters != nullptr; + } + if (isCoopMatKHR() && right.isCoopMatKHR()) { + return ((getBasicType() == right.getBasicType()) || (getBasicType() == EbtCoopmat) || + (right.getBasicType() == EbtCoopmat)) && + typeParameters == nullptr && right.typeParameters != nullptr; + } + return false; } bool sameCoopMatBaseType(const TType &right) const { - bool rv = coopmat && right.coopmat; - if (getBasicType() == EbtFloat || getBasicType() == EbtFloat16) - rv = right.getBasicType() == EbtFloat || right.getBasicType() == EbtFloat16; - else if (getBasicType() == EbtUint || getBasicType() == EbtUint8) - rv = right.getBasicType() == EbtUint || right.getBasicType() == EbtUint8; - else if (getBasicType() == EbtInt || getBasicType() == EbtInt8) - rv = right.getBasicType() == EbtInt || right.getBasicType() == EbtInt8; - else - rv = false; + bool rv = false; + + if (isCoopMatNV()) { + rv = isCoopMatNV() && right.isCoopMatNV(); + if (getBasicType() == EbtFloat || getBasicType() == EbtFloat16) + rv = right.getBasicType() == EbtFloat || right.getBasicType() == EbtFloat16; + else if (getBasicType() == EbtUint || getBasicType() == EbtUint8 || getBasicType() == EbtUint16) + rv = right.getBasicType() == EbtUint || right.getBasicType() == EbtUint8 || right.getBasicType() == EbtUint16; + else if (getBasicType() == EbtInt || getBasicType() == EbtInt8 || getBasicType() == EbtInt16) + rv = right.getBasicType() == EbtInt || right.getBasicType() == EbtInt8 || right.getBasicType() == EbtInt16; + else + rv = false; + } else if (isCoopMatKHR() && right.isCoopMatKHR()) { + if (getBasicType() == EbtFloat || getBasicType() == EbtFloat16) + rv = right.getBasicType() == EbtFloat || right.getBasicType() == EbtFloat16 || right.getBasicType() == EbtCoopmat; + else if (getBasicType() == EbtUint || getBasicType() == EbtUint8 || getBasicType() == EbtUint16) + rv = right.getBasicType() == EbtUint || right.getBasicType() == EbtUint8 || right.getBasicType() == EbtUint16 || right.getBasicType() == EbtCoopmat; + else if (getBasicType() == EbtInt || getBasicType() == EbtInt8 || getBasicType() == EbtInt16) + rv = right.getBasicType() == EbtInt || right.getBasicType() == EbtInt8 || right.getBasicType() == EbtInt16 || right.getBasicType() == EbtCoopmat; + else + rv = false; + } return rv; } + bool sameCoopMatUse(const TType &right) const { + return coopmatKHRuse == right.coopmatKHRuse; + } + + bool sameCoopMatShapeAndUse(const TType &right) const + { + if (!isCoopMat() || !right.isCoopMat() || isCoopMatKHR() != right.isCoopMatKHR()) + return false; + + if (coopmatKHRuse != right.coopmatKHRuse) + return false; + + // Skip bit width type parameter (first array size) for coopmatNV + int firstArrayDimToCompare = isCoopMatNV() ? 1 : 0; + for (int i = firstArrayDimToCompare; i < typeParameters->arraySizes->getNumDims(); ++i) { + if (typeParameters->arraySizes->getDimSize(i) != right.typeParameters->arraySizes->getDimSize(i)) + return false; + } + return true; + } // See if two types match in all ways (just the actual type, not qualification) bool operator==(const TType& right) const { -#ifndef GLSLANG_WEB - return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right) && sameSpirvType(right); -#else - return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right); -#endif + return sameElementType(right) && sameArrayness(right) && sameTypeParameters(right) && sameCoopMatUse(right) && sameSpirvType(right); } bool operator!=(const TType& right) const @@ -2611,18 +2773,14 @@ class TType { unsigned int getBufferReferenceAlignment() const { -#ifndef GLSLANG_WEB if (getBasicType() == glslang::EbtReference) { return getReferentType()->getQualifier().hasBufferReferenceAlign() ? (1u << getReferentType()->getQualifier().layoutBufferReferenceAlign) : 16u; } -#endif return 0; } -#ifndef GLSLANG_WEB const TSpirvType& getSpirvType() const { assert(spirvType); return *spirvType; } -#endif protected: // Require consumer to pick between deep copy and shallow copy. @@ -2636,7 +2794,6 @@ class TType { { shallowCopy(copyOf); -#ifndef GLSLANG_WEB // GL_EXT_spirv_intrinsics if (copyOf.qualifier.spirvDecorate) { qualifier.spirvDecorate = new TSpirvDecorate; @@ -2647,7 +2804,6 @@ class TType { spirvType = new TSpirvType; *spirvType = *copyOf.spirvType; } -#endif if (copyOf.arraySizes) { arraySizes = new TArraySizes; @@ -2655,8 +2811,10 @@ class TType { } if (copyOf.typeParameters) { - typeParameters = new TArraySizes; - *typeParameters = *copyOf.typeParameters; + typeParameters = new TTypeParameters; + typeParameters->arraySizes = new TArraySizes; + *typeParameters->arraySizes = *copyOf.typeParameters->arraySizes; + typeParameters->basicType = copyOf.basicType; } if (copyOf.isStruct() && copyOf.structure) { @@ -2686,15 +2844,18 @@ class TType { void buildMangledName(TString&) const; TBasicType basicType : 8; - int vectorSize : 4; // 1 means either scalar or 1-component vector; see vector1 to disambiguate. - int matrixCols : 4; - int matrixRows : 4; + uint32_t vectorSize : 4; // 1 means either scalar or 1-component vector; see vector1 to disambiguate. + uint32_t matrixCols : 4; + uint32_t matrixRows : 4; bool vector1 : 1; // Backward-compatible tracking of a 1-component vector distinguished from a scalar. // GLSL 4.5 never has a 1-component vector; so this will always be false until such // functionality is added. // HLSL does have a 1-component vectors, so this will be true to disambiguate // from a scalar. - bool coopmat : 1; + bool coopmatNV : 1; + bool coopmatKHR : 1; + uint32_t coopmatKHRuse : 3; // Accepts one of three values: 0, 1, 2 (gl_MatrixUseA, gl_MatrixUseB, gl_MatrixUseAccumulator) + bool coopmatKHRUseValid : 1; // True if coopmatKHRuse has been set TQualifier qualifier; TArraySizes* arraySizes; // nullptr unless an array; can be shared across types @@ -2707,10 +2868,8 @@ class TType { TString *fieldName; // for structure field names TString *typeName; // for structure type name TSampler sampler; - TArraySizes* typeParameters;// nullptr unless a parameterized type; can be shared across types -#ifndef GLSLANG_WEB + TTypeParameters *typeParameters;// nullptr unless a parameterized type; can be shared across types TSpirvType* spirvType; // SPIR-V type defined by spirv_type directive -#endif }; } // end namespace glslang diff --git a/src/libraries/glslang/glslang/Include/arrays.h b/src/libraries/glslang/glslang/Include/arrays.h index 7f047d9fb..91e190835 100644 --- a/src/libraries/glslang/glslang/Include/arrays.h +++ b/src/libraries/glslang/glslang/Include/arrays.h @@ -147,6 +147,15 @@ struct TSmallArrayVector { sizes->erase(sizes->begin()); } + void pop_back() + { + assert(sizes != nullptr && sizes->size() > 0); + if (sizes->size() == 1) + dealloc(); + else + sizes->resize(sizes->size() - 1); + } + // 'this' should currently not be holding anything, and copyNonFront // will make it hold a copy of all but the first element of rhs. // (This would be useful for making a type that is dereferenced by @@ -222,7 +231,7 @@ struct TSmallArrayVector { struct TArraySizes { POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) - TArraySizes() : implicitArraySize(1), variablyIndexed(false) { } + TArraySizes() : implicitArraySize(0), implicitlySized(true), variablyIndexed(false){ } // For breaking into two non-shared copies, independently modifiable. TArraySizes& operator=(const TArraySizes& from) @@ -230,6 +239,7 @@ struct TArraySizes { implicitArraySize = from.implicitArraySize; variablyIndexed = from.variablyIndexed; sizes = from.sizes; + implicitlySized = from.implicitlySized; return *this; } @@ -256,11 +266,17 @@ struct TArraySizes { void addInnerSize(int s, TIntermTyped* n) { sizes.push_back((unsigned)s, n); } void addInnerSize(TArraySize pair) { sizes.push_back(pair.size, pair.node); + implicitlySized = false; } void addInnerSizes(const TArraySizes& s) { sizes.push_back(s.sizes); } - void changeOuterSize(int s) { sizes.changeFront((unsigned)s); } - int getImplicitSize() const { return implicitArraySize; } - void updateImplicitSize(int s) { implicitArraySize = std::max(implicitArraySize, s); } + void changeOuterSize(int s) { + sizes.changeFront((unsigned)s); + implicitlySized = false; + } + int getImplicitSize() const { return implicitArraySize > 0 ? implicitArraySize : 1; } + void updateImplicitSize(int s) { + implicitArraySize = (std::max)(implicitArraySize, s); + } bool isInnerUnsized() const { for (int d = 1; d < sizes.size(); ++d) { @@ -295,7 +311,11 @@ struct TArraySizes { bool hasUnsized() const { return getOuterSize() == UnsizedArraySize || isInnerUnsized(); } bool isSized() const { return getOuterSize() != UnsizedArraySize; } + bool isImplicitlySized() const { return implicitlySized; } + bool isDefaultImplicitlySized() const { return implicitlySized && implicitArraySize == 0; } + void setImplicitlySized(bool isImplicitSizing) { implicitlySized = isImplicitSizing; } void dereference() { sizes.pop_front(); } + void removeLastSize() { sizes.pop_back(); } void copyDereferenced(const TArraySizes& rhs) { assert(sizes.size() == 0); @@ -333,6 +353,7 @@ struct TArraySizes { // the implicit size of the array, if not variably indexed and // otherwise legal. int implicitArraySize; + bool implicitlySized; bool variablyIndexed; // true if array is indexed with a non compile-time constant }; diff --git a/src/libraries/glslang/glslang/Include/glslang_c_interface.h b/src/libraries/glslang/glslang/Include/glslang_c_interface.h deleted file mode 100644 index 14ab6acbc..000000000 --- a/src/libraries/glslang/glslang/Include/glslang_c_interface.h +++ /dev/null @@ -1,253 +0,0 @@ -/** - This code is based on the glslang_c_interface implementation by Viktor Latypov -**/ - -/** -BSD 2-Clause License - -Copyright (c) 2019, Viktor Latypov -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. 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. - -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 HOLDER 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_C_IFACE_H_INCLUDED -#define GLSLANG_C_IFACE_H_INCLUDED - -#include -#include - -#include "glslang_c_shader_types.h" - -typedef struct glslang_shader_s glslang_shader_t; -typedef struct glslang_program_s glslang_program_t; - -/* TLimits counterpart */ -typedef struct glslang_limits_s { - bool non_inductive_for_loops; - bool while_loops; - bool do_while_loops; - bool general_uniform_indexing; - bool general_attribute_matrix_vector_indexing; - bool general_varying_indexing; - bool general_sampler_indexing; - bool general_variable_indexing; - bool general_constant_matrix_vector_indexing; -} glslang_limits_t; - -/* TBuiltInResource counterpart */ -typedef struct glslang_resource_s { - int max_lights; - int max_clip_planes; - int max_texture_units; - int max_texture_coords; - int max_vertex_attribs; - int max_vertex_uniform_components; - int max_varying_floats; - int max_vertex_texture_image_units; - int max_combined_texture_image_units; - int max_texture_image_units; - int max_fragment_uniform_components; - int max_draw_buffers; - int max_vertex_uniform_vectors; - int max_varying_vectors; - int max_fragment_uniform_vectors; - int max_vertex_output_vectors; - int max_fragment_input_vectors; - int min_program_texel_offset; - int max_program_texel_offset; - int max_clip_distances; - int max_compute_work_group_count_x; - int max_compute_work_group_count_y; - int max_compute_work_group_count_z; - int max_compute_work_group_size_x; - int max_compute_work_group_size_y; - int max_compute_work_group_size_z; - int max_compute_uniform_components; - int max_compute_texture_image_units; - int max_compute_image_uniforms; - int max_compute_atomic_counters; - int max_compute_atomic_counter_buffers; - int max_varying_components; - int max_vertex_output_components; - int max_geometry_input_components; - int max_geometry_output_components; - int max_fragment_input_components; - int max_image_units; - int max_combined_image_units_and_fragment_outputs; - int max_combined_shader_output_resources; - int max_image_samples; - int max_vertex_image_uniforms; - int max_tess_control_image_uniforms; - int max_tess_evaluation_image_uniforms; - int max_geometry_image_uniforms; - int max_fragment_image_uniforms; - int max_combined_image_uniforms; - int max_geometry_texture_image_units; - int max_geometry_output_vertices; - int max_geometry_total_output_components; - int max_geometry_uniform_components; - int max_geometry_varying_components; - int max_tess_control_input_components; - int max_tess_control_output_components; - int max_tess_control_texture_image_units; - int max_tess_control_uniform_components; - int max_tess_control_total_output_components; - int max_tess_evaluation_input_components; - int max_tess_evaluation_output_components; - int max_tess_evaluation_texture_image_units; - int max_tess_evaluation_uniform_components; - int max_tess_patch_components; - int max_patch_vertices; - int max_tess_gen_level; - int max_viewports; - int max_vertex_atomic_counters; - int max_tess_control_atomic_counters; - int max_tess_evaluation_atomic_counters; - int max_geometry_atomic_counters; - int max_fragment_atomic_counters; - int max_combined_atomic_counters; - int max_atomic_counter_bindings; - int max_vertex_atomic_counter_buffers; - int max_tess_control_atomic_counter_buffers; - int max_tess_evaluation_atomic_counter_buffers; - int max_geometry_atomic_counter_buffers; - int max_fragment_atomic_counter_buffers; - int max_combined_atomic_counter_buffers; - int max_atomic_counter_buffer_size; - int max_transform_feedback_buffers; - int max_transform_feedback_interleaved_components; - int max_cull_distances; - int max_combined_clip_and_cull_distances; - int max_samples; - int max_mesh_output_vertices_nv; - int max_mesh_output_primitives_nv; - int max_mesh_work_group_size_x_nv; - int max_mesh_work_group_size_y_nv; - int max_mesh_work_group_size_z_nv; - int max_task_work_group_size_x_nv; - int max_task_work_group_size_y_nv; - int max_task_work_group_size_z_nv; - int max_mesh_view_count_nv; - int maxDualSourceDrawBuffersEXT; - - glslang_limits_t limits; -} glslang_resource_t; - -typedef struct glslang_input_s { - glslang_source_t language; - glslang_stage_t stage; - glslang_client_t client; - glslang_target_client_version_t client_version; - glslang_target_language_t target_language; - glslang_target_language_version_t target_language_version; - /** Shader source code */ - const char* code; - int default_version; - glslang_profile_t default_profile; - int force_default_version_and_profile; - int forward_compatible; - glslang_messages_t messages; - const glslang_resource_t* resource; -} glslang_input_t; - -/* Inclusion result structure allocated by C include_local/include_system callbacks */ -typedef struct glsl_include_result_s { - /* Header file name or NULL if inclusion failed */ - const char* header_name; - - /* Header contents or NULL */ - const char* header_data; - size_t header_length; - -} glsl_include_result_t; - -/* Callback for local file inclusion */ -typedef glsl_include_result_t* (*glsl_include_local_func)(void* ctx, const char* header_name, const char* includer_name, - size_t include_depth); - -/* Callback for system file inclusion */ -typedef glsl_include_result_t* (*glsl_include_system_func)(void* ctx, const char* header_name, - const char* includer_name, size_t include_depth); - -/* Callback for include result destruction */ -typedef int (*glsl_free_include_result_func)(void* ctx, glsl_include_result_t* result); - -/* Collection of callbacks for GLSL preprocessor */ -typedef struct glsl_include_callbacks_s { - glsl_include_system_func include_system; - glsl_include_local_func include_local; - glsl_free_include_result_func free_include_result; -} glsl_include_callbacks_t; - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef GLSLANG_IS_SHARED_LIBRARY - #ifdef _WIN32 - #ifdef GLSLANG_EXPORTING - #define GLSLANG_EXPORT __declspec(dllexport) - #else - #define GLSLANG_EXPORT __declspec(dllimport) - #endif - #elif __GNUC__ >= 4 - #define GLSLANG_EXPORT __attribute__((visibility("default"))) - #endif -#endif // GLSLANG_IS_SHARED_LIBRARY - -#ifndef GLSLANG_EXPORT -#define GLSLANG_EXPORT -#endif - -GLSLANG_EXPORT int glslang_initialize_process(); -GLSLANG_EXPORT void glslang_finalize_process(); - -GLSLANG_EXPORT glslang_shader_t* glslang_shader_create(const glslang_input_t* input); -GLSLANG_EXPORT void glslang_shader_delete(glslang_shader_t* shader); -GLSLANG_EXPORT void glslang_shader_shift_binding(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base); -GLSLANG_EXPORT void glslang_shader_shift_binding_for_set(glslang_shader_t* shader, glslang_resource_type_t res, unsigned int base, unsigned int set); -GLSLANG_EXPORT void glslang_shader_set_options(glslang_shader_t* shader, int options); // glslang_shader_options_t -GLSLANG_EXPORT int glslang_shader_preprocess(glslang_shader_t* shader, const glslang_input_t* input); -GLSLANG_EXPORT int glslang_shader_parse(glslang_shader_t* shader, const glslang_input_t* input); -GLSLANG_EXPORT const char* glslang_shader_get_preprocessed_code(glslang_shader_t* shader); -GLSLANG_EXPORT const char* glslang_shader_get_info_log(glslang_shader_t* shader); -GLSLANG_EXPORT const char* glslang_shader_get_info_debug_log(glslang_shader_t* shader); - -GLSLANG_EXPORT glslang_program_t* glslang_program_create(); -GLSLANG_EXPORT void glslang_program_delete(glslang_program_t* program); -GLSLANG_EXPORT void glslang_program_add_shader(glslang_program_t* program, glslang_shader_t* shader); -GLSLANG_EXPORT int glslang_program_link(glslang_program_t* program, int messages); // glslang_messages_t -GLSLANG_EXPORT int glslang_program_map_io(glslang_program_t* program); -GLSLANG_EXPORT void glslang_program_SPIRV_generate(glslang_program_t* program, glslang_stage_t stage); -GLSLANG_EXPORT size_t glslang_program_SPIRV_get_size(glslang_program_t* program); -GLSLANG_EXPORT void glslang_program_SPIRV_get(glslang_program_t* program, unsigned int*); -GLSLANG_EXPORT unsigned int* glslang_program_SPIRV_get_ptr(glslang_program_t* program); -GLSLANG_EXPORT const char* glslang_program_SPIRV_get_messages(glslang_program_t* program); -GLSLANG_EXPORT const char* glslang_program_get_info_log(glslang_program_t* program); -GLSLANG_EXPORT const char* glslang_program_get_info_debug_log(glslang_program_t* program); - -#ifdef __cplusplus -} -#endif - -#endif /* #ifdef GLSLANG_C_IFACE_INCLUDED */ diff --git a/src/libraries/glslang/glslang/Include/glslang_c_shader_types.h b/src/libraries/glslang/glslang/Include/glslang_c_shader_types.h deleted file mode 100644 index fc8028065..000000000 --- a/src/libraries/glslang/glslang/Include/glslang_c_shader_types.h +++ /dev/null @@ -1,207 +0,0 @@ -/** - This code is based on the glslang_c_interface implementation by Viktor Latypov -**/ - -/** -BSD 2-Clause License - -Copyright (c) 2019, Viktor Latypov -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. 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. - -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 HOLDER 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 C_SHADER_TYPES_H_INCLUDED -#define C_SHADER_TYPES_H_INCLUDED - -#define LAST_ELEMENT_MARKER(x) x - -/* EShLanguage counterpart */ -typedef enum { - GLSLANG_STAGE_VERTEX, - GLSLANG_STAGE_TESSCONTROL, - GLSLANG_STAGE_TESSEVALUATION, - GLSLANG_STAGE_GEOMETRY, - GLSLANG_STAGE_FRAGMENT, - GLSLANG_STAGE_COMPUTE, - GLSLANG_STAGE_RAYGEN_NV, - GLSLANG_STAGE_INTERSECT_NV, - GLSLANG_STAGE_ANYHIT_NV, - GLSLANG_STAGE_CLOSESTHIT_NV, - GLSLANG_STAGE_MISS_NV, - GLSLANG_STAGE_CALLABLE_NV, - GLSLANG_STAGE_TASK_NV, - GLSLANG_STAGE_MESH_NV, - LAST_ELEMENT_MARKER(GLSLANG_STAGE_COUNT), -} glslang_stage_t; // would be better as stage, but this is ancient now - -/* EShLanguageMask counterpart */ -typedef enum { - GLSLANG_STAGE_VERTEX_MASK = (1 << GLSLANG_STAGE_VERTEX), - GLSLANG_STAGE_TESSCONTROL_MASK = (1 << GLSLANG_STAGE_TESSCONTROL), - GLSLANG_STAGE_TESSEVALUATION_MASK = (1 << GLSLANG_STAGE_TESSEVALUATION), - GLSLANG_STAGE_GEOMETRY_MASK = (1 << GLSLANG_STAGE_GEOMETRY), - GLSLANG_STAGE_FRAGMENT_MASK = (1 << GLSLANG_STAGE_FRAGMENT), - GLSLANG_STAGE_COMPUTE_MASK = (1 << GLSLANG_STAGE_COMPUTE), - GLSLANG_STAGE_RAYGEN_NV_MASK = (1 << GLSLANG_STAGE_RAYGEN_NV), - GLSLANG_STAGE_INTERSECT_NV_MASK = (1 << GLSLANG_STAGE_INTERSECT_NV), - GLSLANG_STAGE_ANYHIT_NV_MASK = (1 << GLSLANG_STAGE_ANYHIT_NV), - GLSLANG_STAGE_CLOSESTHIT_NV_MASK = (1 << GLSLANG_STAGE_CLOSESTHIT_NV), - GLSLANG_STAGE_MISS_NV_MASK = (1 << GLSLANG_STAGE_MISS_NV), - GLSLANG_STAGE_CALLABLE_NV_MASK = (1 << GLSLANG_STAGE_CALLABLE_NV), - GLSLANG_STAGE_TASK_NV_MASK = (1 << GLSLANG_STAGE_TASK_NV), - GLSLANG_STAGE_MESH_NV_MASK = (1 << GLSLANG_STAGE_MESH_NV), - LAST_ELEMENT_MARKER(GLSLANG_STAGE_MASK_COUNT), -} glslang_stage_mask_t; - -/* EShSource counterpart */ -typedef enum { - GLSLANG_SOURCE_NONE, - GLSLANG_SOURCE_GLSL, - GLSLANG_SOURCE_HLSL, - LAST_ELEMENT_MARKER(GLSLANG_SOURCE_COUNT), -} glslang_source_t; - -/* EShClient counterpart */ -typedef enum { - GLSLANG_CLIENT_NONE, - GLSLANG_CLIENT_VULKAN, - GLSLANG_CLIENT_OPENGL, - LAST_ELEMENT_MARKER(GLSLANG_CLIENT_COUNT), -} glslang_client_t; - -/* EShTargetLanguage counterpart */ -typedef enum { - GLSLANG_TARGET_NONE, - GLSLANG_TARGET_SPV, - LAST_ELEMENT_MARKER(GLSLANG_TARGET_COUNT), -} glslang_target_language_t; - -/* SH_TARGET_ClientVersion counterpart */ -typedef enum { - GLSLANG_TARGET_VULKAN_1_0 = (1 << 22), - GLSLANG_TARGET_VULKAN_1_1 = (1 << 22) | (1 << 12), - GLSLANG_TARGET_VULKAN_1_2 = (1 << 22) | (2 << 12), - GLSLANG_TARGET_OPENGL_450 = 450, - LAST_ELEMENT_MARKER(GLSLANG_TARGET_CLIENT_VERSION_COUNT = 4), -} glslang_target_client_version_t; - -/* SH_TARGET_LanguageVersion counterpart */ -typedef enum { - GLSLANG_TARGET_SPV_1_0 = (1 << 16), - GLSLANG_TARGET_SPV_1_1 = (1 << 16) | (1 << 8), - GLSLANG_TARGET_SPV_1_2 = (1 << 16) | (2 << 8), - GLSLANG_TARGET_SPV_1_3 = (1 << 16) | (3 << 8), - GLSLANG_TARGET_SPV_1_4 = (1 << 16) | (4 << 8), - GLSLANG_TARGET_SPV_1_5 = (1 << 16) | (5 << 8), - GLSLANG_TARGET_SPV_1_6 = (1 << 16) | (6 << 8), - LAST_ELEMENT_MARKER(GLSLANG_TARGET_LANGUAGE_VERSION_COUNT = 7), -} glslang_target_language_version_t; - -/* EShExecutable counterpart */ -typedef enum { GLSLANG_EX_VERTEX_FRAGMENT, GLSLANG_EX_FRAGMENT } glslang_executable_t; - -/* EShOptimizationLevel counterpart */ -typedef enum { - GLSLANG_OPT_NO_GENERATION, - GLSLANG_OPT_NONE, - GLSLANG_OPT_SIMPLE, - GLSLANG_OPT_FULL, - LAST_ELEMENT_MARKER(GLSLANG_OPT_LEVEL_COUNT), -} glslang_optimization_level_t; - -/* EShTextureSamplerTransformMode counterpart */ -typedef enum { - GLSLANG_TEX_SAMP_TRANS_KEEP, - GLSLANG_TEX_SAMP_TRANS_UPGRADE_TEXTURE_REMOVE_SAMPLER, - LAST_ELEMENT_MARKER(GLSLANG_TEX_SAMP_TRANS_COUNT), -} glslang_texture_sampler_transform_mode_t; - -/* EShMessages counterpart */ -typedef enum { - GLSLANG_MSG_DEFAULT_BIT = 0, - GLSLANG_MSG_RELAXED_ERRORS_BIT = (1 << 0), - GLSLANG_MSG_SUPPRESS_WARNINGS_BIT = (1 << 1), - GLSLANG_MSG_AST_BIT = (1 << 2), - GLSLANG_MSG_SPV_RULES_BIT = (1 << 3), - GLSLANG_MSG_VULKAN_RULES_BIT = (1 << 4), - GLSLANG_MSG_ONLY_PREPROCESSOR_BIT = (1 << 5), - GLSLANG_MSG_READ_HLSL_BIT = (1 << 6), - GLSLANG_MSG_CASCADING_ERRORS_BIT = (1 << 7), - GLSLANG_MSG_KEEP_UNCALLED_BIT = (1 << 8), - GLSLANG_MSG_HLSL_OFFSETS_BIT = (1 << 9), - GLSLANG_MSG_DEBUG_INFO_BIT = (1 << 10), - GLSLANG_MSG_HLSL_ENABLE_16BIT_TYPES_BIT = (1 << 11), - GLSLANG_MSG_HLSL_LEGALIZATION_BIT = (1 << 12), - GLSLANG_MSG_HLSL_DX9_COMPATIBLE_BIT = (1 << 13), - GLSLANG_MSG_BUILTIN_SYMBOL_TABLE_BIT = (1 << 14), - LAST_ELEMENT_MARKER(GLSLANG_MSG_COUNT), -} glslang_messages_t; - -/* EShReflectionOptions counterpart */ -typedef enum { - GLSLANG_REFLECTION_DEFAULT_BIT = 0, - GLSLANG_REFLECTION_STRICT_ARRAY_SUFFIX_BIT = (1 << 0), - GLSLANG_REFLECTION_BASIC_ARRAY_SUFFIX_BIT = (1 << 1), - GLSLANG_REFLECTION_INTERMEDIATE_IOO_BIT = (1 << 2), - GLSLANG_REFLECTION_SEPARATE_BUFFERS_BIT = (1 << 3), - GLSLANG_REFLECTION_ALL_BLOCK_VARIABLES_BIT = (1 << 4), - GLSLANG_REFLECTION_UNWRAP_IO_BLOCKS_BIT = (1 << 5), - GLSLANG_REFLECTION_ALL_IO_VARIABLES_BIT = (1 << 6), - GLSLANG_REFLECTION_SHARED_STD140_SSBO_BIT = (1 << 7), - GLSLANG_REFLECTION_SHARED_STD140_UBO_BIT = (1 << 8), - LAST_ELEMENT_MARKER(GLSLANG_REFLECTION_COUNT), -} glslang_reflection_options_t; - -/* EProfile counterpart (from Versions.h) */ -typedef enum { - GLSLANG_BAD_PROFILE = 0, - GLSLANG_NO_PROFILE = (1 << 0), - GLSLANG_CORE_PROFILE = (1 << 1), - GLSLANG_COMPATIBILITY_PROFILE = (1 << 2), - GLSLANG_ES_PROFILE = (1 << 3), - LAST_ELEMENT_MARKER(GLSLANG_PROFILE_COUNT), -} glslang_profile_t; - -/* Shader options */ -typedef enum { - GLSLANG_SHADER_DEFAULT_BIT = 0, - GLSLANG_SHADER_AUTO_MAP_BINDINGS = (1 << 0), - GLSLANG_SHADER_AUTO_MAP_LOCATIONS = (1 << 1), - GLSLANG_SHADER_VULKAN_RULES_RELAXED = (1 << 2), - LAST_ELEMENT_MARKER(GLSLANG_SHADER_COUNT), -} glslang_shader_options_t; - -/* TResourceType counterpart */ -typedef enum { - GLSLANG_RESOURCE_TYPE_SAMPLER, - GLSLANG_RESOURCE_TYPE_TEXTURE, - GLSLANG_RESOURCE_TYPE_IMAGE, - GLSLANG_RESOURCE_TYPE_UBO, - GLSLANG_RESOURCE_TYPE_SSBO, - GLSLANG_RESOURCE_TYPE_UAV, - LAST_ELEMENT_MARKER(GLSLANG_RESOURCE_TYPE_COUNT), -} glslang_resource_type_t; - -#undef LAST_ELEMENT_MARKER - -#endif diff --git a/src/libraries/glslang/glslang/Include/intermediate.h b/src/libraries/glslang/glslang/Include/intermediate.h index 595bd623d..b0e154e92 100644 --- a/src/libraries/glslang/glslang/Include/intermediate.h +++ b/src/libraries/glslang/glslang/Include/intermediate.h @@ -48,14 +48,9 @@ #ifndef __INTERMEDIATE_H #define __INTERMEDIATE_H -#if defined(_MSC_VER) && _MSC_VER >= 1900 - #pragma warning(disable : 4464) // relative include path contains '..' - #pragma warning(disable : 5026) // 'glslang::TIntermUnary': move constructor was implicitly defined as deleted -#endif - -#include "../Include/Common.h" -#include "../Include/Types.h" -#include "../Include/ConstantUnion.h" +#include "Common.h" +#include "Types.h" +#include "ConstantUnion.h" namespace glslang { @@ -67,13 +62,12 @@ class TIntermediate; enum TOperator { EOpNull, // if in a node, should only mean a node is still being built EOpSequence, // denotes a list of statements, or parameters, etc. + EOpScope, // Used by debugging to denote a scoped list of statements EOpLinkerObjects, // for aggregate node of objects the linker may need, if not reference by the rest of the AST EOpFunctionCall, EOpFunction, // For function definition EOpParameters, // an aggregate listing the parameters to a function -#ifndef GLSLANG_WEB EOpSpirvInst, -#endif // // Unary operators @@ -91,6 +85,8 @@ enum TOperator { EOpCopyObject, + EOpDeclare, // Used by debugging to force declaration of variable in correct scope + // (u)int* -> bool EOpConvInt8ToBool, EOpConvUint8ToBool, @@ -626,6 +622,9 @@ enum TOperator { EOpCooperativeMatrixLoad, EOpCooperativeMatrixStore, EOpCooperativeMatrixMulAdd, + EOpCooperativeMatrixLoadNV, + EOpCooperativeMatrixStoreNV, + EOpCooperativeMatrixMulAddNV, EOpBeginInvocationInterlock, // Fragment only EOpEndInvocationInterlock, // Fragment only @@ -763,7 +762,8 @@ enum TOperator { EOpConstructTextureSampler, EOpConstructNonuniform, // expected to be transformed away, not present in final AST EOpConstructReference, - EOpConstructCooperativeMatrix, + EOpConstructCooperativeMatrixNV, + EOpConstructCooperativeMatrixKHR, EOpConstructAccStruct, EOpConstructGuardEnd, @@ -824,6 +824,7 @@ enum TOperator { EOpSubpassLoadMS, EOpSparseImageLoad, EOpSparseImageLoadLod, + EOpColorAttachmentReadEXT, // Fragment only EOpImageGuardEnd, @@ -934,6 +935,8 @@ enum TOperator { EOpExecuteCallableNV, EOpExecuteCallableKHR, EOpWritePackedPrimitiveIndices4x8NV, + EOpEmitMeshTasksEXT, + EOpSetMeshOutputsEXT, // // GL_EXT_ray_query operations @@ -963,7 +966,44 @@ enum TOperator { EOpRayQueryGetIntersectionObjectToWorld, EOpRayQueryGetIntersectionWorldToObject, + // + // GL_NV_shader_invocation_reorder // + + EOpHitObjectTraceRayNV, + EOpHitObjectTraceRayMotionNV, + EOpHitObjectRecordHitNV, + EOpHitObjectRecordHitMotionNV, + EOpHitObjectRecordHitWithIndexNV, + EOpHitObjectRecordHitWithIndexMotionNV, + EOpHitObjectRecordMissNV, + EOpHitObjectRecordMissMotionNV, + EOpHitObjectRecordEmptyNV, + EOpHitObjectExecuteShaderNV, + EOpHitObjectIsEmptyNV, + EOpHitObjectIsMissNV, + EOpHitObjectIsHitNV, + EOpHitObjectGetRayTMinNV, + EOpHitObjectGetRayTMaxNV, + EOpHitObjectGetObjectRayOriginNV, + EOpHitObjectGetObjectRayDirectionNV, + EOpHitObjectGetWorldRayOriginNV, + EOpHitObjectGetWorldRayDirectionNV, + EOpHitObjectGetWorldToObjectNV, + EOpHitObjectGetObjectToWorldNV, + EOpHitObjectGetInstanceCustomIndexNV, + EOpHitObjectGetInstanceIdNV, + EOpHitObjectGetGeometryIndexNV, + EOpHitObjectGetPrimitiveIndexNV, + EOpHitObjectGetHitKindNV, + EOpHitObjectGetShaderBindingTableRecordIndexNV, + EOpHitObjectGetShaderRecordBufferHandleNV, + EOpHitObjectGetAttributesNV, + EOpHitObjectGetCurrentTimeNV, + EOpReorderThreadNV, + EOpFetchMicroTriangleVertexPositionNV, + EOpFetchMicroTriangleVertexBarycentricNV, + // HLSL operations // @@ -1050,6 +1090,24 @@ enum TOperator { // Shader Clock Ops EOpReadClockSubgroupKHR, EOpReadClockDeviceKHR, + + // GL_EXT_ray_tracing_position_fetch + EOpRayQueryGetIntersectionTriangleVertexPositionsEXT, + + // Shader tile image ops + EOpStencilAttachmentReadEXT, // Fragment only + EOpDepthAttachmentReadEXT, // Fragment only + + // Image processing + EOpImageSampleWeightedQCOM, + EOpImageBoxFilterQCOM, + EOpImageBlockMatchSADQCOM, + EOpImageBlockMatchSSDQCOM, +}; + +enum TLinkType { + ELinkNone, + ELinkExport, }; class TIntermTraverser; @@ -1081,31 +1139,31 @@ class TIntermNode { virtual const glslang::TSourceLoc& getLoc() const { return loc; } virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; } virtual void traverse(glslang::TIntermTraverser*) = 0; - virtual glslang::TIntermTyped* getAsTyped() { return 0; } - virtual glslang::TIntermOperator* getAsOperator() { return 0; } - virtual glslang::TIntermConstantUnion* getAsConstantUnion() { return 0; } - virtual glslang::TIntermAggregate* getAsAggregate() { return 0; } - virtual glslang::TIntermUnary* getAsUnaryNode() { return 0; } - virtual glslang::TIntermBinary* getAsBinaryNode() { return 0; } - virtual glslang::TIntermSelection* getAsSelectionNode() { return 0; } - virtual glslang::TIntermSwitch* getAsSwitchNode() { return 0; } - virtual glslang::TIntermMethod* getAsMethodNode() { return 0; } - virtual glslang::TIntermSymbol* getAsSymbolNode() { return 0; } - virtual glslang::TIntermBranch* getAsBranchNode() { return 0; } - virtual glslang::TIntermLoop* getAsLoopNode() { return 0; } - - virtual const glslang::TIntermTyped* getAsTyped() const { return 0; } - virtual const glslang::TIntermOperator* getAsOperator() const { return 0; } - virtual const glslang::TIntermConstantUnion* getAsConstantUnion() const { return 0; } - virtual const glslang::TIntermAggregate* getAsAggregate() const { return 0; } - virtual const glslang::TIntermUnary* getAsUnaryNode() const { return 0; } - virtual const glslang::TIntermBinary* getAsBinaryNode() const { return 0; } - virtual const glslang::TIntermSelection* getAsSelectionNode() const { return 0; } - virtual const glslang::TIntermSwitch* getAsSwitchNode() const { return 0; } - virtual const glslang::TIntermMethod* getAsMethodNode() const { return 0; } - virtual const glslang::TIntermSymbol* getAsSymbolNode() const { return 0; } - virtual const glslang::TIntermBranch* getAsBranchNode() const { return 0; } - virtual const glslang::TIntermLoop* getAsLoopNode() const { return 0; } + virtual glslang::TIntermTyped* getAsTyped() { return nullptr; } + virtual glslang::TIntermOperator* getAsOperator() { return nullptr; } + virtual glslang::TIntermConstantUnion* getAsConstantUnion() { return nullptr; } + virtual glslang::TIntermAggregate* getAsAggregate() { return nullptr; } + virtual glslang::TIntermUnary* getAsUnaryNode() { return nullptr; } + virtual glslang::TIntermBinary* getAsBinaryNode() { return nullptr; } + virtual glslang::TIntermSelection* getAsSelectionNode() { return nullptr; } + virtual glslang::TIntermSwitch* getAsSwitchNode() { return nullptr; } + virtual glslang::TIntermMethod* getAsMethodNode() { return nullptr; } + virtual glslang::TIntermSymbol* getAsSymbolNode() { return nullptr; } + virtual glslang::TIntermBranch* getAsBranchNode() { return nullptr; } + virtual glslang::TIntermLoop* getAsLoopNode() { return nullptr; } + + virtual const glslang::TIntermTyped* getAsTyped() const { return nullptr; } + virtual const glslang::TIntermOperator* getAsOperator() const { return nullptr; } + virtual const glslang::TIntermConstantUnion* getAsConstantUnion() const { return nullptr; } + virtual const glslang::TIntermAggregate* getAsAggregate() const { return nullptr; } + virtual const glslang::TIntermUnary* getAsUnaryNode() const { return nullptr; } + virtual const glslang::TIntermBinary* getAsBinaryNode() const { return nullptr; } + virtual const glslang::TIntermSelection* getAsSelectionNode() const { return nullptr; } + virtual const glslang::TIntermSwitch* getAsSwitchNode() const { return nullptr; } + virtual const glslang::TIntermMethod* getAsMethodNode() const { return nullptr; } + virtual const glslang::TIntermSymbol* getAsSymbolNode() const { return nullptr; } + virtual const glslang::TIntermBranch* getAsBranchNode() const { return nullptr; } + virtual const glslang::TIntermLoop* getAsLoopNode() const { return nullptr; } virtual ~TIntermNode() { } protected: @@ -1155,7 +1213,7 @@ class TIntermTyped : public TIntermNode { 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(bool enhanced = false) const { return type.getCompleteString(enhanced); } protected: TIntermTyped& operator=(const TIntermTyped&); @@ -1269,9 +1327,11 @@ class TIntermMethod : public TIntermTyped { virtual const TString& getMethodName() const { return method; } virtual TIntermTyped* getObject() const { return object; } virtual void traverse(TIntermTraverser*); + void setExport() { linkType = ELinkExport; } protected: TIntermTyped* object; TString method; + TLinkType linkType; }; // @@ -1283,12 +1343,7 @@ class TIntermSymbol : public TIntermTyped { // per process threadPoolAllocator, then it causes increased memory usage per compile // it is essential to use "symbol = sym" to assign to symbol TIntermSymbol(long long i, const TString& n, const TType& t) - : TIntermTyped(t), id(i), -#ifndef GLSLANG_WEB - flattenSubset(-1), -#endif - constSubtree(nullptr) - { name = n; } + : TIntermTyped(t), id(i), flattenSubset(-1), constSubtree(nullptr) { name = n; } virtual long long getId() const { return id; } virtual void changeId(long long i) { id = i; } virtual const TString& getName() const { return name; } @@ -1299,12 +1354,10 @@ class TIntermSymbol : public TIntermTyped { const TConstUnionArray& getConstArray() const { return constArray; } void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; } TIntermTyped* getConstSubtree() const { return constSubtree; } -#ifndef GLSLANG_WEB void setFlattenSubset(int subset) { flattenSubset = subset; } virtual const TString& getAccessName() const; int getFlattenSubset() const { return flattenSubset; } // -1 means full object -#endif // This is meant for cases where a node has already been constructed, and // later on, it becomes necessary to switch to a different symbol. @@ -1312,9 +1365,7 @@ class TIntermSymbol : public TIntermTyped { protected: long long id; // the unique id of the symbol this node represents -#ifndef GLSLANG_WEB int flattenSubset; // how deeply the flattened object rooted at id has been dereferenced -#endif TString name; // the name of the symbol this node represents TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value TIntermTyped* constSubtree; @@ -1353,6 +1404,7 @@ struct TCrackedTextureOp { bool subpass; bool lodClamp; bool fragMask; + bool attachmentEXT; }; // @@ -1368,19 +1420,11 @@ class TIntermOperator : public TIntermTyped { bool isConstructor() const; bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; } 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 isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; } bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; } bool isSparseImage() const { return op == EOpSparseImageLoad; } bool isSubgroup() const { return op > EOpSubgroupGuardStart && op < EOpSubgroupGuardStop; } -#endif void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; } TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ? @@ -1409,6 +1453,7 @@ class TIntermOperator : public TIntermTyped { cracked.gather = false; cracked.grad = false; cracked.subpass = false; + cracked.attachmentEXT = false; cracked.lodClamp = false; cracked.fragMask = false; @@ -1485,7 +1530,6 @@ class TIntermOperator : public TIntermTyped { cracked.offset = true; cracked.proj = true; break; -#ifndef GLSLANG_WEB case EOpTextureClamp: case EOpSparseTextureClamp: cracked.lodClamp = true; @@ -1569,7 +1613,9 @@ class TIntermOperator : public TIntermTyped { case EOpSubpassLoadMS: cracked.subpass = true; break; -#endif + case EOpColorAttachmentReadEXT: + cracked.attachmentEXT = true; + break; default: break; } @@ -1611,8 +1657,8 @@ class TIntermBinary : public TIntermOperator { // class TIntermUnary : public TIntermOperator { public: - TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {} - TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {} + TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(nullptr) {} + TIntermUnary(TOperator o) : TIntermOperator(o), operand(nullptr) {} virtual void traverse(TIntermTraverser*); virtual void setOperand(TIntermTyped* o) { operand = o; } virtual TIntermTyped* getOperand() { return operand; } @@ -1620,15 +1666,11 @@ class TIntermUnary : public TIntermOperator { virtual TIntermUnary* getAsUnaryNode() { return this; } virtual const TIntermUnary* getAsUnaryNode() const { return this; } virtual void updatePrecision(); -#ifndef GLSLANG_WEB void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; } const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; } -#endif protected: TIntermTyped* operand; -#ifndef GLSLANG_WEB TSpirvInstruction spirvInst; -#endif }; typedef TVector TIntermSequence; @@ -1660,10 +1702,11 @@ class TIntermAggregate : public TIntermOperator { bool getDebug() const { return debug; } void setPragmaTable(const TPragmaTable& pTable); const TPragmaTable& getPragmaTable() const { return *pragmaTable; } -#ifndef GLSLANG_WEB void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; } const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; } -#endif + + void setLinkType(TLinkType l) { linkType = l; } + TLinkType getLinkType() const { return linkType; } protected: TIntermAggregate(const TIntermAggregate&); // disallow copy constructor TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator @@ -1674,9 +1717,8 @@ class TIntermAggregate : public TIntermOperator { bool optimize; bool debug; TPragmaTable* pragmaTable; -#ifndef GLSLANG_WEB TSpirvInstruction spirvInst; -#endif + TLinkType linkType = ELinkNone; }; // @@ -1814,7 +1856,7 @@ class TIntermTraverser { TIntermNode *getParentNode() { - return path.size() == 0 ? NULL : path.back(); + return path.size() == 0 ? nullptr : path.back(); } const bool preVisit; diff --git a/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp b/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp index 5fc61dbb7..ac7fc8cd1 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/Constant.cpp @@ -177,7 +177,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right newConstArray[i].setUConst(leftUnionArray[i].getUConst() / rightUnionArray[i].getUConst()); break; -#ifndef GLSLANG_WEB case EbtInt8: if (rightUnionArray[i] == (signed char)0) newConstArray[i].setI8Const((signed char)0x7F); @@ -212,9 +211,9 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right case EbtInt64: if (rightUnionArray[i] == 0ll) - newConstArray[i].setI64Const(0x7FFFFFFFFFFFFFFFll); - else if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == (long long)-0x8000000000000000ll) - newConstArray[i].setI64Const((long long)-0x8000000000000000ll); + newConstArray[i].setI64Const(LLONG_MAX); + else if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == LLONG_MIN) + newConstArray[i].setI64Const(LLONG_MIN); else newConstArray[i].setI64Const(leftUnionArray[i].getI64Const() / rightUnionArray[i].getI64Const()); break; @@ -226,8 +225,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right newConstArray[i].setU64Const(leftUnionArray[i].getU64Const() / rightUnionArray[i].getU64Const()); break; default: - return 0; -#endif + return nullptr; } } break; @@ -266,7 +264,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right newConstArray[i].setIConst(0); break; } else goto modulo_default; -#ifndef GLSLANG_WEB case EbtInt64: if (rightUnionArray[i].getI64Const() == -1 && leftUnionArray[i].getI64Const() == LLONG_MIN) { newConstArray[i].setI64Const(0); @@ -277,7 +274,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right newConstArray[i].setIConst(0); break; } else goto modulo_default; -#endif default: modulo_default: newConstArray[i] = leftUnionArray[i] % rightUnionArray[i]; @@ -354,7 +350,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TIntermTyped* right break; default: - return 0; + return nullptr; } TIntermConstantUnion *newNode = new TIntermConstantUnion(newConstArray, returnType); @@ -507,14 +503,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) : -unionArray[i].getIConst()); break; case EbtUint: newConstArray[i].setUConst(static_cast(-static_cast(unionArray[i].getUConst()))); break; -#ifndef GLSLANG_WEB case EbtInt8: newConstArray[i].setI8Const(-unionArray[i].getI8Const()); break; case EbtUint8: newConstArray[i].setU8Const(static_cast(-static_cast(unionArray[i].getU8Const()))); break; case EbtInt16: newConstArray[i].setI16Const(-unionArray[i].getI16Const()); break; case EbtUint16:newConstArray[i].setU16Const(static_cast(-static_cast(unionArray[i].getU16Const()))); break; case EbtInt64: newConstArray[i].setI64Const(-unionArray[i].getI64Const()); break; case EbtUint64: newConstArray[i].setU64Const(static_cast(-static_cast(unionArray[i].getU64Const()))); break; -#endif default: return nullptr; } @@ -634,12 +628,12 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EOpIsNan: { - newConstArray[i].setBConst(IsNan(unionArray[i].getDConst())); + newConstArray[i].setBConst(std::isnan(unionArray[i].getDConst())); break; } case EOpIsInf: { - newConstArray[i].setBConst(IsInfinity(unionArray[i].getDConst())); + newConstArray[i].setBConst(std::isinf(unionArray[i].getDConst())); break; } @@ -684,7 +678,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EOpConvDoubleToInt: newConstArray[i].setIConst(static_cast(unionArray[i].getDConst())); break; -#ifndef GLSLANG_WEB case EOpConvInt8ToBool: newConstArray[i].setBConst(unionArray[i].getI8Const() != 0); break; case EOpConvUint8ToBool: @@ -696,7 +689,7 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EOpConvInt64ToBool: newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break; case EOpConvUint64ToBool: - newConstArray[i].setBConst(unionArray[i].getI64Const() != 0); break; + newConstArray[i].setBConst(unionArray[i].getU64Const() != 0); break; case EOpConvFloat16ToBool: newConstArray[i].setBConst(unionArray[i].getDConst() != 0); break; @@ -919,7 +912,6 @@ TIntermTyped* TIntermConstantUnion::fold(TOperator op, const TType& returnType) case EOpConvUint64ToPtr: case EOpConstructReference: 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 @@ -1066,7 +1058,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EbtUint: newConstArray[comp].setUConst(std::min(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); break; -#ifndef GLSLANG_WEB case EbtInt8: newConstArray[comp].setI8Const(std::min(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const())); break; @@ -1085,7 +1076,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EbtUint64: newConstArray[comp].setU64Const(std::min(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const())); break; -#endif default: assert(false && "Default missing"); } break; @@ -1102,7 +1092,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EbtUint: newConstArray[comp].setUConst(std::max(childConstUnions[0][arg0comp].getUConst(), childConstUnions[1][arg1comp].getUConst())); break; -#ifndef GLSLANG_WEB case EbtInt8: newConstArray[comp].setI8Const(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const())); break; @@ -1121,7 +1110,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) case EbtUint64: newConstArray[comp].setU64Const(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const())); break; -#endif default: assert(false && "Default missing"); } break; @@ -1137,7 +1125,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) 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: newConstArray[comp].setI8Const(std::min(std::max(childConstUnions[0][arg0comp].getI8Const(), childConstUnions[1][arg1comp].getI8Const()), childConstUnions[2][arg2comp].getI8Const())); @@ -1166,7 +1153,6 @@ TIntermTyped* TIntermediate::fold(TIntermAggregate* aggrNode) newConstArray[comp].setU64Const(std::min(std::max(childConstUnions[0][arg0comp].getU64Const(), childConstUnions[1][arg1comp].getU64Const()), childConstUnions[2][arg2comp].getU64Const())); break; -#endif default: assert(false && "Default missing"); } break; @@ -1345,7 +1331,7 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, cons { TType dereferencedType(node->getType(), index); dereferencedType.getQualifier().storage = EvqConst; - TIntermTyped* result = 0; + TIntermTyped* result = nullptr; int size = dereferencedType.computeNumComponents(); // arrays, vectors, matrices, all use simple multiplicative math @@ -1365,7 +1351,7 @@ TIntermTyped* TIntermediate::foldDereference(TIntermTyped* node, int index, cons result = addConstantUnion(TConstUnionArray(node->getAsConstantUnion()->getConstArray(), start, size), node->getType(), loc); - if (result == 0) + if (result == nullptr) result = node; else result->setType(dereferencedType); @@ -1387,7 +1373,7 @@ TIntermTyped* TIntermediate::foldSwizzle(TIntermTyped* node, TSwizzleSelectorsgetType(), loc); - if (result == 0) + if (result == nullptr) result = node; else result->setType(TType(node->getBasicType(), EvqConst, selectors.size())); diff --git a/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp b/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp old mode 100644 new mode 100755 index daf34d385..437c56200 --- a/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/Initialize.cpp @@ -51,8 +51,9 @@ // including identifying what extensions are needed if a version does not allow a symbol // -#include "../Include/intermediate.h" +#include #include "Initialize.h" +#include "span.h" namespace glslang { @@ -61,10 +62,6 @@ const bool ARBCompatibility = false; const bool ForwardCompatibility = true; -// change this back to false if depending on textual spellings of texturing calls when consuming the AST -// Using PureOperatorBuiltins=false is deprecated. -bool PureOperatorBuiltins = true; - namespace { // @@ -144,29 +141,17 @@ struct Versioning { EProfile EDesktopProfile = static_cast(ENoProfile | ECoreProfile | ECompatibilityProfile); // Declare pointers to put into the table for versioning. -#ifdef GLSLANG_WEB - const Versioning* Es300Desktop130 = nullptr; - const Versioning* Es310Desktop420 = nullptr; -#elif defined(GLSLANG_ANGLE) - const Versioning* Es300Desktop130 = nullptr; - const Versioning* Es310Desktop420 = nullptr; - const Versioning* Es310Desktop450 = nullptr; -#else - const Versioning Es300Desktop130Version[] = { { EEsProfile, 0, 300, 0, nullptr }, - { EDesktopProfile, 0, 130, 0, nullptr }, - { EBadProfile } }; - const Versioning* Es300Desktop130 = &Es300Desktop130Version[0]; - - const Versioning Es310Desktop420Version[] = { { EEsProfile, 0, 310, 0, nullptr }, - { EDesktopProfile, 0, 420, 0, nullptr }, - { EBadProfile } }; - const Versioning* Es310Desktop420 = &Es310Desktop420Version[0]; - - const Versioning Es310Desktop450Version[] = { { EEsProfile, 0, 310, 0, nullptr }, - { EDesktopProfile, 0, 450, 0, nullptr }, - { EBadProfile } }; - const Versioning* Es310Desktop450 = &Es310Desktop450Version[0]; -#endif + const std::array Es300Desktop130Version = { Versioning{ EEsProfile, 0, 300, 0, nullptr }, + Versioning{ EDesktopProfile, 0, 130, 0, nullptr }, + }; + + const std::array Es310Desktop400Version = { Versioning{ EEsProfile, 0, 310, 0, nullptr }, + Versioning{ EDesktopProfile, 0, 400, 0, nullptr }, + }; + + const std::array Es310Desktop450Version = { Versioning{ EEsProfile, 0, 310, 0, nullptr }, + Versioning{ EDesktopProfile, 0, 450, 0, nullptr }, + }; // The main descriptor of what a set of function prototypes can look like, and // a pointer to extra versioning information, when needed. @@ -176,7 +161,7 @@ struct BuiltInFunction { int numArguments; // number of arguments (overloads with varying arguments need different entries) ArgType types; // ArgType mask ArgClass classes; // the ways this particular function entry manifests - const Versioning* versioning; // nullptr means always a valid version + const span versioning; // An empty span means always a valid version }; // The tables can have the same built-in function name more than one time, @@ -188,153 +173,146 @@ struct BuiltInFunction { // // Table is terminated by an OpNull TOperator. -const BuiltInFunction BaseFunctions[] = { +const std::array BaseFunctions = { // TOperator, name, arg-count, ArgType, ArgClass, versioning // --------- ---- --------- ------- -------- ---------- - { EOpRadians, "radians", 1, TypeF, ClassRegular, nullptr }, - { EOpDegrees, "degrees", 1, TypeF, ClassRegular, nullptr }, - { EOpSin, "sin", 1, TypeF, ClassRegular, nullptr }, - { EOpCos, "cos", 1, TypeF, ClassRegular, nullptr }, - { EOpTan, "tan", 1, TypeF, ClassRegular, nullptr }, - { EOpAsin, "asin", 1, TypeF, ClassRegular, nullptr }, - { EOpAcos, "acos", 1, TypeF, ClassRegular, nullptr }, - { EOpAtan, "atan", 2, TypeF, ClassRegular, nullptr }, - { EOpAtan, "atan", 1, TypeF, ClassRegular, nullptr }, - { EOpPow, "pow", 2, TypeF, ClassRegular, nullptr }, - { EOpExp, "exp", 1, TypeF, ClassRegular, nullptr }, - { EOpLog, "log", 1, TypeF, ClassRegular, nullptr }, - { EOpExp2, "exp2", 1, TypeF, ClassRegular, nullptr }, - { EOpLog2, "log2", 1, TypeF, ClassRegular, nullptr }, - { EOpSqrt, "sqrt", 1, TypeF, ClassRegular, nullptr }, - { EOpInverseSqrt, "inversesqrt", 1, TypeF, ClassRegular, nullptr }, - { EOpAbs, "abs", 1, TypeF, ClassRegular, nullptr }, - { EOpSign, "sign", 1, TypeF, ClassRegular, nullptr }, - { EOpFloor, "floor", 1, TypeF, ClassRegular, nullptr }, - { EOpCeil, "ceil", 1, TypeF, ClassRegular, nullptr }, - { EOpFract, "fract", 1, TypeF, ClassRegular, nullptr }, - { EOpMod, "mod", 2, TypeF, ClassLS, nullptr }, - { EOpMin, "min", 2, TypeF, ClassLS, nullptr }, - { EOpMax, "max", 2, TypeF, ClassLS, nullptr }, - { EOpClamp, "clamp", 3, TypeF, ClassLS2, nullptr }, - { EOpMix, "mix", 3, TypeF, ClassLS, nullptr }, - { EOpStep, "step", 2, TypeF, ClassFS, nullptr }, - { EOpSmoothStep, "smoothstep", 3, TypeF, ClassFS2, nullptr }, - { EOpNormalize, "normalize", 1, TypeF, ClassRegular, nullptr }, - { EOpFaceForward, "faceforward", 3, TypeF, ClassRegular, nullptr }, - { EOpReflect, "reflect", 2, TypeF, ClassRegular, nullptr }, - { EOpRefract, "refract", 3, TypeF, ClassXLS, nullptr }, - { EOpLength, "length", 1, TypeF, ClassRS, nullptr }, - { EOpDistance, "distance", 2, TypeF, ClassRS, nullptr }, - { EOpDot, "dot", 2, TypeF, ClassRS, nullptr }, - { EOpCross, "cross", 2, TypeF, ClassV3, nullptr }, - { EOpLessThan, "lessThan", 2, TypeFI, ClassBNS, nullptr }, - { EOpLessThanEqual, "lessThanEqual", 2, TypeFI, ClassBNS, nullptr }, - { EOpGreaterThan, "greaterThan", 2, TypeFI, ClassBNS, nullptr }, - { EOpGreaterThanEqual, "greaterThanEqual", 2, TypeFI, ClassBNS, nullptr }, - { EOpVectorEqual, "equal", 2, TypeFIB, ClassBNS, nullptr }, - { EOpVectorNotEqual, "notEqual", 2, TypeFIB, ClassBNS, nullptr }, - { EOpAny, "any", 1, TypeB, ClassRSNS, nullptr }, - { EOpAll, "all", 1, TypeB, ClassRSNS, nullptr }, - { EOpVectorLogicalNot, "not", 1, TypeB, ClassNS, nullptr }, - { EOpSinh, "sinh", 1, TypeF, ClassRegular, Es300Desktop130 }, - { EOpCosh, "cosh", 1, TypeF, ClassRegular, Es300Desktop130 }, - { EOpTanh, "tanh", 1, TypeF, ClassRegular, Es300Desktop130 }, - { EOpAsinh, "asinh", 1, TypeF, ClassRegular, Es300Desktop130 }, - { EOpAcosh, "acosh", 1, TypeF, ClassRegular, Es300Desktop130 }, - { EOpAtanh, "atanh", 1, TypeF, ClassRegular, Es300Desktop130 }, - { EOpAbs, "abs", 1, TypeI, ClassRegular, Es300Desktop130 }, - { EOpSign, "sign", 1, TypeI, ClassRegular, Es300Desktop130 }, - { EOpTrunc, "trunc", 1, TypeF, ClassRegular, Es300Desktop130 }, - { EOpRound, "round", 1, TypeF, ClassRegular, Es300Desktop130 }, - { EOpRoundEven, "roundEven", 1, TypeF, ClassRegular, Es300Desktop130 }, - { EOpModf, "modf", 2, TypeF, ClassLO, Es300Desktop130 }, - { EOpMin, "min", 2, TypeIU, ClassLS, Es300Desktop130 }, - { EOpMax, "max", 2, TypeIU, ClassLS, Es300Desktop130 }, - { EOpClamp, "clamp", 3, TypeIU, ClassLS2, Es300Desktop130 }, - { EOpMix, "mix", 3, TypeF, ClassLB, Es300Desktop130 }, - { EOpIsInf, "isinf", 1, TypeF, ClassB, Es300Desktop130 }, - { EOpIsNan, "isnan", 1, TypeF, ClassB, Es300Desktop130 }, - { EOpLessThan, "lessThan", 2, TypeU, ClassBNS, Es300Desktop130 }, - { EOpLessThanEqual, "lessThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 }, - { EOpGreaterThan, "greaterThan", 2, TypeU, ClassBNS, Es300Desktop130 }, - { EOpGreaterThanEqual, "greaterThanEqual", 2, TypeU, ClassBNS, Es300Desktop130 }, - { EOpVectorEqual, "equal", 2, TypeU, ClassBNS, Es300Desktop130 }, - { EOpVectorNotEqual, "notEqual", 2, TypeU, ClassBNS, Es300Desktop130 }, - { EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, - { EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, - { EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, - { EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, - { EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, - { EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, - { EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, Es310Desktop420 }, - { EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, Es310Desktop420 }, -#ifndef GLSLANG_WEB - { EOpMix, "mix", 3, TypeB, ClassRegular, Es310Desktop450 }, - { EOpMix, "mix", 3, TypeIU, ClassLB, Es310Desktop450 }, -#endif - - { EOpNull } + BuiltInFunction{ EOpRadians, "radians", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpDegrees, "degrees", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpSin, "sin", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpCos, "cos", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpTan, "tan", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpAsin, "asin", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpAcos, "acos", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpAtan, "atan", 2, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpAtan, "atan", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpPow, "pow", 2, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpExp, "exp", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpLog, "log", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpExp2, "exp2", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpLog2, "log2", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpSqrt, "sqrt", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpInverseSqrt, "inversesqrt", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpAbs, "abs", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpSign, "sign", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpFloor, "floor", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpCeil, "ceil", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpFract, "fract", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpMod, "mod", 2, TypeF, ClassLS, {} }, + BuiltInFunction{ EOpMin, "min", 2, TypeF, ClassLS, {} }, + BuiltInFunction{ EOpMax, "max", 2, TypeF, ClassLS, {} }, + BuiltInFunction{ EOpClamp, "clamp", 3, TypeF, ClassLS2, {} }, + BuiltInFunction{ EOpMix, "mix", 3, TypeF, ClassLS, {} }, + BuiltInFunction{ EOpStep, "step", 2, TypeF, ClassFS, {} }, + BuiltInFunction{ EOpSmoothStep, "smoothstep", 3, TypeF, ClassFS2, {} }, + BuiltInFunction{ EOpNormalize, "normalize", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpFaceForward, "faceforward", 3, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpReflect, "reflect", 2, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpRefract, "refract", 3, TypeF, ClassXLS, {} }, + BuiltInFunction{ EOpLength, "length", 1, TypeF, ClassRS, {} }, + BuiltInFunction{ EOpDistance, "distance", 2, TypeF, ClassRS, {} }, + BuiltInFunction{ EOpDot, "dot", 2, TypeF, ClassRS, {} }, + BuiltInFunction{ EOpCross, "cross", 2, TypeF, ClassV3, {} }, + BuiltInFunction{ EOpLessThan, "lessThan", 2, TypeFI, ClassBNS, {} }, + BuiltInFunction{ EOpLessThanEqual, "lessThanEqual", 2, TypeFI, ClassBNS, {} }, + BuiltInFunction{ EOpGreaterThan, "greaterThan", 2, TypeFI, ClassBNS, {} }, + BuiltInFunction{ EOpGreaterThanEqual, "greaterThanEqual", 2, TypeFI, ClassBNS, {} }, + BuiltInFunction{ EOpVectorEqual, "equal", 2, TypeFIB, ClassBNS, {} }, + BuiltInFunction{ EOpVectorNotEqual, "notEqual", 2, TypeFIB, ClassBNS, {} }, + BuiltInFunction{ EOpAny, "any", 1, TypeB, ClassRSNS, {} }, + BuiltInFunction{ EOpAll, "all", 1, TypeB, ClassRSNS, {} }, + BuiltInFunction{ EOpVectorLogicalNot, "not", 1, TypeB, ClassNS, {} }, + BuiltInFunction{ EOpSinh, "sinh", 1, TypeF, ClassRegular, {Es300Desktop130Version} }, + BuiltInFunction{ EOpCosh, "cosh", 1, TypeF, ClassRegular, {Es300Desktop130Version} }, + BuiltInFunction{ EOpTanh, "tanh", 1, TypeF, ClassRegular, {Es300Desktop130Version} }, + BuiltInFunction{ EOpAsinh, "asinh", 1, TypeF, ClassRegular, {Es300Desktop130Version} }, + BuiltInFunction{ EOpAcosh, "acosh", 1, TypeF, ClassRegular, {Es300Desktop130Version} }, + BuiltInFunction{ EOpAtanh, "atanh", 1, TypeF, ClassRegular, {Es300Desktop130Version} }, + BuiltInFunction{ EOpAbs, "abs", 1, TypeI, ClassRegular, {Es300Desktop130Version} }, + BuiltInFunction{ EOpSign, "sign", 1, TypeI, ClassRegular, {Es300Desktop130Version} }, + BuiltInFunction{ EOpTrunc, "trunc", 1, TypeF, ClassRegular, {Es300Desktop130Version} }, + BuiltInFunction{ EOpRound, "round", 1, TypeF, ClassRegular, {Es300Desktop130Version} }, + BuiltInFunction{ EOpRoundEven, "roundEven", 1, TypeF, ClassRegular, {Es300Desktop130Version} }, + BuiltInFunction{ EOpModf, "modf", 2, TypeF, ClassLO, {Es300Desktop130Version} }, + BuiltInFunction{ EOpMin, "min", 2, TypeIU, ClassLS, {Es300Desktop130Version} }, + BuiltInFunction{ EOpMax, "max", 2, TypeIU, ClassLS, {Es300Desktop130Version} }, + BuiltInFunction{ EOpClamp, "clamp", 3, TypeIU, ClassLS2, {Es300Desktop130Version} }, + BuiltInFunction{ EOpMix, "mix", 3, TypeF, ClassLB, {Es300Desktop130Version} }, + BuiltInFunction{ EOpIsInf, "isinf", 1, TypeF, ClassB, {Es300Desktop130Version} }, + BuiltInFunction{ EOpIsNan, "isnan", 1, TypeF, ClassB, {Es300Desktop130Version} }, + BuiltInFunction{ EOpLessThan, "lessThan", 2, TypeU, ClassBNS, {Es300Desktop130Version} }, + BuiltInFunction{ EOpLessThanEqual, "lessThanEqual", 2, TypeU, ClassBNS, {Es300Desktop130Version} }, + BuiltInFunction{ EOpGreaterThan, "greaterThan", 2, TypeU, ClassBNS, {Es300Desktop130Version} }, + BuiltInFunction{ EOpGreaterThanEqual, "greaterThanEqual", 2, TypeU, ClassBNS, {Es300Desktop130Version} }, + BuiltInFunction{ EOpVectorEqual, "equal", 2, TypeU, ClassBNS, {Es300Desktop130Version} }, + BuiltInFunction{ EOpVectorNotEqual, "notEqual", 2, TypeU, ClassBNS, {Es300Desktop130Version} }, + BuiltInFunction{ EOpAtomicAdd, "atomicAdd", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} }, + BuiltInFunction{ EOpAtomicMin, "atomicMin", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} }, + BuiltInFunction{ EOpAtomicMax, "atomicMax", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} }, + BuiltInFunction{ EOpAtomicAnd, "atomicAnd", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} }, + BuiltInFunction{ EOpAtomicOr, "atomicOr", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} }, + BuiltInFunction{ EOpAtomicXor, "atomicXor", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} }, + BuiltInFunction{ EOpAtomicExchange, "atomicExchange", 2, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} }, + BuiltInFunction{ EOpAtomicCompSwap, "atomicCompSwap", 3, TypeIU, ClassV1FIOCV, {Es310Desktop400Version} }, + BuiltInFunction{ EOpMix, "mix", 3, TypeB, ClassRegular, {Es310Desktop450Version} }, + BuiltInFunction{ EOpMix, "mix", 3, TypeIU, ClassLB, {Es310Desktop450Version} }, }; -const BuiltInFunction DerivativeFunctions[] = { - { EOpDPdx, "dFdx", 1, TypeF, ClassRegular, nullptr }, - { EOpDPdy, "dFdy", 1, TypeF, ClassRegular, nullptr }, - { EOpFwidth, "fwidth", 1, TypeF, ClassRegular, nullptr }, - { EOpNull } +const std::array DerivativeFunctions = { + BuiltInFunction{ EOpDPdx, "dFdx", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpDPdy, "dFdy", 1, TypeF, ClassRegular, {} }, + BuiltInFunction{ EOpFwidth, "fwidth", 1, TypeF, ClassRegular, {} }, }; // For functions declared some other way, but still use the table to relate to operator. struct CustomFunction { TOperator op; // operator to map the name to const char* name; // function name - const Versioning* versioning; // nullptr means always a valid version + const span versioning; // An empty span means always a valid version }; const CustomFunction CustomFunctions[] = { - { EOpBarrier, "barrier", nullptr }, - { EOpMemoryBarrierShared, "memoryBarrierShared", nullptr }, - { EOpGroupMemoryBarrier, "groupMemoryBarrier", nullptr }, - { EOpMemoryBarrier, "memoryBarrier", nullptr }, - { EOpMemoryBarrierBuffer, "memoryBarrierBuffer", nullptr }, - - { EOpPackSnorm2x16, "packSnorm2x16", nullptr }, - { EOpUnpackSnorm2x16, "unpackSnorm2x16", nullptr }, - { EOpPackUnorm2x16, "packUnorm2x16", nullptr }, - { EOpUnpackUnorm2x16, "unpackUnorm2x16", nullptr }, - { EOpPackHalf2x16, "packHalf2x16", nullptr }, - { EOpUnpackHalf2x16, "unpackHalf2x16", nullptr }, - - { EOpMul, "matrixCompMult", nullptr }, - { EOpOuterProduct, "outerProduct", nullptr }, - { EOpTranspose, "transpose", nullptr }, - { EOpDeterminant, "determinant", nullptr }, - { EOpMatrixInverse, "inverse", nullptr }, - { EOpFloatBitsToInt, "floatBitsToInt", nullptr }, - { EOpFloatBitsToUint, "floatBitsToUint", nullptr }, - { EOpIntBitsToFloat, "intBitsToFloat", nullptr }, - { EOpUintBitsToFloat, "uintBitsToFloat", nullptr }, - - { EOpTextureQuerySize, "textureSize", nullptr }, - { EOpTextureQueryLod, "textureQueryLod", nullptr }, - { EOpTextureQueryLod, "textureQueryLOD", nullptr }, // extension GL_ARB_texture_query_lod - { EOpTextureQueryLevels, "textureQueryLevels", nullptr }, - { EOpTextureQuerySamples, "textureSamples", nullptr }, - { EOpTexture, "texture", nullptr }, - { EOpTextureProj, "textureProj", nullptr }, - { EOpTextureLod, "textureLod", nullptr }, - { EOpTextureOffset, "textureOffset", nullptr }, - { EOpTextureFetch, "texelFetch", nullptr }, - { EOpTextureFetchOffset, "texelFetchOffset", nullptr }, - { EOpTextureProjOffset, "textureProjOffset", nullptr }, - { EOpTextureLodOffset, "textureLodOffset", nullptr }, - { EOpTextureProjLod, "textureProjLod", nullptr }, - { EOpTextureProjLodOffset, "textureProjLodOffset", nullptr }, - { EOpTextureGrad, "textureGrad", nullptr }, - { EOpTextureGradOffset, "textureGradOffset", nullptr }, - { EOpTextureProjGrad, "textureProjGrad", nullptr }, - { EOpTextureProjGradOffset, "textureProjGradOffset", nullptr }, - - { EOpNull } + { EOpBarrier, "barrier", {} }, + { EOpMemoryBarrierShared, "memoryBarrierShared", {} }, + { EOpGroupMemoryBarrier, "groupMemoryBarrier", {} }, + { EOpMemoryBarrier, "memoryBarrier", {} }, + { EOpMemoryBarrierBuffer, "memoryBarrierBuffer", {} }, + + { EOpPackSnorm2x16, "packSnorm2x16", {} }, + { EOpUnpackSnorm2x16, "unpackSnorm2x16", {} }, + { EOpPackUnorm2x16, "packUnorm2x16", {} }, + { EOpUnpackUnorm2x16, "unpackUnorm2x16", {} }, + { EOpPackHalf2x16, "packHalf2x16", {} }, + { EOpUnpackHalf2x16, "unpackHalf2x16", {} }, + + { EOpMul, "matrixCompMult", {} }, + { EOpOuterProduct, "outerProduct", {} }, + { EOpTranspose, "transpose", {} }, + { EOpDeterminant, "determinant", {} }, + { EOpMatrixInverse, "inverse", {} }, + { EOpFloatBitsToInt, "floatBitsToInt", {} }, + { EOpFloatBitsToUint, "floatBitsToUint", {} }, + { EOpIntBitsToFloat, "intBitsToFloat", {} }, + { EOpUintBitsToFloat, "uintBitsToFloat", {} }, + + { EOpTextureQuerySize, "textureSize", {} }, + { EOpTextureQueryLod, "textureQueryLod", {} }, + { EOpTextureQueryLod, "textureQueryLOD", {} }, // extension GL_ARB_texture_query_lod + { EOpTextureQueryLevels, "textureQueryLevels", {} }, + { EOpTextureQuerySamples, "textureSamples", {} }, + { EOpTexture, "texture", {} }, + { EOpTextureProj, "textureProj", {} }, + { EOpTextureLod, "textureLod", {} }, + { EOpTextureOffset, "textureOffset", {} }, + { EOpTextureFetch, "texelFetch", {} }, + { EOpTextureFetchOffset, "texelFetchOffset", {} }, + { EOpTextureProjOffset, "textureProjOffset", {} }, + { EOpTextureLodOffset, "textureLodOffset", {} }, + { EOpTextureProjLod, "textureProjLod", {} }, + { EOpTextureProjLodOffset, "textureProjLodOffset", {} }, + { EOpTextureGrad, "textureGrad", {} }, + { EOpTextureGradOffset, "textureGradOffset", {} }, + { EOpTextureProjGrad, "textureProjGrad", {} }, + { EOpTextureProjGradOffset, "textureProjGradOffset", {} }, }; // For the given table of functions, add all the indicated prototypes for each @@ -390,10 +368,8 @@ void AddTabledBuiltin(TString& decls, const BuiltInFunction& function) if (arg == function.numArguments - 1 && (function.classes & ClassLO)) decls.append("out "); if (arg == 0) { -#ifndef GLSLANG_WEB if (function.classes & ClassCV) decls.append("coherent volatile "); -#endif if (function.classes & ClassFIO) decls.append("inout "); if (function.classes & ClassFO) @@ -420,19 +396,14 @@ void AddTabledBuiltin(TString& decls, const BuiltInFunction& function) // See if the tabled versioning information allows the current version. bool ValidVersion(const BuiltInFunction& function, int version, EProfile profile, const SpvVersion& /* spVersion */) { -#if defined(GLSLANG_WEB) || defined(GLSLANG_ANGLE) - // all entries in table are valid - return true; -#endif - // nullptr means always valid - if (function.versioning == nullptr) + if (function.versioning.empty()) return true; // check for what is said about our current profile - for (const Versioning* v = function.versioning; v->profiles != EBadProfile; ++v) { - if ((v->profiles & profile) != 0) { - if (v->minCoreVersion <= version || (v->numExtensions > 0 && v->minExtendedVersion <= version)) + for (const auto& v : function.versioning) { + if ((v.profiles & profile) != 0) { + if (v.minCoreVersion <= version || (v.numExtensions > 0 && v.minExtendedVersion <= version)) return true; } } @@ -445,12 +416,11 @@ bool ValidVersion(const BuiltInFunction& function, int version, EProfile profile // called once per stage). This is a performance issue only, not a correctness // concern. It is done for quality arising from simplicity, as there are subtleties // to get correct if instead trying to do it surgically. -template -void RelateTabledBuiltins(const FunctionT* functions, TSymbolTable& symbolTable) +template +void RelateTabledBuiltins(const FunctionContainer& functions, TSymbolTable& symbolTable) { - while (functions->op != EOpNull) { - symbolTable.relateToOperator(functions->name, functions->op); - ++functions; + for (const auto& fn : functions) { + symbolTable.relateToOperator(fn.name, fn.op); } } @@ -459,11 +429,10 @@ void RelateTabledBuiltins(const FunctionT* functions, TSymbolTable& symbolTable) // Add declarations for all tables of built-in functions. void TBuiltIns::addTabledBuiltins(int version, EProfile profile, const SpvVersion& spvVersion) { - const auto forEachFunction = [&](TString& decls, const BuiltInFunction* function) { - while (function->op != EOpNull) { - if (ValidVersion(*function, version, profile, spvVersion)) - AddTabledBuiltin(decls, *function); - ++function; + const auto forEachFunction = [&](TString& decls, const span& functions) { + for (const auto& fn : functions) { + if (ValidVersion(fn, version, profile, spvVersion)) + AddTabledBuiltin(decls, fn); } }; @@ -505,7 +474,6 @@ TBuiltIns::TBuiltIns() prefixes[EbtFloat] = ""; prefixes[EbtInt] = "i"; prefixes[EbtUint] = "u"; -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) prefixes[EbtFloat16] = "f16"; prefixes[EbtInt8] = "i8"; prefixes[EbtUint8] = "u8"; @@ -513,7 +481,6 @@ TBuiltIns::TBuiltIns() prefixes[EbtUint16] = "u16"; prefixes[EbtInt64] = "i64"; prefixes[EbtUint64] = "u64"; -#endif postfixes[2] = "2"; postfixes[3] = "3"; @@ -523,14 +490,11 @@ TBuiltIns::TBuiltIns() dimMap[Esd2D] = 2; dimMap[Esd3D] = 3; dimMap[EsdCube] = 3; -#ifndef GLSLANG_WEB -#ifndef GLSLANG_ANGLE dimMap[Esd1D] = 1; -#endif dimMap[EsdRect] = 2; dimMap[EsdBuffer] = 1; dimMap[EsdSubpass] = 2; // potentially unused for now -#endif + dimMap[EsdAttachmentEXT] = 2; // potentially unused for now } TBuiltIns::~TBuiltIns() @@ -548,13 +512,6 @@ TBuiltIns::~TBuiltIns() // void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvVersion) { -#ifdef GLSLANG_WEB - version = 310; - profile = EEsProfile; -#elif defined(GLSLANG_ANGLE) - version = 450; - profile = ECoreProfile; -#endif addTabledBuiltins(version, profile, spvVersion); //============================================================================ @@ -563,7 +520,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV // //============================================================================ -#ifndef GLSLANG_WEB // // Derivatives Functions. // @@ -599,7 +555,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec4 fwidthCoarse(vec4 p);" ); -#ifndef GLSLANG_ANGLE TString derivativesAndControl16bits ( "float16_t dFdx(float16_t);" "f16vec2 dFdx(f16vec2);" @@ -1393,7 +1348,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n" ); } -#endif // !GLSLANG_ANGLE if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 430)) { @@ -1431,7 +1385,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifndef GLSLANG_ANGLE if (profile != EEsProfile && version >= 440) { commonBuiltins.append( "uint64_t atomicMin(coherent volatile inout uint64_t, uint64_t);" @@ -1511,8 +1464,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void atomicStore(coherent volatile out double, double, int, int, int);" "\n"); } -#endif // !GLSLANG_ANGLE -#endif // !GLSLANG_WEB if ((profile == EEsProfile && version >= 300) || (profile != EEsProfile && version >= 150)) { // GL_ARB_shader_bit_encoding @@ -1540,7 +1491,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifndef GLSLANG_WEB if ((profile != EEsProfile && version >= 400) || (profile == EEsProfile && version >= 310)) { // GL_OES_gpu_shader5 @@ -1552,7 +1502,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifndef GLSLANG_ANGLE if (profile != EEsProfile && version >= 150) { // ARB_gpu_shader_fp64 commonBuiltins.append( "double fma(double, double, double);" @@ -1570,7 +1519,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "f64vec4 fma(f64vec4, f64vec4, f64vec4 );" "\n"); } -#endif if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 400)) { @@ -1588,7 +1536,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifndef GLSLANG_ANGLE if (profile != EEsProfile && version >= 150) { // ARB_gpu_shader_fp64 commonBuiltins.append( "double frexp(double, out int);" @@ -1621,8 +1568,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#endif -#endif if ((profile == EEsProfile && version >= 300) || (profile != EEsProfile && version >= 150)) { @@ -1651,7 +1596,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifndef GLSLANG_WEB if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 150)) { commonBuiltins.append( @@ -1671,7 +1615,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec4 unpackUnorm4x8(highp uint);" "\n"); } -#endif // // Matrix Functions. @@ -1730,8 +1673,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } } -#ifndef GLSLANG_WEB -#ifndef GLSLANG_ANGLE // // Original-style texture functions existing in all stages. // (Per-stage functions below.) @@ -1752,7 +1693,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec4 textureCube(samplerCube, vec3);" - "vec4 texture2DArray(sampler2DArray, vec3);" // GL_EXT_texture_array + "vec4 texture2DArray(sampler2DArray, vec3);" // GL_EXT_texture_array + "vec4 texture2DArray(sampler2DArray, vec3, float);" // GL_EXT_texture_array "\n"); } @@ -1782,7 +1724,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec4 texture1DArray(sampler1DArray, vec2);" // GL_EXT_texture_array "vec4 shadow1DArray(sampler1DArrayShadow, vec3);" // GL_EXT_texture_array "vec4 shadow2DArray(sampler2DArrayShadow, vec4);" // GL_EXT_texture_array - + "vec4 texture1DArray(sampler1DArray, vec2, float);" // GL_EXT_texture_array + "vec4 shadow1DArray(sampler1DArrayShadow, vec3, float);" // GL_EXT_texture_array + "vec4 texture1DArrayLod(sampler1DArray, vec2, float);" // GL_EXT_texture_array + "vec4 texture2DArrayLod(sampler2DArray, vec3, float);" // GL_EXT_texture_array + "vec4 shadow1DArrayLod(sampler1DArrayShadow, vec3, float);" // GL_EXT_texture_array "\n"); } } @@ -1932,7 +1878,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } } -#endif // !GLSLANG_ANGLE // Bitfield if ((profile == EEsProfile && version >= 310) || @@ -2075,7 +2020,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifndef GLSLANG_ANGLE // GL_ARB_shader_ballot if (profile != EEsProfile && version >= 450) { commonBuiltins.append( @@ -2274,11 +2218,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n" ); - stageBuiltins[EShLangMeshNV].append( + stageBuiltins[EShLangMesh].append( "void subgroupMemoryBarrierShared();" "\n" ); - stageBuiltins[EShLangTaskNV].append( + stageBuiltins[EShLangTask].append( "void subgroupMemoryBarrierShared();" "\n" ); @@ -3396,7 +3340,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "bool textureFootprintGradClampNV(sampler2D, vec2, vec2, vec2, float, int, bool, out gl_TextureFootprint2DNV);" "\n"); } -#endif // !GLSLANG_ANGLE if ((profile == EEsProfile && version >= 300 && version < 310) || (profile != EEsProfile && version >= 150 && version < 450)) { // GL_EXT_shader_integer_mix @@ -3416,7 +3359,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifndef GLSLANG_ANGLE // GL_AMD_gpu_shader_half_float/Explicit types if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 310)) { commonBuiltins.append( @@ -4169,6 +4111,19 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } + // Builtins for GL_EXT_texture_shadow_lod + if ((profile == EEsProfile && version >= 300) || ((profile != EEsProfile && version >= 130))) { + commonBuiltins.append( + "float texture(sampler2DArrayShadow, vec4, float);" + "float texture(samplerCubeArrayShadow, vec4, float, float);" + "float textureLod(sampler2DArrayShadow, vec4, float);" + "float textureLod(samplerCubeShadow, vec4, float);" + "float textureLod(samplerCubeArrayShadow, vec4, float, float);" + "float textureLodOffset(sampler2DArrayShadow, vec4, float, ivec2);" + "float textureOffset(sampler2DArrayShadow, vec4 , ivec2, float);" + "\n"); + } + if (profile != EEsProfile && version >= 450) { stageBuiltins[EShLangFragment].append(derivativesAndControl64bits); stageBuiltins[EShLangFragment].append( @@ -4190,7 +4145,18 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#endif // !GLSLANG_ANGLE + + // QCOM_image_processing + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + commonBuiltins.append( + "vec4 textureWeightedQCOM(sampler2D, vec2, sampler2DArray);" + "vec4 textureWeightedQCOM(sampler2D, vec2, sampler1DArray);" + "vec4 textureBoxFilterQCOM(sampler2D, vec2, vec2);" + "vec4 textureBlockMatchSADQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);" + "vec4 textureBlockMatchSSDQCOM(sampler2D, uvec2, sampler2D, uvec2, uvec2);" + "\n"); + } //============================================================================ // @@ -4206,7 +4172,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV if (spvVersion.vulkan == 0 && IncludeLegacy(version, profile, spvVersion)) stageBuiltins[EShLangVertex].append("vec4 ftransform();"); -#ifndef GLSLANG_ANGLE // // Original-style texture Functions with lod. // @@ -4228,8 +4193,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec4 texture3DProjLod(sampler3D, vec4, float);" // GL_ARB_shader_texture_lod // OES_texture_3D, but caught by keyword check "vec4 textureCubeLod(samplerCube, vec3, float);" // GL_ARB_shader_texture_lod - "vec4 texture2DArrayLod(sampler2DArray, vec3, float);" // GL_EXT_texture_array - "\n"); } } @@ -4265,14 +4228,9 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec4 shadow2DRectGradARB( sampler2DRectShadow, vec3, vec2, vec2);" // GL_ARB_shader_texture_lod "vec4 shadow2DRectProjGradARB(sampler2DRectShadow, vec4, vec2, vec2);" // GL_ARB_shader_texture_lod - "vec4 texture1DArrayLod(sampler1DArray, vec2, float);" // GL_EXT_texture_array - "vec4 shadow1DArrayLod(sampler1DArrayShadow, vec3, float);" // GL_EXT_texture_array - "vec4 shadow2DArrayLod(sampler2DArrayShadow, vec4, float);" // GL_EXT_texture_array - "\n"); } } -#endif // !GLSLANG_ANGLE if ((profile != EEsProfile && version >= 150) || (profile == EEsProfile && version >= 310)) { @@ -4282,7 +4240,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV // //============================================================================ - if (profile != EEsProfile && version >= 400) { + if (profile != EEsProfile && (version >= 400 || version == 150)) { stageBuiltins[EShLangGeometry].append( "void EmitStreamVertex(int);" "void EndStreamPrimitive(int);" @@ -4293,7 +4251,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void EndPrimitive();" "\n"); } -#endif // !GLSLANG_WEB //============================================================================ // @@ -4310,10 +4267,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void barrier();" ); if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { - stageBuiltins[EShLangMeshNV].append( + stageBuiltins[EShLangMesh].append( "void barrier();" ); - stageBuiltins[EShLangTaskNV].append( + stageBuiltins[EShLangTask].append( "void barrier();" ); } @@ -4330,7 +4287,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void groupMemoryBarrier();" ); } -#ifndef GLSLANG_WEB if ((profile != EEsProfile && version >= 420) || esBarrier) { if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed) { commonBuiltins.append("void memoryBarrierAtomicCounter();"); @@ -4338,11 +4294,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV commonBuiltins.append("void memoryBarrierImage();"); } if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { - stageBuiltins[EShLangMeshNV].append( + stageBuiltins[EShLangMesh].append( "void memoryBarrierShared();" "void groupMemoryBarrier();" ); - stageBuiltins[EShLangTaskNV].append( + stageBuiltins[EShLangTask].append( "void memoryBarrierShared();" "void groupMemoryBarrier();" ); @@ -4353,7 +4309,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV commonBuiltins.append("void debugPrintfEXT();\n"); -#ifndef GLSLANG_ANGLE if (profile != EEsProfile && version >= 450) { // coopMatStoreNV perhaps ought to have "out" on the buf parameter, but // adding it introduces undesirable tempArgs on the stack. What we want @@ -4434,6 +4389,94 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "icoopmatNV coopMatMulAddNV(icoopmatNV A, icoopmatNV B, icoopmatNV C);\n" "ucoopmatNV coopMatMulAddNV(ucoopmatNV A, ucoopmatNV B, ucoopmatNV C);\n" ); + + std::string cooperativeMatrixFuncs = + "void coopMatLoad(out coopmat m, volatile coherent int8_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent int16_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent int32_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent int64_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent uint8_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent uint16_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent uint32_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent uint64_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent float16_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent float[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent float64_t[] buf, uint element, uint stride, int matrixLayout);\n" + + "void coopMatLoad(out coopmat m, volatile coherent i8vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent i16vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent i32vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent i64vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent u8vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent u16vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent u32vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent u64vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent f16vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent f32vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent f64vec2[] buf, uint element, uint stride, int matrixLayout);\n" + + "void coopMatLoad(out coopmat m, volatile coherent i8vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent i16vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent i32vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent i64vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent u8vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent u16vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent u32vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent u64vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent f16vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent f32vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatLoad(out coopmat m, volatile coherent f64vec4[] buf, uint element, uint stride, int matrixLayout);\n" + + "void coopMatStore(coopmat m, volatile coherent int8_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent int16_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent int32_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent int64_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent uint8_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent uint16_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent uint32_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent uint64_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent float16_t[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent float[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent float64_t[] buf, uint element, uint stride, int matrixLayout);\n" + + "void coopMatStore(coopmat m, volatile coherent i8vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent i16vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent i32vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent i64vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent u8vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent u16vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent u32vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent u64vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent f16vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent f32vec2[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent f64vec2[] buf, uint element, uint stride, int matrixLayout);\n" + + "void coopMatStore(coopmat m, volatile coherent i8vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent i16vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent i32vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent i64vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent u8vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent u16vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent u32vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent u64vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent f16vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent f32vec4[] buf, uint element, uint stride, int matrixLayout);\n" + "void coopMatStore(coopmat m, volatile coherent f64vec4[] buf, uint element, uint stride, int matrixLayout);\n" + + "coopmat coopMatMulAdd(coopmat A, coopmat B, coopmat C);\n" + "coopmat coopMatMulAdd(coopmat A, coopmat B, coopmat C, int matrixOperands);\n"; + + commonBuiltins.append(cooperativeMatrixFuncs.c_str()); + + commonBuiltins.append( + "const int gl_MatrixUseA = 0;\n" + "const int gl_MatrixUseB = 1;\n" + "const int gl_MatrixUseAccumulator = 2;\n" + "const int gl_MatrixOperandsSaturatingAccumulation = 0x10;\n" + "const int gl_CooperativeMatrixLayoutRowMajor = 0;\n" + "const int gl_CooperativeMatrixLayoutColumnMajor = 1;\n" + "\n" + ); } //============================================================================ @@ -4453,7 +4496,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec4 texture3D(sampler3D, vec3, float);" // OES_texture_3D "vec4 texture3DProj(sampler3D, vec4, float);" // OES_texture_3D "vec4 textureCube(samplerCube, vec3, float);" - "vec4 texture2DArray(sampler2DArray, vec3, float);" // GL_EXT_texture_array "\n"); } @@ -4466,9 +4508,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec4 shadow2D(sampler2DShadow, vec3, float);" "vec4 shadow1DProj(sampler1DShadow, vec4, float);" "vec4 shadow2DProj(sampler2DShadow, vec4, float);" - "vec4 texture1DArray(sampler1DArray, vec2, float);" // GL_EXT_texture_array - "vec4 shadow1DArray(sampler1DArrayShadow, vec3, float);" // GL_EXT_texture_array - "vec4 shadow2DArray(sampler2DArrayShadow, vec4, float);" // GL_EXT_texture_array + "\n"); } if (spvVersion.spv == 0 && profile == EEsProfile) { @@ -4480,7 +4520,24 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#endif // !GLSLANG_ANGLE + + // GL_EXT_shader_tile_image + if (spvVersion.vulkan > 0) { + stageBuiltins[EShLangFragment].append( + "lowp uint stencilAttachmentReadEXT();" + "lowp uint stencilAttachmentReadEXT(int);" + "highp float depthAttachmentReadEXT();" + "highp float depthAttachmentReadEXT(int);" + "\n"); + stageBuiltins[EShLangFragment].append( + "vec4 colorAttachmentReadEXT(attachmentEXT);" + "vec4 colorAttachmentReadEXT(attachmentEXT, int);" + "ivec4 colorAttachmentReadEXT(iattachmentEXT);" + "ivec4 colorAttachmentReadEXT(iattachmentEXT, int);" + "uvec4 colorAttachmentReadEXT(uattachmentEXT);" + "uvec4 colorAttachmentReadEXT(uattachmentEXT, int);" + "\n"); + } // GL_ARB_derivative_control if (profile != EEsProfile && version >= 400) { @@ -4518,7 +4575,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "bool helperInvocationEXT();" "\n"); -#ifndef GLSLANG_ANGLE // GL_AMD_shader_explicit_vertex_parameter if (profile != EEsProfile && version >= 450) { stageBuiltins[EShLangFragment].append( @@ -4591,9 +4647,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "uvec4 fragmentFetchAMD(usubpassInputMS, uint);" "\n"); - } + } - // Builtins for GL_NV_ray_tracing/GL_NV_ray_tracing_motion_blur/GL_EXT_ray_tracing/GL_EXT_ray_query + // Builtins for GL_NV_ray_tracing/GL_NV_ray_tracing_motion_blur/GL_EXT_ray_tracing/GL_EXT_ray_query/ + // GL_NV_shader_invocation_reorder/GL_KHR_ray_tracing_position_Fetch if (profile != EEsProfile && version >= 460) { commonBuiltins.append("void rayQueryInitializeEXT(rayQueryEXT, accelerationStructureEXT, uint, uint, vec3, float, vec3, float);" "void rayQueryTerminateEXT(rayQueryEXT);" @@ -4618,6 +4675,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "vec3 rayQueryGetIntersectionObjectRayOriginEXT(rayQueryEXT, bool);" "mat4x3 rayQueryGetIntersectionObjectToWorldEXT(rayQueryEXT, bool);" "mat4x3 rayQueryGetIntersectionWorldToObjectEXT(rayQueryEXT, bool);" + "void rayQueryGetIntersectionTriangleVertexPositionsEXT(rayQueryEXT, bool, out vec3[3]);" "\n"); stageBuiltins[EShLangRayGen].append( @@ -4626,6 +4684,41 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void executeCallableNV(uint, int);" "void executeCallableEXT(uint, int);" + "void hitObjectTraceRayNV(hitObjectNV,accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" + "void hitObjectTraceRayMotionNV(hitObjectNV,accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);" + "void hitObjectRecordHitNV(hitObjectNV,accelerationStructureEXT,int,int,int,uint,uint,uint,vec3,float,vec3,float,int);" + "void hitObjectRecordHitMotionNV(hitObjectNV,accelerationStructureEXT,int,int,int,uint,uint,uint,vec3,float,vec3,float,float,int);" + "void hitObjectRecordHitWithIndexNV(hitObjectNV, accelerationStructureEXT,int,int,int,uint,uint,vec3,float,vec3,float,int);" + "void hitObjectRecordHitWithIndexMotionNV(hitObjectNV, accelerationStructureEXT,int,int,int,uint,uint,vec3,float,vec3,float,float,int);" + "void hitObjectRecordMissNV(hitObjectNV,uint,vec3,float,vec3,float);" + "void hitObjectRecordMissMotionNV(hitObjectNV,uint,vec3,float,vec3,float,float);" + "void hitObjectRecordEmptyNV(hitObjectNV);" + "void hitObjectExecuteShaderNV(hitObjectNV,int);" + "bool hitObjectIsEmptyNV(hitObjectNV);" + "bool hitObjectIsMissNV(hitObjectNV);" + "bool hitObjectIsHitNV(hitObjectNV);" + "float hitObjectGetRayTMinNV(hitObjectNV);" + "float hitObjectGetRayTMaxNV(hitObjectNV);" + "vec3 hitObjectGetWorldRayOriginNV(hitObjectNV);" + "vec3 hitObjectGetWorldRayDirectionNV(hitObjectNV);" + "vec3 hitObjectGetObjectRayOriginNV(hitObjectNV);" + "vec3 hitObjectGetObjectRayDirectionNV(hitObjectNV);" + "mat4x3 hitObjectGetWorldToObjectNV(hitObjectNV);" + "mat4x3 hitObjectGetObjectToWorldNV(hitObjectNV);" + "int hitObjectGetInstanceCustomIndexNV(hitObjectNV);" + "int hitObjectGetInstanceIdNV(hitObjectNV);" + "int hitObjectGetGeometryIndexNV(hitObjectNV);" + "int hitObjectGetPrimitiveIndexNV(hitObjectNV);" + "uint hitObjectGetHitKindNV(hitObjectNV);" + "void hitObjectGetAttributesNV(hitObjectNV,int);" + "float hitObjectGetCurrentTimeNV(hitObjectNV);" + "uint hitObjectGetShaderBindingTableRecordIndexNV(hitObjectNV);" + "uvec2 hitObjectGetShaderRecordBufferHandleNV(hitObjectNV);" + "void reorderThreadNV(uint, uint);" + "void reorderThreadNV(hitObjectNV);" + "void reorderThreadNV(hitObjectNV, uint, uint);" + "vec3 fetchMicroTriangleVertexPositionNV(accelerationStructureEXT, int, int, int, ivec2);" + "vec2 fetchMicroTriangleVertexBarycentricNV(accelerationStructureEXT, int, int, int, ivec2);" "\n"); stageBuiltins[EShLangIntersect].append( "bool reportIntersectionNV(float, uint);" @@ -4641,6 +4734,36 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void executeCallableNV(uint, int);" "void executeCallableEXT(uint, int);" + "void hitObjectTraceRayNV(hitObjectNV,accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" + "void hitObjectTraceRayMotionNV(hitObjectNV,accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);" + "void hitObjectRecordHitNV(hitObjectNV,accelerationStructureEXT,int,int,int,uint,uint,uint,vec3,float,vec3,float,int);" + "void hitObjectRecordHitMotionNV(hitObjectNV,accelerationStructureEXT,int,int,int,uint,uint,uint,vec3,float,vec3,float,float,int);" + "void hitObjectRecordHitWithIndexNV(hitObjectNV,accelerationStructureEXT,int,int,int,uint,uint,vec3,float,vec3,float,int);" + "void hitObjectRecordHitWithIndexMotionNV(hitObjectNV, accelerationStructureEXT,int,int,int,uint,uint,vec3,float,vec3,float,float,int);" + "void hitObjectRecordMissNV(hitObjectNV, uint, vec3, float, vec3, float);" + "void hitObjectRecordMissMotionNV(hitObjectNV,uint,vec3,float,vec3,float,float);" + "void hitObjectRecordEmptyNV(hitObjectNV);" + "void hitObjectExecuteShaderNV(hitObjectNV, int);" + "bool hitObjectIsEmptyNV(hitObjectNV);" + "bool hitObjectIsMissNV(hitObjectNV);" + "bool hitObjectIsHitNV(hitObjectNV);" + "float hitObjectGetRayTMinNV(hitObjectNV);" + "float hitObjectGetRayTMaxNV(hitObjectNV);" + "vec3 hitObjectGetWorldRayOriginNV(hitObjectNV);" + "vec3 hitObjectGetWorldRayDirectionNV(hitObjectNV);" + "vec3 hitObjectGetObjectRayOriginNV(hitObjectNV);" + "vec3 hitObjectGetObjectRayDirectionNV(hitObjectNV);" + "mat4x3 hitObjectGetWorldToObjectNV(hitObjectNV);" + "mat4x3 hitObjectGetObjectToWorldNV(hitObjectNV);" + "int hitObjectGetInstanceCustomIndexNV(hitObjectNV);" + "int hitObjectGetInstanceIdNV(hitObjectNV);" + "int hitObjectGetGeometryIndexNV(hitObjectNV);" + "int hitObjectGetPrimitiveIndexNV(hitObjectNV);" + "uint hitObjectGetHitKindNV(hitObjectNV);" + "void hitObjectGetAttributesNV(hitObjectNV,int);" + "float hitObjectGetCurrentTimeNV(hitObjectNV);" + "uint hitObjectGetShaderBindingTableRecordIndexNV(hitObjectNV);" + "uvec2 hitObjectGetShaderRecordBufferHandleNV(hitObjectNV);" "\n"); stageBuiltins[EShLangMiss].append( "void traceNV(accelerationStructureNV,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" @@ -4648,20 +4771,48 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "void traceRayEXT(accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" "void executeCallableNV(uint, int);" "void executeCallableEXT(uint, int);" + "void hitObjectTraceRayNV(hitObjectNV,accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,int);" + "void hitObjectTraceRayMotionNV(hitObjectNV,accelerationStructureEXT,uint,uint,uint,uint,uint,vec3,float,vec3,float,float,int);" + "void hitObjectRecordHitNV(hitObjectNV,accelerationStructureEXT,int,int,int,uint,uint,uint,vec3,float,vec3,float,int);" + "void hitObjectRecordHitMotionNV(hitObjectNV,accelerationStructureEXT,int,int,int,uint,uint,uint,vec3,float,vec3,float,float,int);" + "void hitObjectRecordHitWithIndexNV(hitObjectNV,accelerationStructureEXT,int,int,int,uint,uint,vec3,float,vec3,float,int);" + "void hitObjectRecordHitWithIndexMotionNV(hitObjectNV, accelerationStructureEXT,int,int,int,uint,uint,vec3,float,vec3,float,float,int);" + "void hitObjectRecordMissNV(hitObjectNV, uint, vec3, float, vec3, float);" + "void hitObjectRecordMissMotionNV(hitObjectNV,uint,vec3,float,vec3,float,float);" + "void hitObjectRecordEmptyNV(hitObjectNV);" + "void hitObjectExecuteShaderNV(hitObjectNV, int);" + "bool hitObjectIsEmptyNV(hitObjectNV);" + "bool hitObjectIsMissNV(hitObjectNV);" + "bool hitObjectIsHitNV(hitObjectNV);" + "float hitObjectGetRayTMinNV(hitObjectNV);" + "float hitObjectGetRayTMaxNV(hitObjectNV);" + "vec3 hitObjectGetWorldRayOriginNV(hitObjectNV);" + "vec3 hitObjectGetWorldRayDirectionNV(hitObjectNV);" + "vec3 hitObjectGetObjectRayOriginNV(hitObjectNV);" + "vec3 hitObjectGetObjectRayDirectionNV(hitObjectNV);" + "mat4x3 hitObjectGetWorldToObjectNV(hitObjectNV);" + "mat4x3 hitObjectGetObjectToWorldNV(hitObjectNV);" + "int hitObjectGetInstanceCustomIndexNV(hitObjectNV);" + "int hitObjectGetInstanceIdNV(hitObjectNV);" + "int hitObjectGetGeometryIndexNV(hitObjectNV);" + "int hitObjectGetPrimitiveIndexNV(hitObjectNV);" + "uint hitObjectGetHitKindNV(hitObjectNV);" + "void hitObjectGetAttributesNV(hitObjectNV,int);" + "float hitObjectGetCurrentTimeNV(hitObjectNV);" + "uint hitObjectGetShaderBindingTableRecordIndexNV(hitObjectNV);" + "uvec2 hitObjectGetShaderRecordBufferHandleNV(hitObjectNV);" "\n"); stageBuiltins[EShLangCallable].append( "void executeCallableNV(uint, int);" "void executeCallableEXT(uint, int);" "\n"); } -#endif // !GLSLANG_ANGLE //E_SPV_NV_compute_shader_derivatives if ((profile == EEsProfile && version >= 320) || (profile != EEsProfile && version >= 450)) { stageBuiltins[EShLangCompute].append(derivativeControls); stageBuiltins[EShLangCompute].append("\n"); } -#ifndef GLSLANG_ANGLE if (profile != EEsProfile && version >= 450) { stageBuiltins[EShLangCompute].append(derivativesAndControl16bits); stageBuiltins[EShLangCompute].append(derivativesAndControl64bits); @@ -4670,12 +4821,35 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV // Builtins for GL_NV_mesh_shader if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { - stageBuiltins[EShLangMeshNV].append( + stageBuiltins[EShLangMesh].append( "void writePackedPrimitiveIndices4x8NV(uint, uint);" "\n"); } -#endif // !GLSLANG_ANGLE -#endif // !GLSLANG_WEB + // Builtins for GL_EXT_mesh_shader + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { + // Builtins for GL_EXT_mesh_shader + stageBuiltins[EShLangTask].append( + "void EmitMeshTasksEXT(uint, uint, uint);" + "\n"); + + stageBuiltins[EShLangMesh].append( + "void SetMeshOutputsEXT(uint, uint);" + "\n"); + } + // Builtins for GL_NV_displacement_micromap + if ((profile != EEsProfile && version >= 460) || (profile == EEsProfile && version >= 320)) { + stageBuiltins[EShLangMesh].append( + "vec3 fetchMicroTriangleVertexPositionNV(accelerationStructureEXT, int, int, int, ivec2);" + "vec2 fetchMicroTriangleVertexBarycentricNV(accelerationStructureEXT, int, int, int, ivec2);" + "\n"); + + stageBuiltins[EShLangCompute].append( + "vec3 fetchMicroTriangleVertexPositionNV(accelerationStructureEXT, int, int, int, ivec2);" + "vec2 fetchMicroTriangleVertexBarycentricNV(accelerationStructureEXT, int, int, int, ivec2);" + "\n"); + + } + //============================================================================ // @@ -4697,13 +4871,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "highp float diff;" // f - n ); } else { -#ifndef GLSLANG_WEB commonBuiltins.append( "float near;" // n "float far;" // f "float diff;" // f - n ); -#endif } commonBuiltins.append( @@ -4712,7 +4884,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) if (spvVersion.spv == 0 && IncludeLegacy(version, profile, spvVersion)) { // // Matrix state. p. 31, 32, 37, 39, 40. @@ -4830,7 +5001,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#endif // !GLSLANG_WEB && !GLSLANG_ANGLE //============================================================================ // @@ -4860,8 +5030,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifndef GLSLANG_WEB -#ifndef GLSLANG_ANGLE //============================================================================ // // Define the interface to the mesh/task shader. @@ -4870,7 +5038,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { // per-vertex attributes - stageBuiltins[EShLangMeshNV].append( + stageBuiltins[EShLangMesh].append( "out gl_MeshPerVertexNV {" "vec4 gl_Position;" "float gl_PointSize;" @@ -4883,7 +5051,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV ); // per-primitive attributes - stageBuiltins[EShLangMeshNV].append( + stageBuiltins[EShLangMesh].append( "perprimitiveNV out gl_MeshPerPrimitiveNV {" "int gl_PrimitiveID;" "int gl_Layer;" @@ -4894,7 +5062,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "} gl_MeshPrimitivesNV[];" ); - stageBuiltins[EShLangMeshNV].append( + stageBuiltins[EShLangMesh].append( "out uint gl_PrimitiveCountNV;" "out uint gl_PrimitiveIndicesNV[];" @@ -4908,10 +5076,38 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in highp uvec3 gl_GlobalInvocationID;" "in highp uint gl_LocalInvocationIndex;" + "\n"); + // GL_EXT_mesh_shader + stageBuiltins[EShLangMesh].append( + "out uint gl_PrimitivePointIndicesEXT[];" + "out uvec2 gl_PrimitiveLineIndicesEXT[];" + "out uvec3 gl_PrimitiveTriangleIndicesEXT[];" + "in highp uvec3 gl_NumWorkGroups;" "\n"); - stageBuiltins[EShLangTaskNV].append( + // per-vertex attributes + stageBuiltins[EShLangMesh].append( + "out gl_MeshPerVertexEXT {" + "vec4 gl_Position;" + "float gl_PointSize;" + "float gl_ClipDistance[];" + "float gl_CullDistance[];" + "} gl_MeshVerticesEXT[];" + ); + + // per-primitive attributes + stageBuiltins[EShLangMesh].append( + "perprimitiveEXT out gl_MeshPerPrimitiveEXT {" + "int gl_PrimitiveID;" + "int gl_Layer;" + "int gl_ViewportIndex;" + "bool gl_CullPrimitiveEXT;" + "int gl_PrimitiveShadingRateEXT;" + "} gl_MeshPrimitivesEXT[];" + ); + + stageBuiltins[EShLangTask].append( "out uint gl_TaskCountNV;" "const highp uvec3 gl_WorkGroupSize = uvec3(1,1,1);" @@ -4924,32 +5120,32 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in uint gl_MeshViewCountNV;" "in uint gl_MeshViewIndicesNV[4];" - + "in highp uvec3 gl_NumWorkGroups;" "\n"); } if (profile != EEsProfile && version >= 450) { - stageBuiltins[EShLangMeshNV].append( + stageBuiltins[EShLangMesh].append( "in highp int gl_DeviceIndex;" // GL_EXT_device_group "in int gl_DrawIDARB;" // GL_ARB_shader_draw_parameters + "in int gl_ViewIndex;" // GL_EXT_multiview "\n"); - stageBuiltins[EShLangTaskNV].append( + stageBuiltins[EShLangTask].append( "in highp int gl_DeviceIndex;" // GL_EXT_device_group "in int gl_DrawIDARB;" // GL_ARB_shader_draw_parameters "\n"); if (version >= 460) { - stageBuiltins[EShLangMeshNV].append( + stageBuiltins[EShLangMesh].append( "in int gl_DrawID;" "\n"); - stageBuiltins[EShLangTaskNV].append( + stageBuiltins[EShLangTask].append( "in int gl_DrawID;" "\n"); } } -#endif // !GLSLANG_ANGLE //============================================================================ // @@ -5053,7 +5249,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV stageBuiltins[EShLangVertex].append( "int gl_VertexID;" // needs qualifier fixed later ); - if (version >= 140 && spvVersion.vulkan == 0) + if (spvVersion.vulkan == 0) stageBuiltins[EShLangVertex].append( "int gl_InstanceID;" // needs qualifier fixed later ); @@ -5108,6 +5304,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV stageBuiltins[EShLangVertex].append( "highp vec4 gl_Position;" // needs qualifier fixed later "mediump float gl_PointSize;" // needs qualifier fixed later + "highp int gl_InstanceID;" // needs qualifier fixed later ); } else { if (spvVersion.vulkan == 0 || spvVersion.vulkanRelaxed) @@ -5116,19 +5313,15 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in highp int gl_InstanceID;" // needs qualifier fixed later ); if (spvVersion.vulkan > 0) -#endif stageBuiltins[EShLangVertex].append( "in highp int gl_VertexIndex;" "in highp int gl_InstanceIndex;" ); -#ifndef GLSLANG_WEB if (version < 310) -#endif stageBuiltins[EShLangVertex].append( "highp vec4 gl_Position;" // needs qualifier fixed later "highp float gl_PointSize;" // needs qualifier fixed later ); -#ifndef GLSLANG_WEB else stageBuiltins[EShLangVertex].append( "out gl_PerVertex {" @@ -5586,6 +5779,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "flat in int gl_InvocationsPerPixelNV;" "in vec3 gl_BaryCoordNV;" // GL_NV_fragment_shader_barycentric "in vec3 gl_BaryCoordNoPerspNV;" + "in vec3 gl_BaryCoordEXT;" // GL_EXT_fragment_shader_barycentric + "in vec3 gl_BaryCoordNoPerspEXT;" ); if (version >= 450) @@ -5604,7 +5799,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "mediump vec2 gl_PointCoord;" // needs qualifier fixed later ); } -#endif if (version >= 300) { stageBuiltins[EShLangFragment].append( "highp vec4 gl_FragCoord;" // needs qualifier fixed later @@ -5613,7 +5807,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "highp float gl_FragDepth;" // needs qualifier fixed later ); } -#ifndef GLSLANG_WEB if (version >= 310) { stageBuiltins[EShLangFragment].append( "bool gl_HelperInvocation;" // needs qualifier fixed later @@ -5650,21 +5843,20 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV stageBuiltins[EShLangFragment].append( "in vec3 gl_BaryCoordNV;" "in vec3 gl_BaryCoordNoPerspNV;" - ); + "in vec3 gl_BaryCoordEXT;" + "in vec3 gl_BaryCoordNoPerspEXT;" + ); if (version >= 310) stageBuiltins[EShLangFragment].append( "flat in highp int gl_ShadingRateEXT;" // GL_EXT_fragment_shading_rate ); } -#endif stageBuiltins[EShLangFragment].append("\n"); if (version >= 130) add2ndGenerationSamplingImaging(version, profile, spvVersion); -#ifndef GLSLANG_WEB - if ((profile != EEsProfile && version >= 140) || (profile == EEsProfile && version >= 310)) { stageBuiltins[EShLangFragment].append( @@ -5679,7 +5871,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "\n"); } -#ifndef GLSLANG_ANGLE // GL_ARB_shader_ballot if (profile != EEsProfile && version >= 450) { const char* ballotDecls = @@ -5715,8 +5906,8 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV stageBuiltins[EShLangGeometry] .append(ballotDecls); stageBuiltins[EShLangCompute] .append(ballotDecls); stageBuiltins[EShLangFragment] .append(fragmentBallotDecls); - stageBuiltins[EShLangMeshNV] .append(ballotDecls); - stageBuiltins[EShLangTaskNV] .append(ballotDecls); + stageBuiltins[EShLangMesh] .append(ballotDecls); + stageBuiltins[EShLangTask] .append(ballotDecls); stageBuiltins[EShLangRayGen] .append(rtBallotDecls); stageBuiltins[EShLangIntersect] .append(rtBallotDecls); // No volatile qualifier on these builtins in any-hit @@ -5742,6 +5933,12 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in highp uint gl_SMCountNV;" "in highp uint gl_WarpIDNV;" "in highp uint gl_SMIDNV;" + // GL_ARM_shader_core_builtins + "in highp uint gl_CoreIDARM;" + "in highp uint gl_CoreCountARM;" + "in highp uint gl_CoreMaxIDARM;" + "in highp uint gl_WarpIDARM;" + "in highp uint gl_WarpMaxIDARM;" "\n"; const char* fragmentSubgroupDecls = "flat in mediump uint gl_SubgroupSize;" @@ -5756,6 +5953,12 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "flat in highp uint gl_SMCountNV;" "flat in highp uint gl_WarpIDNV;" "flat in highp uint gl_SMIDNV;" + // GL_ARM_shader_core_builtins + "flat in highp uint gl_CoreIDARM;" + "flat in highp uint gl_CoreCountARM;" + "flat in highp uint gl_CoreMaxIDARM;" + "flat in highp uint gl_WarpIDARM;" + "flat in highp uint gl_WarpMaxIDARM;" "\n"; const char* computeSubgroupDecls = "in highp uint gl_NumSubgroups;" @@ -5775,6 +5978,12 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in highp uint gl_SMCountNV;" "in highp volatile uint gl_WarpIDNV;" "in highp volatile uint gl_SMIDNV;" + // GL_ARM_shader_core_builtins + "in highp uint gl_CoreIDARM;" + "in highp uint gl_CoreCountARM;" + "in highp uint gl_CoreMaxIDARM;" + "in highp uint gl_WarpIDARM;" + "in highp uint gl_WarpMaxIDARM;" "\n"; stageBuiltins[EShLangVertex] .append(subgroupDecls); @@ -5784,10 +5993,10 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV stageBuiltins[EShLangCompute] .append(subgroupDecls); stageBuiltins[EShLangCompute] .append(computeSubgroupDecls); stageBuiltins[EShLangFragment] .append(fragmentSubgroupDecls); - stageBuiltins[EShLangMeshNV] .append(subgroupDecls); - stageBuiltins[EShLangMeshNV] .append(computeSubgroupDecls); - stageBuiltins[EShLangTaskNV] .append(subgroupDecls); - stageBuiltins[EShLangTaskNV] .append(computeSubgroupDecls); + stageBuiltins[EShLangMesh] .append(subgroupDecls); + stageBuiltins[EShLangMesh] .append(computeSubgroupDecls); + stageBuiltins[EShLangTask] .append(subgroupDecls); + stageBuiltins[EShLangTask] .append(computeSubgroupDecls); stageBuiltins[EShLangRayGen] .append(rtSubgroupDecls); stageBuiltins[EShLangIntersect] .append(rtSubgroupDecls); // No volatile qualifier on these builtins in any-hit @@ -5821,8 +6030,11 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "const uint gl_RayFlagsCullNoOpaqueEXT = 128U;" "const uint gl_RayFlagsSkipTrianglesEXT = 256U;" "const uint gl_RayFlagsSkipAABBEXT = 512U;" + "const uint gl_RayFlagsForceOpacityMicromap2StateEXT = 1024U;" "const uint gl_HitKindFrontFacingTriangleEXT = 254U;" "const uint gl_HitKindBackFacingTriangleEXT = 255U;" + "in uint gl_HitKindFrontFacingMicroTriangleNV;" + "in uint gl_HitKindBackFacingMicroTriangleNV;" "\n"; const char *constRayQueryIntersection = @@ -5872,6 +6084,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in uint gl_IncomingRayFlagsNV;" "in uint gl_IncomingRayFlagsEXT;" "in float gl_CurrentRayTimeNV;" + "in uint gl_CullMaskEXT;" "\n"; const char *hitDecls = "in uvec3 gl_LaunchIDNV;" @@ -5908,7 +6121,12 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in uint gl_IncomingRayFlagsNV;" "in uint gl_IncomingRayFlagsEXT;" "in float gl_CurrentRayTimeNV;" + "in uint gl_CullMaskEXT;" + "in vec3 gl_HitTriangleVertexPositionsEXT[3];" + "in vec3 gl_HitMicroTriangleVertexPositionsNV[3];" + "in vec2 gl_HitMicroTriangleVertexBarycentricsNV[3];" "\n"; + const char *missDecls = "in uvec3 gl_LaunchIDNV;" "in uvec3 gl_LaunchIDEXT;" @@ -5927,6 +6145,7 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV "in uint gl_IncomingRayFlagsNV;" "in uint gl_IncomingRayFlagsEXT;" "in float gl_CurrentRayTimeNV;" + "in uint gl_CullMaskEXT;" "\n"; const char *callableDecls = @@ -6034,9 +6253,6 @@ void TBuiltIns::initialize(int version, EProfile profile, const SpvVersion& spvV } } } -#endif // !GLSLANG_ANGLE - -#endif // !GLSLANG_WEB // printf("%s\n", commonBuiltins.c_str()); // printf("%s\n", stageBuiltins[EShLangFragment].c_str()); @@ -6055,30 +6271,18 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c // enumerate all the types const TBasicType bTypes[] = { EbtFloat, EbtInt, EbtUint, -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) - EbtFloat16 -#endif + EbtFloat16 }; -#ifdef GLSLANG_WEB - bool skipBuffer = true; - bool skipCubeArrayed = true; - const int image = 0; -#else bool skipBuffer = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 140); bool skipCubeArrayed = (profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 130); for (int image = 0; image <= 1; ++image) // loop over "bool" image vs sampler -#endif { for (int shadow = 0; shadow <= 1; ++shadow) { // loop over "bool" shadow or not -#ifdef GLSLANG_WEB - const int ms = 0; -#else for (int ms = 0; ms <= 1; ++ms) // loop over "bool" multisample or not -#endif { if ((ms || image) && shadow) continue; - if (ms && profile != EEsProfile && version < 150) + if (ms && profile != EEsProfile && version < 140) continue; if (ms && image && profile == EEsProfile) continue; @@ -6086,14 +6290,9 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c continue; for (int arrayed = 0; arrayed <= 1; ++arrayed) { // loop over "bool" arrayed or not -#ifdef GLSLANG_WEB - for (int dim = Esd2D; dim <= EsdCube; ++dim) { // 2D, 3D, and Cube -#else -#if defined(GLSLANG_ANGLE) - for (int dim = Esd2D; dim < EsdNumDims; ++dim) { // 2D, ..., buffer, subpass -#else for (int dim = Esd1D; dim < EsdNumDims; ++dim) { // 1D, ..., buffer, subpass -#endif + if (dim == EsdAttachmentEXT) + continue; if (dim == EsdSubpass && spvVersion.vulkan == 0) continue; if (dim == EsdSubpass && (image || shadow || arrayed)) @@ -6114,7 +6313,6 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c continue; if (ms && arrayed && profile == EEsProfile && version < 310) continue; -#endif if (dim == Esd3D && shadow) continue; if (dim == EsdCube && arrayed && skipCubeArrayed) @@ -6124,23 +6322,21 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c // Loop over the bTypes for (size_t bType = 0; bType < sizeof(bTypes)/sizeof(TBasicType); ++bType) { -#ifndef GLSLANG_WEB if (bTypes[bType] == EbtFloat16 && (profile == EEsProfile || version < 450)) continue; if (dim == EsdRect && version < 140 && bType > 0) continue; -#endif if (shadow && (bTypes[bType] == EbtInt || bTypes[bType] == EbtUint)) continue; // // Now, make all the function prototypes for the type we just built... // TSampler sampler; -#ifndef GLSLANG_WEB if (dim == EsdSubpass) { sampler.setSubpass(bTypes[bType], ms ? true : false); + } else if (dim == EsdAttachmentEXT) { + sampler.setAttachmentEXT(bTypes[bType]); } else -#endif if (image) { sampler.setImage(bTypes[bType], (TSamplerDim)dim, arrayed ? true : false, shadow ? true : false, @@ -6153,12 +6349,10 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c TString typeName = sampler.getString(); -#ifndef GLSLANG_WEB if (dim == EsdSubpass) { addSubpassSampling(sampler, typeName, version, profile); continue; } -#endif addQueryFunctions(sampler, typeName, version, profile); @@ -6166,7 +6360,6 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c addImageFunctions(sampler, typeName, version, profile); else { addSamplingFunctions(sampler, typeName, version, profile); -#ifndef GLSLANG_WEB addGatherFunctions(sampler, typeName, version, profile); if (spvVersion.vulkan > 0 && sampler.isCombined() && !sampler.shadow) { // Base Vulkan allows texelFetch() for @@ -6182,7 +6375,6 @@ void TBuiltIns::add2ndGenerationSamplingImaging(int version, EProfile profile, c addSamplingFunctions(sampler, textureTypeName, version, profile); addQueryFunctions(sampler, textureTypeName, version, profile); } -#endif } } } @@ -6213,16 +6405,6 @@ void TBuiltIns::addQueryFunctions(TSampler sampler, const TString& typeName, int int sizeDims = dimMap[sampler.dim] + (sampler.arrayed ? 1 : 0) - (sampler.dim == EsdCube ? 1 : 0); -#ifdef GLSLANG_WEB - commonBuiltins.append("highp "); - commonBuiltins.append("ivec"); - commonBuiltins.append(postfixes[sizeDims]); - commonBuiltins.append(" textureSize("); - commonBuiltins.append(typeName); - commonBuiltins.append(",int);\n"); - return; -#endif - if (sampler.isImage() && ((profile == EEsProfile && version < 310) || (profile != EEsProfile && version < 420))) return; @@ -6542,14 +6724,6 @@ void TBuiltIns::addSubpassSampling(TSampler sampler, const TString& typeName, in // void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile) { -#ifdef GLSLANG_WEB - profile = EEsProfile; - version = 310; -#elif defined(GLSLANG_ANGLE) - profile = ECoreProfile; - version = 450; -#endif - // // texturing // @@ -6624,11 +6798,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, continue; // loop over 16-bit floating-point texel addressing -#if defined(GLSLANG_WEB) || defined(GLSLANG_ANGLE) - const int f16TexAddr = 0; -#else for (int f16TexAddr = 0; f16TexAddr <= 1; ++f16TexAddr) -#endif { if (f16TexAddr && sampler.type != EbtFloat16) continue; @@ -6637,11 +6807,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, totalDims--; } // loop over "bool" lod clamp -#if defined(GLSLANG_WEB) || defined(GLSLANG_ANGLE) - const int lodClamp = 0; -#else for (int lodClamp = 0; lodClamp <= 1 ;++lodClamp) -#endif { if (lodClamp && (profile == EEsProfile || version < 450)) continue; @@ -6649,11 +6815,7 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, continue; // loop over "bool" sparse or not -#if defined(GLSLANG_WEB) || defined(GLSLANG_ANGLE) - const int sparse = 0; -#else for (int sparse = 0; sparse <= 1; ++sparse) -#endif { if (sparse && (profile == EEsProfile || version < 450)) continue; @@ -6830,14 +6992,6 @@ void TBuiltIns::addSamplingFunctions(TSampler sampler, const TString& typeName, // void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, int version, EProfile profile) { -#ifdef GLSLANG_WEB - profile = EEsProfile; - version = 310; -#elif defined(GLSLANG_ANGLE) - profile = ECoreProfile; - version = 450; -#endif - switch (sampler.dim) { case Esd2D: case EsdRect: @@ -7076,14 +7230,6 @@ void TBuiltIns::addGatherFunctions(TSampler sampler, const TString& typeName, in // void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language) { -#ifdef GLSLANG_WEB - version = 310; - profile = EEsProfile; -#elif defined(GLSLANG_ANGLE) - version = 450; - profile = ECoreProfile; -#endif - // // Initialize the context-dependent (resource-dependent) built-in strings for parsing. // @@ -7141,7 +7287,6 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append(builtInConstant); } -#ifndef GLSLANG_WEB if (version >= 310) { // geometry @@ -7464,7 +7609,6 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf snprintf(builtInConstant, maxSize, "const int gl_MaxTransformFeedbackInterleavedComponents = %d;", resources.maxTransformFeedbackInterleavedComponents); s.append(builtInConstant); } -#endif } // compute @@ -7486,7 +7630,6 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append("\n"); } -#ifndef GLSLANG_WEB // images (some in compute below) if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 130)) { @@ -7514,7 +7657,6 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append("\n"); } -#ifndef GLSLANG_ANGLE // atomic counters (some in compute below) if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 420)) { @@ -7551,7 +7693,6 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append("\n"); } -#endif // !GLSLANG_ANGLE // GL_ARB_cull_distance if (profile != EEsProfile && version >= 450) { @@ -7568,7 +7709,6 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append(builtInConstant); } -#ifndef GLSLANG_ANGLE // SPV_NV_mesh_shader if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { snprintf(builtInConstant, maxSize, "const int gl_MaxMeshOutputVerticesNV = %d;", resources.maxMeshOutputVerticesNV); @@ -7591,8 +7731,6 @@ void TBuiltIns::initialize(const TBuiltInResource &resources, int version, EProf s.append("\n"); } -#endif -#endif s.append("\n"); } @@ -7621,6 +7759,23 @@ static void SpecialQualifier(const char* name, TStorageQualifier qualifier, TBui symQualifier.builtIn = builtIn; } +// +// Modify the symbol's flat decoration. +// +// Safe to call even if name is not present. +// +// Originally written to transform gl_SubGroupSizeARB from uniform to fragment input in Vulkan. +// +static void ModifyFlatDecoration(const char* name, bool flat, TSymbolTable& symbolTable) +{ + TSymbol* symbol = symbolTable.find(name); + if (symbol == nullptr) + return; + + TQualifier& symQualifier = symbol->getWritableType().getQualifier(); + symQualifier.flat = flat; +} + // // To tag built-in variables with their TBuiltInVariable enum. Use this when the // normal declaration text already gets the qualifier right, and all that's needed @@ -7678,14 +7833,6 @@ static void BuiltInVariable(const char* blockName, const char* name, TBuiltInVar // void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable) { -#ifdef GLSLANG_WEB - version = 310; - profile = EEsProfile; -#elif defined(GLSLANG_ANGLE) - version = 450; - profile = ECoreProfile; -#endif - // // Tag built-in variables and functions with additional qualifier and extension information // that cannot be declared with the text strings. @@ -7705,10 +7852,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_InstanceIndex", EbvInstanceIndex, symbolTable); } -#ifndef GLSLANG_WEB if (spvVersion.vulkan == 0) { SpecialQualifier("gl_VertexID", EvqVertexId, EbvVertexId, symbolTable); SpecialQualifier("gl_InstanceID", EvqInstanceId, EbvInstanceId, symbolTable); + if (version < 140) + symbolTable.setVariableExtensions("gl_InstanceID", 1, &E_GL_EXT_draw_instanced); } if (spvVersion.vulkan > 0 && spvVersion.vulkanRelaxed) { @@ -7860,6 +8008,20 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("shadow2DEXT", 1, &E_GL_EXT_shadow_samplers); symbolTable.setFunctionExtensions("shadow2DProjEXT", 1, &E_GL_EXT_shadow_samplers); } + + // E_GL_EXT_texture_array + if (spvVersion.spv == 0) { + symbolTable.setFunctionExtensions("texture2DArray", 1, &E_GL_EXT_texture_array); + } + if (profile != EEsProfile && spvVersion.spv == 0) { + symbolTable.setFunctionExtensions("texture1DArray", 1, &E_GL_EXT_texture_array); + symbolTable.setFunctionExtensions("shadow1DArray", 1, &E_GL_EXT_texture_array); + symbolTable.setFunctionExtensions("shadow2DArray", 1, &E_GL_EXT_texture_array); + + symbolTable.setFunctionExtensions("texture1DArrayLod", 1, &E_GL_EXT_texture_array); + symbolTable.setFunctionExtensions("texture2DArrayLod", 1, &E_GL_EXT_texture_array); + symbolTable.setFunctionExtensions("shadow1DArrayLod", 1, &E_GL_EXT_texture_array); + } // Fall through case EShLangTessControl: @@ -7879,7 +8041,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion case EShLangTessEvaluation: case EShLangGeometry: -#endif // !GLSLANG_WEB SpecialQualifier("gl_Position", EvqPosition, EbvPosition, symbolTable); SpecialQualifier("gl_PointSize", EvqPointSize, EbvPointSize, symbolTable); @@ -7889,7 +8050,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_out", "gl_Position", EbvPosition, symbolTable); BuiltInVariable("gl_out", "gl_PointSize", EbvPointSize, symbolTable); -#ifndef GLSLANG_WEB SpecialQualifier("gl_ClipVertex", EvqClipVertex, EbvClipVertex, symbolTable); BuiltInVariable("gl_in", "gl_ClipDistance", EbvClipDistance, symbolTable); @@ -7996,7 +8156,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); } - if (profile != EEsProfile) { + if (profile != EEsProfile) { BuiltInVariable("gl_SubGroupInvocationARB", EbvSubGroupInvocation, symbolTable); BuiltInVariable("gl_SubGroupEqMaskARB", EbvSubGroupEqMask, symbolTable); BuiltInVariable("gl_SubGroupGeMaskARB", EbvSubGroupGeMask, symbolTable); @@ -8004,9 +8164,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); - if (spvVersion.vulkan > 0) + if (spvVersion.vulkan > 0) { // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + if (language == EShLangFragment) + ModifyFlatDecoration("gl_SubGroupSizeARB", true, symbolTable); + } else BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); } @@ -8039,6 +8202,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); + + // GL_ARM_shader_core_builtins + symbolTable.setVariableExtensions("gl_CoreCountARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_CoreIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_CoreMaxIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_WarpIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_WarpMaxIDARM", 1, &E_GL_ARM_shader_core_builtins); + + BuiltInVariable("gl_CoreCountARM", EbvCoreCountARM, symbolTable); + BuiltInVariable("gl_CoreIDARM", EbvCoreIDARM, symbolTable); + BuiltInVariable("gl_CoreMaxIDARM", EbvCoreMaxIDARM, symbolTable); + BuiltInVariable("gl_WarpIDARM", EbvWarpIDARM, symbolTable); + BuiltInVariable("gl_WarpMaxIDARM", EbvWarpMaxIDARM, symbolTable); } if (language == EShLangGeometry || language == EShLangVertex) { @@ -8053,8 +8229,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); } } - -#endif // !GLSLANG_WEB break; case EShLangFragment: @@ -8071,8 +8245,8 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } } SpecialQualifier("gl_FragDepth", EvqFragDepth, EbvFragDepth, symbolTable); -#ifndef GLSLANG_WEB SpecialQualifier("gl_FragDepthEXT", EvqFragDepth, EbvFragDepth, symbolTable); + SpecialQualifier("gl_FragStencilRefARB", EvqFragStencil, EbvFragStencilRef, symbolTable); SpecialQualifier("gl_HelperInvocation", EvqVaryingIn, EbvHelperInvocation, symbolTable); BuiltInVariable("gl_ClipDistance", EbvClipDistance, symbolTable); @@ -8112,8 +8286,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("rayQueryGetIntersectionWorldToObjectEXT", 1, &E_GL_EXT_ray_query); symbolTable.setFunctionExtensions("rayQueryGetWorldRayOriginEXT", 1, &E_GL_EXT_ray_query); symbolTable.setFunctionExtensions("rayQueryGetWorldRayDirectionEXT", 1, &E_GL_EXT_ray_query); + symbolTable.setFunctionExtensions("rayQueryGetIntersectionTriangleVertexPositionsEXT", 1, &E_GL_EXT_ray_tracing_position_fetch); symbolTable.setVariableExtensions("gl_RayFlagsSkipAABBEXT", 1, &E_GL_EXT_ray_flags_primitive_culling); symbolTable.setVariableExtensions("gl_RayFlagsSkipTrianglesEXT", 1, &E_GL_EXT_ray_flags_primitive_culling); + symbolTable.setVariableExtensions("gl_RayFlagsForceOpacityMicromap2StateEXT", 1, &E_GL_EXT_opacity_micromap); } if ((profile != EEsProfile && version >= 130) || @@ -8216,27 +8392,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("shadow2DRectProjGradARB", 1, &E_GL_ARB_shader_texture_lod); } - // E_GL_EXT_texture_array - if (spvVersion.spv == 0) { - symbolTable.setFunctionExtensions("texture2DArray", 1, &E_GL_EXT_texture_array); - } - if (profile != EEsProfile && spvVersion.spv == 0) { - int nLodExtensions = 2; - const char *lodExtensions[] = {E_GL_EXT_texture_array, E_GL_ARB_shader_texture_lod}; - - if (version >= 130) - nLodExtensions = 1; - - symbolTable.setFunctionExtensions("texture1DArray", 1, &E_GL_EXT_texture_array); - symbolTable.setFunctionExtensions("shadow1DArray", 1, &E_GL_EXT_texture_array); - symbolTable.setFunctionExtensions("shadow2DArray", 1, &E_GL_EXT_texture_array); - - symbolTable.setFunctionExtensions("texture1DArrayLod", nLodExtensions, lodExtensions); - symbolTable.setFunctionExtensions("texture2DArrayLod", nLodExtensions, lodExtensions); - symbolTable.setFunctionExtensions("shadow1DArrayLod", nLodExtensions, lodExtensions); - symbolTable.setFunctionExtensions("shadow2DArrayLod", nLodExtensions, lodExtensions); - } - // E_GL_ARB_shader_image_load_store if (profile != EEsProfile && version < 420) symbolTable.setFunctionExtensions("memoryBarrier", 1, &E_GL_ARB_shader_image_load_store); @@ -8354,6 +8509,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_BaryCoordNoPerspNV", 1, &E_GL_NV_fragment_shader_barycentric); BuiltInVariable("gl_BaryCoordNV", EbvBaryCoordNV, symbolTable); BuiltInVariable("gl_BaryCoordNoPerspNV", EbvBaryCoordNoPerspNV, symbolTable); + symbolTable.setVariableExtensions("gl_BaryCoordEXT", 1, &E_GL_EXT_fragment_shader_barycentric); + symbolTable.setVariableExtensions("gl_BaryCoordNoPerspEXT", 1, &E_GL_EXT_fragment_shader_barycentric); + BuiltInVariable("gl_BaryCoordEXT", EbvBaryCoordEXT, symbolTable); + BuiltInVariable("gl_BaryCoordNoPerspEXT", EbvBaryCoordNoPerspEXT, symbolTable); } if ((profile != EEsProfile && version >= 450) || @@ -8389,10 +8548,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } if (profile != EEsProfile && version < 330 ) { - symbolTable.setFunctionExtensions("floatBitsToInt", 1, &E_GL_ARB_shader_bit_encoding); - symbolTable.setFunctionExtensions("floatBitsToUint", 1, &E_GL_ARB_shader_bit_encoding); - symbolTable.setFunctionExtensions("intBitsToFloat", 1, &E_GL_ARB_shader_bit_encoding); - symbolTable.setFunctionExtensions("uintBitsToFloat", 1, &E_GL_ARB_shader_bit_encoding); + const char* bitsConvertExt[2] = {E_GL_ARB_shader_bit_encoding, E_GL_ARB_gpu_shader5}; + symbolTable.setFunctionExtensions("floatBitsToInt", 2, bitsConvertExt); + symbolTable.setFunctionExtensions("floatBitsToUint", 2, bitsConvertExt); + symbolTable.setFunctionExtensions("intBitsToFloat", 2, bitsConvertExt); + symbolTable.setFunctionExtensions("uintBitsToFloat", 2, bitsConvertExt); } if (profile != EEsProfile && version < 430 ) { @@ -8453,9 +8613,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); - if (spvVersion.vulkan > 0) + if (spvVersion.vulkan > 0) { // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + if (language == EShLangFragment) + ModifyFlatDecoration("gl_SubGroupSizeARB", true, symbolTable); + } else BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); } @@ -8565,6 +8728,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); + + // GL_ARM_shader_core_builtins + symbolTable.setVariableExtensions("gl_CoreCountARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_CoreIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_CoreMaxIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_WarpIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_WarpMaxIDARM", 1, &E_GL_ARM_shader_core_builtins); + + BuiltInVariable("gl_CoreCountARM", EbvCoreCountARM, symbolTable); + BuiltInVariable("gl_CoreIDARM", EbvCoreIDARM, symbolTable); + BuiltInVariable("gl_CoreMaxIDARM", EbvCoreMaxIDARM, symbolTable); + BuiltInVariable("gl_WarpIDARM", EbvWarpIDARM, symbolTable); + BuiltInVariable("gl_WarpMaxIDARM", EbvWarpMaxIDARM, symbolTable); } if (profile == EEsProfile) { @@ -8605,7 +8781,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_ShadingRateFlag2HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); } -#endif // !GLSLANG_WEB + + // GL_EXT_shader_tile_image + symbolTable.setFunctionExtensions("stencilAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image); + symbolTable.setFunctionExtensions("depthAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image); + symbolTable.setFunctionExtensions("colorAttachmentReadEXT", 1, &E_GL_EXT_shader_tile_image); + + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + symbolTable.setFunctionExtensions("textureWeightedQCOM", 1, &E_GL_QCOM_image_processing); + symbolTable.setFunctionExtensions("textureBoxFilterQCOM", 1, &E_GL_QCOM_image_processing); + symbolTable.setFunctionExtensions("textureBlockMatchSADQCOM", 1, &E_GL_QCOM_image_processing); + symbolTable.setFunctionExtensions("textureBlockMatchSSDQCOM", 1, &E_GL_QCOM_image_processing); + } break; case EShLangCompute: @@ -8618,7 +8806,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); -#ifndef GLSLANG_WEB if ((profile != EEsProfile && version >= 140) || (profile == EEsProfile && version >= 310)) { symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); @@ -8670,9 +8857,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); - if (spvVersion.vulkan > 0) + if (spvVersion.vulkan > 0) { // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + if (language == EShLangFragment) + ModifyFlatDecoration("gl_SubGroupSizeARB", true, symbolTable); + } else BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); } @@ -8705,6 +8895,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); + + // GL_ARM_shader_core_builtins + symbolTable.setVariableExtensions("gl_CoreCountARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_CoreIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_CoreMaxIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_WarpIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_WarpMaxIDARM", 1, &E_GL_ARM_shader_core_builtins); + + BuiltInVariable("gl_CoreCountARM", EbvCoreCountARM, symbolTable); + BuiltInVariable("gl_CoreIDARM", EbvCoreIDARM, symbolTable); + BuiltInVariable("gl_CoreMaxIDARM", EbvCoreMaxIDARM, symbolTable); + BuiltInVariable("gl_WarpIDARM", EbvWarpIDARM, symbolTable); + BuiltInVariable("gl_WarpMaxIDARM", EbvWarpMaxIDARM, symbolTable); } // GL_KHR_shader_subgroup @@ -8726,6 +8929,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("coopMatMulAddNV", 2, coopExt); } + { + symbolTable.setFunctionExtensions("coopMatLoad", 1, &E_GL_KHR_cooperative_matrix); + symbolTable.setFunctionExtensions("coopMatStore", 1, &E_GL_KHR_cooperative_matrix); + symbolTable.setFunctionExtensions("coopMatMulAdd", 1, &E_GL_KHR_cooperative_matrix); + } + if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { symbolTable.setFunctionExtensions("dFdx", 1, &E_GL_NV_compute_shader_derivatives); symbolTable.setFunctionExtensions("dFdy", 1, &E_GL_NV_compute_shader_derivatives); @@ -8745,10 +8954,13 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_ShadingRateFlag2HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); } -#endif // !GLSLANG_WEB + + if ((profile != EEsProfile && version >= 460)) { + symbolTable.setFunctionExtensions("fetchMicroTriangleVertexPositionNV", 1, &E_GL_NV_displacement_micromap); + symbolTable.setFunctionExtensions("fetchMicroTriangleVertexBarycentricNV", 1, &E_GL_NV_displacement_micromap); + } break; -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) case EShLangRayGen: case EShLangIntersect: case EShLangAnyHit: @@ -8778,6 +8990,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_RayTminEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_RayTmaxNV", 1, &E_GL_NV_ray_tracing); symbolTable.setVariableExtensions("gl_RayTmaxEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setVariableExtensions("gl_CullMaskEXT", 1, &E_GL_EXT_ray_cull_mask); symbolTable.setVariableExtensions("gl_HitTNV", 1, &E_GL_NV_ray_tracing); symbolTable.setVariableExtensions("gl_HitTEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_HitKindNV", 1, &E_GL_NV_ray_tracing); @@ -8791,6 +9004,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_IncomingRayFlagsNV", 1, &E_GL_NV_ray_tracing); symbolTable.setVariableExtensions("gl_IncomingRayFlagsEXT", 1, &E_GL_EXT_ray_tracing); symbolTable.setVariableExtensions("gl_CurrentRayTimeNV", 1, &E_GL_NV_ray_tracing_motion_blur); + symbolTable.setVariableExtensions("gl_HitTriangleVertexPositionsEXT", 1, &E_GL_EXT_ray_tracing_position_fetch); + symbolTable.setVariableExtensions("gl_HitMicroTriangleVertexPositionsNV", 1, &E_GL_NV_displacement_micromap); + symbolTable.setVariableExtensions("gl_HitMicroTriangleVertexBarycentricsNV", 1, &E_GL_NV_displacement_micromap); symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); @@ -8805,6 +9021,40 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setFunctionExtensions("executeCallableNV", 1, &E_GL_NV_ray_tracing); symbolTable.setFunctionExtensions("executeCallableEXT", 1, &E_GL_EXT_ray_tracing); + symbolTable.setFunctionExtensions("hitObjectTraceRayNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectTraceRayMotionNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectRecordHitNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectRecordHitMotionNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectRecordHitWithIndexNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectRecordHitWithIndexMotionNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectRecordMissNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectRecordMissMotionNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectRecordEmptyNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectExecuteShaderNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectIsEmptyNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectIsMissNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectIsHitNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetRayTMinNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetRayTMaxNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetObjectRayOriginNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetObjectRayDirectionNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetWorldRayOriginNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetWorldRayDirectionNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetWorldToObjectNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetbjectToWorldNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetInstanceCustomIndexNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetInstanceIdNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetGeometryIndexNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetPrimitiveIndexNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetHitKindNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetAttributesNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetCurrentTimeNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetShaderBindingTableRecordIndexNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("hitObjectGetShaderRecordBufferHandleNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("reorderThreadNV", 1, &E_GL_NV_shader_invocation_reorder); + symbolTable.setFunctionExtensions("fetchMicroTriangleVertexPositionNV", 1, &E_GL_NV_displacement_micromap); + symbolTable.setFunctionExtensions("fetchMicroTriangleVertexBarycentricNV", 1, &E_GL_NV_displacement_micromap); + BuiltInVariable("gl_LaunchIDNV", EbvLaunchId, symbolTable); BuiltInVariable("gl_LaunchIDEXT", EbvLaunchId, symbolTable); @@ -8827,6 +9077,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_RayTminEXT", EbvRayTmin, symbolTable); BuiltInVariable("gl_RayTmaxNV", EbvRayTmax, symbolTable); BuiltInVariable("gl_RayTmaxEXT", EbvRayTmax, symbolTable); + BuiltInVariable("gl_CullMaskEXT", EbvCullMask, symbolTable); BuiltInVariable("gl_HitTNV", EbvHitT, symbolTable); BuiltInVariable("gl_HitTEXT", EbvHitT, symbolTable); BuiltInVariable("gl_HitKindNV", EbvHitKind, symbolTable); @@ -8841,6 +9092,11 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_IncomingRayFlagsEXT", EbvIncomingRayFlags, symbolTable); BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); BuiltInVariable("gl_CurrentRayTimeNV", EbvCurrentRayTimeNV, symbolTable); + BuiltInVariable("gl_HitTriangleVertexPositionsEXT", EbvPositionFetch, symbolTable); + BuiltInVariable("gl_HitMicroTriangleVertexPositionsNV", EbvMicroTrianglePositionNV, symbolTable); + BuiltInVariable("gl_HitMicroTriangleVertexBarycentricsNV", EbvMicroTriangleBaryNV, symbolTable); + BuiltInVariable("gl_HitKindFrontFacingMicroTriangleNV", EbvHitKindFrontFacingMicroTriangleNV, symbolTable); + BuiltInVariable("gl_HitKindBackFacingMicroTriangleNV", EbvHitKindBackFacingMicroTriangleNV, symbolTable); // GL_ARB_shader_ballot symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot); @@ -8858,9 +9114,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); - if (spvVersion.vulkan > 0) + if (spvVersion.vulkan > 0) { // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + if (language == EShLangFragment) + ModifyFlatDecoration("gl_SubGroupSizeARB", true, symbolTable); + } else BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); @@ -8894,6 +9153,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); + + // GL_ARM_shader_core_builtins + symbolTable.setVariableExtensions("gl_CoreCountARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_CoreIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_CoreMaxIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_WarpIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_WarpMaxIDARM", 1, &E_GL_ARM_shader_core_builtins); + + BuiltInVariable("gl_CoreCountARM", EbvCoreCountARM, symbolTable); + BuiltInVariable("gl_CoreIDARM", EbvCoreIDARM, symbolTable); + BuiltInVariable("gl_CoreMaxIDARM", EbvCoreMaxIDARM, symbolTable); + BuiltInVariable("gl_WarpIDARM", EbvWarpIDARM, symbolTable); + BuiltInVariable("gl_WarpMaxIDARM", EbvWarpMaxIDARM, symbolTable); } if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 450)) { @@ -8904,7 +9176,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion } break; - case EShLangMeshNV: + case EShLangMesh: if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { // per-vertex builtins symbolTable.setVariableExtensions("gl_MeshVerticesNV", "gl_Position", 1, &E_GL_NV_mesh_shader); @@ -8948,12 +9220,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_PrimitiveIndicesNV", 1, &E_GL_NV_mesh_shader); symbolTable.setVariableExtensions("gl_MeshViewCountNV", 1, &E_GL_NV_mesh_shader); symbolTable.setVariableExtensions("gl_MeshViewIndicesNV", 1, &E_GL_NV_mesh_shader); - symbolTable.setVariableExtensions("gl_WorkGroupSize", 1, &E_GL_NV_mesh_shader); - symbolTable.setVariableExtensions("gl_WorkGroupID", 1, &E_GL_NV_mesh_shader); - symbolTable.setVariableExtensions("gl_LocalInvocationID", 1, &E_GL_NV_mesh_shader); - symbolTable.setVariableExtensions("gl_GlobalInvocationID", 1, &E_GL_NV_mesh_shader); - symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_NV_mesh_shader); - + if (profile != EEsProfile) { + symbolTable.setVariableExtensions("gl_WorkGroupSize", Num_AEP_mesh_shader, AEP_mesh_shader); + symbolTable.setVariableExtensions("gl_WorkGroupID", Num_AEP_mesh_shader, AEP_mesh_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationID", Num_AEP_mesh_shader, AEP_mesh_shader); + symbolTable.setVariableExtensions("gl_GlobalInvocationID", Num_AEP_mesh_shader, AEP_mesh_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationIndex", Num_AEP_mesh_shader, AEP_mesh_shader); + } else { + symbolTable.setVariableExtensions("gl_WorkGroupSize", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_WorkGroupID", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationID", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_GlobalInvocationID", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_NV_mesh_shader); + } BuiltInVariable("gl_PrimitiveCountNV", EbvPrimitiveCountNV, symbolTable); BuiltInVariable("gl_PrimitiveIndicesNV", EbvPrimitiveIndicesNV, symbolTable); BuiltInVariable("gl_MeshViewCountNV", EbvMeshViewCountNV, symbolTable); @@ -8971,12 +9250,58 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_MaxMeshViewCountNV", 1, &E_GL_NV_mesh_shader); // builtin functions - symbolTable.setFunctionExtensions("barrier", 1, &E_GL_NV_mesh_shader); - symbolTable.setFunctionExtensions("memoryBarrierShared", 1, &E_GL_NV_mesh_shader); - symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_NV_mesh_shader); + if (profile != EEsProfile) { + symbolTable.setFunctionExtensions("barrier", Num_AEP_mesh_shader, AEP_mesh_shader); + symbolTable.setFunctionExtensions("memoryBarrierShared", Num_AEP_mesh_shader, AEP_mesh_shader); + symbolTable.setFunctionExtensions("groupMemoryBarrier", Num_AEP_mesh_shader, AEP_mesh_shader); + } else { + symbolTable.setFunctionExtensions("barrier", 1, &E_GL_NV_mesh_shader); + symbolTable.setFunctionExtensions("memoryBarrierShared", 1, &E_GL_NV_mesh_shader); + symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_NV_mesh_shader); + } + symbolTable.setFunctionExtensions("writePackedPrimitiveIndices4x8NV", 1, &E_GL_NV_mesh_shader); } if (profile != EEsProfile && version >= 450) { + // GL_EXT_Mesh_shader + symbolTable.setVariableExtensions("gl_PrimitivePointIndicesEXT", 1, &E_GL_EXT_mesh_shader); + symbolTable.setVariableExtensions("gl_PrimitiveLineIndicesEXT", 1, &E_GL_EXT_mesh_shader); + symbolTable.setVariableExtensions("gl_PrimitiveTriangleIndicesEXT", 1, &E_GL_EXT_mesh_shader); + symbolTable.setVariableExtensions("gl_NumWorkGroups", 1, &E_GL_EXT_mesh_shader); + + BuiltInVariable("gl_PrimitivePointIndicesEXT", EbvPrimitivePointIndicesEXT, symbolTable); + BuiltInVariable("gl_PrimitiveLineIndicesEXT", EbvPrimitiveLineIndicesEXT, symbolTable); + BuiltInVariable("gl_PrimitiveTriangleIndicesEXT", EbvPrimitiveTriangleIndicesEXT, symbolTable); + BuiltInVariable("gl_NumWorkGroups", EbvNumWorkGroups, symbolTable); + + symbolTable.setVariableExtensions("gl_MeshVerticesEXT", "gl_Position", 1, &E_GL_EXT_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshVerticesEXT", "gl_PointSize", 1, &E_GL_EXT_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshVerticesEXT", "gl_ClipDistance", 1, &E_GL_EXT_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshVerticesEXT", "gl_CullDistance", 1, &E_GL_EXT_mesh_shader); + + BuiltInVariable("gl_MeshVerticesEXT", "gl_Position", EbvPosition, symbolTable); + BuiltInVariable("gl_MeshVerticesEXT", "gl_PointSize", EbvPointSize, symbolTable); + BuiltInVariable("gl_MeshVerticesEXT", "gl_ClipDistance", EbvClipDistance, symbolTable); + BuiltInVariable("gl_MeshVerticesEXT", "gl_CullDistance", EbvCullDistance, symbolTable); + + symbolTable.setVariableExtensions("gl_MeshPrimitivesEXT", "gl_PrimitiveID", 1, &E_GL_EXT_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshPrimitivesEXT", "gl_Layer", 1, &E_GL_EXT_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshPrimitivesEXT", "gl_ViewportIndex", 1, &E_GL_EXT_mesh_shader); + symbolTable.setVariableExtensions("gl_MeshPrimitivesEXT", "gl_CullPrimitiveEXT", 1, &E_GL_EXT_mesh_shader); + + // note: technically this member requires both GL_EXT_mesh_shader and GL_EXT_fragment_shading_rate + // since setVariableExtensions only needs *one of* the extensions to validate, it's more useful to specify EXT_fragment_shading_rate + // GL_EXT_mesh_shader will be required in practice by use of other fields of gl_MeshPrimitivesEXT + symbolTable.setVariableExtensions("gl_MeshPrimitivesEXT", "gl_PrimitiveShadingRateEXT", 1, &E_GL_EXT_fragment_shading_rate); + + BuiltInVariable("gl_MeshPrimitivesEXT", "gl_PrimitiveID", EbvPrimitiveId, symbolTable); + BuiltInVariable("gl_MeshPrimitivesEXT", "gl_Layer", EbvLayer, symbolTable); + BuiltInVariable("gl_MeshPrimitivesEXT", "gl_ViewportIndex", EbvViewportIndex, symbolTable); + BuiltInVariable("gl_MeshPrimitivesEXT", "gl_CullPrimitiveEXT", EbvCullPrimitiveEXT, symbolTable); + BuiltInVariable("gl_MeshPrimitivesEXT", "gl_PrimitiveShadingRateEXT", EbvPrimitiveShadingRateKHR, symbolTable); + + symbolTable.setFunctionExtensions("SetMeshOutputsEXT", 1, &E_GL_EXT_mesh_shader); + // GL_EXT_device_group symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); @@ -8987,6 +9312,9 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion if (version >= 460) { BuiltInVariable("gl_DrawID", EbvDrawId, symbolTable); } + // GL_EXT_multiview + BuiltInVariable("gl_ViewIndex", EbvViewIndex, symbolTable); + symbolTable.setVariableExtensions("gl_ViewIndex", 1, &E_GL_EXT_multiview); // GL_ARB_shader_ballot symbolTable.setVariableExtensions("gl_SubGroupSizeARB", 1, &E_GL_ARB_shader_ballot); @@ -9004,9 +9332,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); - if (spvVersion.vulkan > 0) + if (spvVersion.vulkan > 0) { // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + if (language == EShLangFragment) + ModifyFlatDecoration("gl_SubGroupSizeARB", true, symbolTable); + } else BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); } @@ -9045,6 +9376,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); + + // GL_ARM_shader_core_builtins + symbolTable.setVariableExtensions("gl_CoreCountARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_CoreIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_CoreMaxIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_WarpIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_WarpMaxIDARM", 1, &E_GL_ARM_shader_core_builtins); + + BuiltInVariable("gl_CoreCountARM", EbvCoreCountARM, symbolTable); + BuiltInVariable("gl_CoreIDARM", EbvCoreIDARM, symbolTable); + BuiltInVariable("gl_CoreMaxIDARM", EbvCoreMaxIDARM, symbolTable); + BuiltInVariable("gl_WarpIDARM", EbvWarpIDARM, symbolTable); + BuiltInVariable("gl_WarpMaxIDARM", EbvWarpMaxIDARM, symbolTable); } if ((profile == EEsProfile && version >= 310) || @@ -9054,18 +9398,33 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_ShadingRateFlag2HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); } + + // Builtins for GL_NV_displacment_micromap + if ((profile != EEsProfile && version >= 460)) { + symbolTable.setFunctionExtensions("fetchMicroTriangleVertexPositionNV", 1, &E_GL_NV_displacement_micromap); + symbolTable.setFunctionExtensions("fetchMicroTriangleVertexBarycentricNV", 1, &E_GL_NV_displacement_micromap); + } + break; - case EShLangTaskNV: + case EShLangTask: if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { symbolTable.setVariableExtensions("gl_TaskCountNV", 1, &E_GL_NV_mesh_shader); - symbolTable.setVariableExtensions("gl_WorkGroupSize", 1, &E_GL_NV_mesh_shader); - symbolTable.setVariableExtensions("gl_WorkGroupID", 1, &E_GL_NV_mesh_shader); - symbolTable.setVariableExtensions("gl_LocalInvocationID", 1, &E_GL_NV_mesh_shader); - symbolTable.setVariableExtensions("gl_GlobalInvocationID", 1, &E_GL_NV_mesh_shader); - symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_NV_mesh_shader); symbolTable.setVariableExtensions("gl_MeshViewCountNV", 1, &E_GL_NV_mesh_shader); symbolTable.setVariableExtensions("gl_MeshViewIndicesNV", 1, &E_GL_NV_mesh_shader); + if (profile != EEsProfile) { + symbolTable.setVariableExtensions("gl_WorkGroupSize", Num_AEP_mesh_shader, AEP_mesh_shader); + symbolTable.setVariableExtensions("gl_WorkGroupID", Num_AEP_mesh_shader, AEP_mesh_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationID", Num_AEP_mesh_shader, AEP_mesh_shader); + symbolTable.setVariableExtensions("gl_GlobalInvocationID", Num_AEP_mesh_shader, AEP_mesh_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationIndex", Num_AEP_mesh_shader, AEP_mesh_shader); + } else { + symbolTable.setVariableExtensions("gl_WorkGroupSize", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_WorkGroupID", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationID", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_GlobalInvocationID", 1, &E_GL_NV_mesh_shader); + symbolTable.setVariableExtensions("gl_LocalInvocationIndex", 1, &E_GL_NV_mesh_shader); + } BuiltInVariable("gl_TaskCountNV", EbvTaskCountNV, symbolTable); BuiltInVariable("gl_WorkGroupSize", EbvWorkGroupSize, symbolTable); @@ -9079,12 +9438,23 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_MaxTaskWorkGroupSizeNV", 1, &E_GL_NV_mesh_shader); symbolTable.setVariableExtensions("gl_MaxMeshViewCountNV", 1, &E_GL_NV_mesh_shader); - symbolTable.setFunctionExtensions("barrier", 1, &E_GL_NV_mesh_shader); - symbolTable.setFunctionExtensions("memoryBarrierShared", 1, &E_GL_NV_mesh_shader); - symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_NV_mesh_shader); + if (profile != EEsProfile) { + symbolTable.setFunctionExtensions("barrier", Num_AEP_mesh_shader, AEP_mesh_shader); + symbolTable.setFunctionExtensions("memoryBarrierShared", Num_AEP_mesh_shader, AEP_mesh_shader); + symbolTable.setFunctionExtensions("groupMemoryBarrier", Num_AEP_mesh_shader, AEP_mesh_shader); + } else { + symbolTable.setFunctionExtensions("barrier", 1, &E_GL_NV_mesh_shader); + symbolTable.setFunctionExtensions("memoryBarrierShared", 1, &E_GL_NV_mesh_shader); + symbolTable.setFunctionExtensions("groupMemoryBarrier", 1, &E_GL_NV_mesh_shader); + } } if (profile != EEsProfile && version >= 450) { + // GL_EXT_mesh_shader + symbolTable.setFunctionExtensions("EmitMeshTasksEXT", 1, &E_GL_EXT_mesh_shader); + symbolTable.setVariableExtensions("gl_NumWorkGroups", 1, &E_GL_EXT_mesh_shader); + BuiltInVariable("gl_NumWorkGroups", EbvNumWorkGroups, symbolTable); + // GL_EXT_device_group symbolTable.setVariableExtensions("gl_DeviceIndex", 1, &E_GL_EXT_device_group); BuiltInVariable("gl_DeviceIndex", EbvDeviceIndex, symbolTable); @@ -9112,9 +9482,12 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SubGroupLeMaskARB", EbvSubGroupLeMask, symbolTable); BuiltInVariable("gl_SubGroupLtMaskARB", EbvSubGroupLtMask, symbolTable); - if (spvVersion.vulkan > 0) + if (spvVersion.vulkan > 0) { // Treat "gl_SubGroupSizeARB" as shader input instead of uniform for Vulkan SpecialQualifier("gl_SubGroupSizeARB", EvqVaryingIn, EbvSubGroupSize, symbolTable); + if (language == EShLangFragment) + ModifyFlatDecoration("gl_SubGroupSizeARB", true, symbolTable); + } else BuiltInVariable("gl_SubGroupSizeARB", EbvSubGroupSize, symbolTable); } @@ -9153,6 +9526,19 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion BuiltInVariable("gl_SMCountNV", EbvSMCount, symbolTable); BuiltInVariable("gl_WarpIDNV", EbvWarpID, symbolTable); BuiltInVariable("gl_SMIDNV", EbvSMID, symbolTable); + + // GL_ARM_shader_core_builtins + symbolTable.setVariableExtensions("gl_CoreCountARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_CoreIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_CoreMaxIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_WarpIDARM", 1, &E_GL_ARM_shader_core_builtins); + symbolTable.setVariableExtensions("gl_WarpMaxIDARM", 1, &E_GL_ARM_shader_core_builtins); + + BuiltInVariable("gl_CoreCountARM", EbvCoreCountARM, symbolTable); + BuiltInVariable("gl_CoreIDARM", EbvCoreIDARM, symbolTable); + BuiltInVariable("gl_CoreMaxIDARM", EbvCoreMaxIDARM, symbolTable); + BuiltInVariable("gl_WarpIDARM", EbvWarpIDARM, symbolTable); + BuiltInVariable("gl_WarpMaxIDARM", EbvWarpMaxIDARM, symbolTable); } if ((profile == EEsProfile && version >= 310) || (profile != EEsProfile && version >= 450)) { @@ -9162,7 +9548,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.setVariableExtensions("gl_ShadingRateFlag4HorizontalPixelsEXT", 1, &E_GL_EXT_fragment_shading_rate); } break; -#endif default: assert(false && "Language not supported"); @@ -9178,7 +9563,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion relateTabledBuiltins(version, profile, spvVersion, language, symbolTable); -#ifndef GLSLANG_WEB symbolTable.relateToOperator("doubleBitsToInt64", EOpDoubleBitsToInt64); symbolTable.relateToOperator("doubleBitsToUint64", EOpDoubleBitsToUint64); symbolTable.relateToOperator("int64BitsToDouble", EOpInt64BitsToDouble); @@ -9400,15 +9784,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("texture2DProjLod", EOpTextureProjLod); symbolTable.relateToOperator("texture2DProjLodEXT", EOpTextureProjLod); - symbolTable.relateToOperator("texture1DArray", EOpTexture); - symbolTable.relateToOperator("texture2DArray", EOpTexture); - symbolTable.relateToOperator("shadow1DArray", EOpTexture); - symbolTable.relateToOperator("shadow2DArray", EOpTexture); - symbolTable.relateToOperator("texture1DArrayLod", EOpTextureLod); - symbolTable.relateToOperator("texture2DArrayLod", EOpTextureLod); - symbolTable.relateToOperator("shadow1DArrayLod", EOpTextureLod); - symbolTable.relateToOperator("shadow2DArrayLod", EOpTextureLod); - symbolTable.relateToOperator("texture3D", EOpTexture); symbolTable.relateToOperator("texture3DGradARB", EOpTextureGrad); symbolTable.relateToOperator("texture3DProj", EOpTextureProj); @@ -9604,6 +9979,27 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("shadow2DEXT", EOpTexture); symbolTable.relateToOperator("shadow2DProjEXT", EOpTextureProj); } + + if ((profile == EEsProfile && version >= 310) || + (profile != EEsProfile && version >= 140)) { + symbolTable.relateToOperator("textureWeightedQCOM", EOpImageSampleWeightedQCOM); + symbolTable.relateToOperator("textureBoxFilterQCOM", EOpImageBoxFilterQCOM); + symbolTable.relateToOperator("textureBlockMatchSADQCOM", EOpImageBlockMatchSADQCOM); + symbolTable.relateToOperator("textureBlockMatchSSDQCOM", EOpImageBlockMatchSSDQCOM); + } + + if (spvVersion.spv == 0) { + symbolTable.relateToOperator("texture2DArray", EOpTexture); + } + if (profile != EEsProfile && spvVersion.spv == 0) { + symbolTable.relateToOperator("texture1DArray", EOpTexture); + symbolTable.relateToOperator("shadow1DArray", EOpTexture); + symbolTable.relateToOperator("shadow2DArray", EOpTexture); + + symbolTable.relateToOperator("texture1DArrayLod", EOpTextureLod); + symbolTable.relateToOperator("texture2DArrayLod", EOpTextureLod); + symbolTable.relateToOperator("shadow1DArrayLod", EOpTextureLod); + } } switch(language) { @@ -9655,6 +10051,7 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("rayQueryGetWorldRayOriginEXT", EOpRayQueryGetWorldRayOrigin); symbolTable.relateToOperator("rayQueryGetIntersectionObjectToWorldEXT", EOpRayQueryGetIntersectionObjectToWorld); symbolTable.relateToOperator("rayQueryGetIntersectionWorldToObjectEXT", EOpRayQueryGetIntersectionWorldToObject); + symbolTable.relateToOperator("rayQueryGetIntersectionTriangleVertexPositionsEXT", EOpRayQueryGetIntersectionTriangleVertexPositionsEXT); } symbolTable.relateToOperator("interpolateAtCentroid", EOpInterpolateAtCentroid); @@ -9667,6 +10064,10 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("beginInvocationInterlockARB", EOpBeginInvocationInterlock); symbolTable.relateToOperator("endInvocationInterlockARB", EOpEndInvocationInterlock); + symbolTable.relateToOperator("stencilAttachmentReadEXT", EOpStencilAttachmentReadEXT); + symbolTable.relateToOperator("depthAttachmentReadEXT", EOpDepthAttachmentReadEXT); + symbolTable.relateToOperator("colorAttachmentReadEXT", EOpColorAttachmentReadEXT); + break; case EShLangCompute: @@ -9683,12 +10084,25 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("dFdyCoarse", EOpDPdyCoarse); symbolTable.relateToOperator("fwidthCoarse",EOpFwidthCoarse); } - symbolTable.relateToOperator("coopMatLoadNV", EOpCooperativeMatrixLoad); - symbolTable.relateToOperator("coopMatStoreNV", EOpCooperativeMatrixStore); - symbolTable.relateToOperator("coopMatMulAddNV", EOpCooperativeMatrixMulAdd); + symbolTable.relateToOperator("coopMatLoadNV", EOpCooperativeMatrixLoadNV); + symbolTable.relateToOperator("coopMatStoreNV", EOpCooperativeMatrixStoreNV); + symbolTable.relateToOperator("coopMatMulAddNV", EOpCooperativeMatrixMulAddNV); + + symbolTable.relateToOperator("coopMatLoad", EOpCooperativeMatrixLoad); + symbolTable.relateToOperator("coopMatStore", EOpCooperativeMatrixStore); + symbolTable.relateToOperator("coopMatMulAdd", EOpCooperativeMatrixMulAdd); + + if (profile != EEsProfile && version >= 460) { + symbolTable.relateToOperator("fetchMicroTriangleVertexPositionNV", EOpFetchMicroTriangleVertexPositionNV); + symbolTable.relateToOperator("fetchMicroTriangleVertexBarycentricNV", EOpFetchMicroTriangleVertexBarycentricNV); + } break; case EShLangRayGen: + if (profile != EEsProfile && version >= 460) { + symbolTable.relateToOperator("fetchMicroTriangleVertexPositionNV", EOpFetchMicroTriangleVertexPositionNV); + symbolTable.relateToOperator("fetchMicroTriangleVertexBarycentricNV", EOpFetchMicroTriangleVertexBarycentricNV); + } // fallthrough case EShLangClosestHit: case EShLangMiss: if (profile != EEsProfile && version >= 460) { @@ -9697,13 +10111,45 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("traceRayEXT", EOpTraceKHR); symbolTable.relateToOperator("executeCallableNV", EOpExecuteCallableNV); symbolTable.relateToOperator("executeCallableEXT", EOpExecuteCallableKHR); + + symbolTable.relateToOperator("hitObjectTraceRayNV", EOpHitObjectTraceRayNV); + symbolTable.relateToOperator("hitObjectTraceRayMotionNV", EOpHitObjectTraceRayMotionNV); + symbolTable.relateToOperator("hitObjectRecordHitNV", EOpHitObjectRecordHitNV); + symbolTable.relateToOperator("hitObjectRecordHitMotionNV", EOpHitObjectRecordHitMotionNV); + symbolTable.relateToOperator("hitObjectRecordHitWithIndexNV", EOpHitObjectRecordHitWithIndexNV); + symbolTable.relateToOperator("hitObjectRecordHitWithIndexMotionNV", EOpHitObjectRecordHitWithIndexMotionNV); + symbolTable.relateToOperator("hitObjectRecordMissNV", EOpHitObjectRecordMissNV); + symbolTable.relateToOperator("hitObjectRecordMissMotionNV", EOpHitObjectRecordMissMotionNV); + symbolTable.relateToOperator("hitObjectRecordEmptyNV", EOpHitObjectRecordEmptyNV); + symbolTable.relateToOperator("hitObjectExecuteShaderNV", EOpHitObjectExecuteShaderNV); + symbolTable.relateToOperator("hitObjectIsEmptyNV", EOpHitObjectIsEmptyNV); + symbolTable.relateToOperator("hitObjectIsMissNV", EOpHitObjectIsMissNV); + symbolTable.relateToOperator("hitObjectIsHitNV", EOpHitObjectIsHitNV); + symbolTable.relateToOperator("hitObjectGetRayTMinNV", EOpHitObjectGetRayTMinNV); + symbolTable.relateToOperator("hitObjectGetRayTMaxNV", EOpHitObjectGetRayTMaxNV); + symbolTable.relateToOperator("hitObjectGetObjectRayOriginNV", EOpHitObjectGetObjectRayOriginNV); + symbolTable.relateToOperator("hitObjectGetObjectRayDirectionNV", EOpHitObjectGetObjectRayDirectionNV); + symbolTable.relateToOperator("hitObjectGetWorldRayOriginNV", EOpHitObjectGetWorldRayOriginNV); + symbolTable.relateToOperator("hitObjectGetWorldRayDirectionNV", EOpHitObjectGetWorldRayDirectionNV); + symbolTable.relateToOperator("hitObjectGetWorldToObjectNV", EOpHitObjectGetWorldToObjectNV); + symbolTable.relateToOperator("hitObjectGetObjectToWorldNV", EOpHitObjectGetObjectToWorldNV); + symbolTable.relateToOperator("hitObjectGetInstanceCustomIndexNV", EOpHitObjectGetInstanceCustomIndexNV); + symbolTable.relateToOperator("hitObjectGetInstanceIdNV", EOpHitObjectGetInstanceIdNV); + symbolTable.relateToOperator("hitObjectGetGeometryIndexNV", EOpHitObjectGetGeometryIndexNV); + symbolTable.relateToOperator("hitObjectGetPrimitiveIndexNV", EOpHitObjectGetPrimitiveIndexNV); + symbolTable.relateToOperator("hitObjectGetHitKindNV", EOpHitObjectGetHitKindNV); + symbolTable.relateToOperator("hitObjectGetAttributesNV", EOpHitObjectGetAttributesNV); + symbolTable.relateToOperator("hitObjectGetCurrentTimeNV", EOpHitObjectGetCurrentTimeNV); + symbolTable.relateToOperator("hitObjectGetShaderBindingTableRecordIndexNV", EOpHitObjectGetShaderBindingTableRecordIndexNV); + symbolTable.relateToOperator("hitObjectGetShaderRecordBufferHandleNV", EOpHitObjectGetShaderRecordBufferHandleNV); + symbolTable.relateToOperator("reorderThreadNV", EOpReorderThreadNV); } break; case EShLangIntersect: if (profile != EEsProfile && version >= 460) { symbolTable.relateToOperator("reportIntersectionNV", EOpReportIntersection); symbolTable.relateToOperator("reportIntersectionEXT", EOpReportIntersection); - } + } break; case EShLangAnyHit: if (profile != EEsProfile && version >= 460) { @@ -9717,23 +10163,38 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion symbolTable.relateToOperator("executeCallableEXT", EOpExecuteCallableKHR); } break; - case EShLangMeshNV: + case EShLangMesh: if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { symbolTable.relateToOperator("writePackedPrimitiveIndices4x8NV", EOpWritePackedPrimitiveIndices4x8NV); + symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared); + symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier); + symbolTable.relateToOperator("subgroupMemoryBarrierShared", EOpSubgroupMemoryBarrierShared); + } + + if (profile != EEsProfile && version >= 450) { + symbolTable.relateToOperator("SetMeshOutputsEXT", EOpSetMeshOutputsEXT); } - // fall through - case EShLangTaskNV: + + if (profile != EEsProfile && version >= 460) { + // Builtins for GL_NV_displacement_micromap. + symbolTable.relateToOperator("fetchMicroTriangleVertexPositionNV", EOpFetchMicroTriangleVertexPositionNV); + symbolTable.relateToOperator("fetchMicroTriangleVertexBarycentricNV", EOpFetchMicroTriangleVertexBarycentricNV); + } + break; + case EShLangTask: if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) { symbolTable.relateToOperator("memoryBarrierShared", EOpMemoryBarrierShared); symbolTable.relateToOperator("groupMemoryBarrier", EOpGroupMemoryBarrier); symbolTable.relateToOperator("subgroupMemoryBarrierShared", EOpSubgroupMemoryBarrierShared); } + if (profile != EEsProfile && version >= 450) { + symbolTable.relateToOperator("EmitMeshTasksEXT", EOpEmitMeshTasksEXT); + } break; default: assert(false && "Language not supported"); } -#endif // !GLSLANG_WEB } // @@ -9747,11 +10208,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion // void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) { -#ifndef GLSLANG_WEB -#if defined(GLSLANG_ANGLE) - profile = ECoreProfile; - version = 450; -#endif if (profile != EEsProfile && version >= 430 && version < 440) { symbolTable.setVariableExtensions("gl_MaxTransformFeedbackBuffers", 1, &E_GL_ARB_enhanced_layouts); symbolTable.setVariableExtensions("gl_MaxTransformFeedbackInterleavedComponents", 1, &E_GL_ARB_enhanced_layouts); @@ -9823,7 +10279,6 @@ void TBuiltIns::identifyBuiltIns(int version, EProfile profile, const SpvVersion default: break; } -#endif } } // end namespace glslang diff --git a/src/libraries/glslang/glslang/MachineIndependent/Initialize.h b/src/libraries/glslang/glslang/MachineIndependent/Initialize.h index ac8ec33e9..42c32ddbb 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/Initialize.h +++ b/src/libraries/glslang/glslang/MachineIndependent/Initialize.h @@ -107,6 +107,9 @@ class TBuiltIns : public TBuiltInParseables { int dimMap[EsdNumDims]; }; +// change this back to false if depending on textual spellings of texturing calls when consuming the AST +// Using PureOperatorBuiltins=false is deprecated. +constexpr bool PureOperatorBuiltins = true; } // end namespace glslang #endif // _INITIALIZE_INCLUDED_ diff --git a/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp b/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp index 6aea5b3d7..ae62f1962 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/Intermediate.cpp @@ -352,7 +352,7 @@ TIntermTyped* TIntermediate::addIndex(TOperator op, TIntermTyped* base, TIntermT TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, const TSourceLoc& loc) { - if (child == 0) + if (child == nullptr) return nullptr; if (child->getType().getBasicType() == EbtBlock) @@ -388,7 +388,6 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, case EOpConstructFloat: newType = EbtFloat; break; case EOpConstructInt: newType = EbtInt; break; case EOpConstructUint: newType = EbtUint; break; -#ifndef GLSLANG_WEB case EOpConstructInt8: newType = EbtInt8; break; case EOpConstructUint8: newType = EbtUint8; break; case EOpConstructInt16: newType = EbtInt16; break; @@ -397,7 +396,6 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermTyped* child, case EOpConstructUint64: newType = EbtUint64; break; case EOpConstructDouble: newType = EbtDouble; break; case EOpConstructFloat16: newType = EbtFloat16; break; -#endif default: break; // some compilers want this } @@ -569,7 +567,6 @@ bool TIntermediate::isConversionAllowed(TOperator op, TIntermTyped* node) const bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& newOp) const { switch (dst) { -#ifndef GLSLANG_WEB case EbtDouble: switch (src) { case EbtUint: newOp = EOpConvUintToDouble; break; @@ -587,13 +584,11 @@ bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& ne return false; } break; -#endif case EbtFloat: switch (src) { case EbtInt: newOp = EOpConvIntToFloat; break; case EbtUint: newOp = EOpConvUintToFloat; break; case EbtBool: newOp = EOpConvBoolToFloat; break; -#ifndef GLSLANG_WEB case EbtDouble: newOp = EOpConvDoubleToFloat; break; case EbtInt8: newOp = EOpConvInt8ToFloat; break; case EbtUint8: newOp = EOpConvUint8ToFloat; break; @@ -602,12 +597,10 @@ bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& ne case EbtFloat16: newOp = EOpConvFloat16ToFloat; break; case EbtInt64: newOp = EOpConvInt64ToFloat; break; case EbtUint64: newOp = EOpConvUint64ToFloat; break; -#endif default: return false; } break; -#ifndef GLSLANG_WEB case EbtFloat16: switch (src) { case EbtInt8: newOp = EOpConvInt8ToFloat16; break; @@ -625,13 +618,11 @@ bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& ne return false; } break; -#endif case EbtBool: switch (src) { case EbtInt: newOp = EOpConvIntToBool; break; case EbtUint: newOp = EOpConvUintToBool; break; case EbtFloat: newOp = EOpConvFloatToBool; break; -#ifndef GLSLANG_WEB case EbtDouble: newOp = EOpConvDoubleToBool; break; case EbtInt8: newOp = EOpConvInt8ToBool; break; case EbtUint8: newOp = EOpConvUint8ToBool; break; @@ -640,12 +631,10 @@ bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& ne case EbtFloat16: newOp = EOpConvFloat16ToBool; break; case EbtInt64: newOp = EOpConvInt64ToBool; break; case EbtUint64: newOp = EOpConvUint64ToBool; break; -#endif default: return false; } break; -#ifndef GLSLANG_WEB case EbtInt8: switch (src) { case EbtUint8: newOp = EOpConvUint8ToInt8; break; @@ -715,14 +704,12 @@ bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& ne return false; } break; -#endif case EbtInt: switch (src) { case EbtUint: newOp = EOpConvUintToInt; break; case EbtBool: newOp = EOpConvBoolToInt; break; case EbtFloat: newOp = EOpConvFloatToInt; break; -#ifndef GLSLANG_WEB case EbtInt8: newOp = EOpConvInt8ToInt; break; case EbtUint8: newOp = EOpConvUint8ToInt; break; case EbtInt16: newOp = EOpConvInt16ToInt; break; @@ -731,7 +718,6 @@ bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& ne case EbtFloat16: newOp = EOpConvFloat16ToInt; break; case EbtInt64: newOp = EOpConvInt64ToInt; break; case EbtUint64: newOp = EOpConvUint64ToInt; break; -#endif default: return false; } @@ -741,7 +727,6 @@ bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& ne case EbtInt: newOp = EOpConvIntToUint; break; case EbtBool: newOp = EOpConvBoolToUint; break; case EbtFloat: newOp = EOpConvFloatToUint; break; -#ifndef GLSLANG_WEB case EbtInt8: newOp = EOpConvInt8ToUint; break; case EbtUint8: newOp = EOpConvUint8ToUint; break; case EbtInt16: newOp = EOpConvInt16ToUint; break; @@ -750,12 +735,15 @@ bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& ne case EbtFloat16: newOp = EOpConvFloat16ToUint; break; case EbtInt64: newOp = EOpConvInt64ToUint; break; case EbtUint64: newOp = EOpConvUint64ToUint; break; -#endif + // For bindless texture type conversion, add a dummy convert op, just + // to generate a new TIntermTyped + // uvec2(any sampler type) + // uvec2(any image type) + case EbtSampler: newOp = EOpConvIntToUint; break; default: return false; } break; -#ifndef GLSLANG_WEB case EbtInt64: switch (src) { case EbtInt8: newOp = EOpConvInt8ToInt64; break; @@ -790,7 +778,6 @@ bool TIntermediate::buildConvertOp(TBasicType dst, TBasicType src, TOperator& ne return false; } break; -#endif default: return false; } @@ -806,7 +793,6 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped // Add a new newNode for the conversion. // -#ifndef GLSLANG_WEB bool convertToIntTypes = (convertTo == EbtInt8 || convertTo == EbtUint8 || convertTo == EbtInt16 || convertTo == EbtUint16 || convertTo == EbtInt || convertTo == EbtUint || @@ -843,7 +829,6 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped return nullptr; } } -#endif TIntermUnary* newNode = nullptr; TOperator newOp = EOpNull; @@ -855,13 +840,11 @@ TIntermTyped* TIntermediate::createConversion(TBasicType convertTo, TIntermTyped newNode = addUnaryNode(newOp, node, node->getLoc(), newType); if (node->getAsConstantUnion()) { -#ifndef GLSLANG_WEB // 8/16-bit storage extensions don't support 8/16-bit constants, so don't fold conversions // to those types if ((getArithemeticInt8Enabled() || !(convertTo == EbtInt8 || convertTo == EbtUint8)) && (getArithemeticInt16Enabled() || !(convertTo == EbtInt16 || convertTo == EbtUint16)) && (getArithemeticFloat16Enabled() || !(convertTo == EbtFloat16))) -#endif { TIntermTyped* folded = node->getAsConstantUnion()->fold(newOp, newType); if (folded) @@ -1044,6 +1027,12 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt if (type.isArray() || node->getType().isArray()) return nullptr; + // Reject implicit conversions to cooperative matrix types + if (node->getType().isCoopMat() && + op != EOpConstructCooperativeMatrixNV && + op != EOpConstructCooperativeMatrixKHR) + return nullptr; + // Note: callers are responsible for other aspects of shape, // like vector and matrix sizes. @@ -1055,7 +1044,6 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EOpConstructFloat: case EOpConstructInt: case EOpConstructUint: -#ifndef GLSLANG_WEB case EOpConstructDouble: case EOpConstructFloat16: case EOpConstructInt8: @@ -1066,8 +1054,6 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EOpConstructUint64: break; -#endif - // // Implicit conversions // @@ -1112,7 +1098,8 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt case EOpSequence: case EOpConstructStruct: - case EOpConstructCooperativeMatrix: + case EOpConstructCooperativeMatrixNV: + case EOpConstructCooperativeMatrixKHR: if (type.isReference() || node->getType().isReference()) { // types must match to assign a reference @@ -1154,7 +1141,6 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt } bool canPromoteConstant = true; -#ifndef GLSLANG_WEB // GL_EXT_shader_16bit_storage can't do OpConstantComposite with // 16-bit types, so disable promotion for those types. // Many issues with this, from JohnK: @@ -1182,7 +1168,6 @@ TIntermTyped* TIntermediate::addConversion(TOperator op, const TType& type, TInt default: break; } -#endif if (canPromoteConstant && node->getAsConstantUnion()) return promoteConstantUnion(type.getBasicType(), node->getAsConstantUnion()); @@ -1479,10 +1464,6 @@ bool TIntermediate::isFPPromotion(TBasicType from, TBasicType to) const bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const { -#ifdef GLSLANG_WEB - return false; -#endif - switch (from) { case EbtInt: switch(to) { @@ -1563,10 +1544,6 @@ bool TIntermediate::isIntegralConversion(TBasicType from, TBasicType to) const bool TIntermediate::isFPConversion(TBasicType from, TBasicType to) const { -#ifdef GLSLANG_WEB - return false; -#endif - if (to == EbtFloat && from == EbtFloat16) { return true; } else { @@ -1587,7 +1564,6 @@ bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const break; } break; -#ifndef GLSLANG_WEB case EbtInt8: case EbtUint8: case EbtInt16: @@ -1607,7 +1583,6 @@ bool TIntermediate::isFPIntegralConversion(TBasicType from, TBasicType to) const return true; } break; -#endif default: break; } @@ -1809,10 +1784,6 @@ bool TIntermediate::canImplicitlyPromote(TBasicType from, TBasicType to, TOperat static bool canSignedIntTypeRepresentAllUnsignedValues(TBasicType sintType, TBasicType uintType) { -#ifdef GLSLANG_WEB - return false; -#endif - switch(sintType) { case EbtInt8: switch(uintType) { @@ -1873,11 +1844,6 @@ static bool canSignedIntTypeRepresentAllUnsignedValues(TBasicType sintType, TBas static TBasicType getCorrespondingUnsignedType(TBasicType type) { -#ifdef GLSLANG_WEB - assert(type == EbtInt); - return EbtUint; -#endif - switch(type) { case EbtInt8: return EbtUint8; @@ -2003,8 +1969,11 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const if (type.getQualifier().isNonUniform()) return EOpConstructNonuniform; - if (type.isCoopMat()) - return EOpConstructCooperativeMatrix; + if (type.isCoopMatNV()) + return EOpConstructCooperativeMatrixNV; + + if (type.isCoopMatKHR()) + return EOpConstructCooperativeMatrixKHR; switch (type.getBasicType()) { case EbtStruct: @@ -2167,7 +2136,6 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const } } break; -#ifndef GLSLANG_WEB case EbtDouble: if (type.getMatrixCols()) { switch (type.getMatrixCols()) { @@ -2306,7 +2274,6 @@ TOperator TIntermediate::mapTypeToConstructorOp(const TType& type) const case EbtAccStruct: op = EOpConstructAccStruct; break; -#endif default: break; } @@ -2350,6 +2317,40 @@ TIntermAggregate* TIntermediate::growAggregate(TIntermNode* left, TIntermNode* r return aggNode; } +TIntermAggregate* TIntermediate::mergeAggregate(TIntermNode* left, TIntermNode* right) +{ + if (left == nullptr && right == nullptr) + return nullptr; + + TIntermAggregate* aggNode = nullptr; + if (left != nullptr) + aggNode = left->getAsAggregate(); + if (aggNode == nullptr || aggNode->getOp() != EOpNull) { + aggNode = new TIntermAggregate; + if (left != nullptr) + aggNode->getSequence().push_back(left); + } + + TIntermAggregate* rhsagg = right->getAsAggregate(); + if (rhsagg == nullptr || rhsagg->getOp() != EOpNull) + aggNode->getSequence().push_back(right); + else + aggNode->getSequence().insert(aggNode->getSequence().end(), + rhsagg->getSequence().begin(), + rhsagg->getSequence().end()); + + return aggNode; +} + +TIntermAggregate* TIntermediate::mergeAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc& loc) +{ + TIntermAggregate* aggNode = mergeAggregate(left, right); + if (aggNode) + aggNode->setLoc(loc); + + return aggNode; +} + // // Turn an existing node into an aggregate. // @@ -2623,6 +2624,18 @@ TIntermConstantUnion* TIntermediate::addConstantUnion(double d, TBasicType baseT { assert(baseType == EbtFloat || baseType == EbtDouble || baseType == EbtFloat16); + if (isEsProfile() && (baseType == EbtFloat || baseType == EbtFloat16)) { + int exponent = 0; + frexp(d, &exponent); + int minExp = baseType == EbtFloat ? -126 : -14; + int maxExp = baseType == EbtFloat ? 127 : 15; + if (exponent > maxExp) { //overflow, d = inf + d = std::numeric_limits::infinity(); + } else if (exponent < minExp) { //underflow, d = 0.0; + d = 0.0; + } + } + TConstUnionArray unionArray(1); unionArray[0].setDConst(d); @@ -2680,28 +2693,42 @@ TIntermTyped* TIntermediate::addSwizzle(TSwizzleSelectors& selecto // 'swizzleOkay' says whether or not it is okay to consider a swizzle // a valid part of the dereference chain. // -// 'BufferReferenceOk' says if type is buffer_reference, the routine stop to find the most left node. +// 'bufferReferenceOk' says if type is buffer_reference, the routine will stop to find the most left node. // +// 'proc' is an optional function to run on each node that is processed during the traversal. 'proc' must +// return true to continue the traversal, or false to end the traversal early. // -const TIntermTyped* TIntermediate::findLValueBase(const TIntermTyped* node, bool swizzleOkay , bool bufferReferenceOk) +const TIntermTyped* TIntermediate::traverseLValueBase(const TIntermTyped* node, bool swizzleOkay, + bool bufferReferenceOk, + std::function proc) { do { const TIntermBinary* binary = node->getAsBinaryNode(); - if (binary == nullptr) + if (binary == nullptr) { + if (proc) { + proc(*node); + } return node; + } TOperator op = binary->getOp(); - if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle && op != EOpMatrixSwizzle) + if (op != EOpIndexDirect && op != EOpIndexIndirect && op != EOpIndexDirectStruct && op != EOpVectorSwizzle && + op != EOpMatrixSwizzle) return nullptr; - if (! swizzleOkay) { + if (!swizzleOkay) { if (op == EOpVectorSwizzle || op == EOpMatrixSwizzle) return nullptr; if ((op == EOpIndexDirect || op == EOpIndexIndirect) && (binary->getLeft()->getType().isVector() || binary->getLeft()->getType().isScalar()) && - ! binary->getLeft()->getType().isArray()) + !binary->getLeft()->getType().isArray()) return nullptr; } - node = node->getAsBinaryNode()->getLeft(); + if (proc) { + if (!proc(*node)) { + return node; + } + } + node = binary->getLeft(); if (bufferReferenceOk && node->isReference()) return node; } while (true); @@ -2733,10 +2760,10 @@ TIntermAggregate* TIntermediate::addForLoop(TIntermNode* body, TIntermNode* init TIntermAggregate* loopSequence = (initializer == nullptr || initializer->getAsAggregate() == nullptr) ? makeAggregate(initializer, loc) : initializer->getAsAggregate(); - if (loopSequence != nullptr && loopSequence->getOp() == EOpSequence) + if (loopSequence != nullptr && (loopSequence->getOp() == EOpSequence || loopSequence->getOp() == EOpScope)) loopSequence->setOp(EOpNull); loopSequence = growAggregate(loopSequence, node); - loopSequence->setOperator(EOpSequence); + loopSequence->setOperator(getDebugInfo() ? EOpScope : EOpSequence); return loopSequence; } @@ -2766,7 +2793,7 @@ void TIntermBranch::updatePrecision(TPrecisionQualifier parentPrecision) return; if (exp->getBasicType() == EbtInt || exp->getBasicType() == EbtUint || - exp->getBasicType() == EbtFloat || exp->getBasicType() == EbtFloat16) { + exp->getBasicType() == EbtFloat) { if (parentPrecision != EpqNone && exp->getQualifier().precision == EpqNone) { exp->propagatePrecision(parentPrecision); } @@ -2787,7 +2814,6 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/) if (aggRoot && aggRoot->getOp() == EOpNull) aggRoot->setOperator(EOpSequence); -#ifndef GLSLANG_WEB // Propagate 'noContraction' label in backward from 'precise' variables. glslang::PropagateNoContraction(*this); @@ -2801,7 +2827,6 @@ bool TIntermediate::postProcess(TIntermNode* root, EShLanguage /*language*/) assert(0); break; } -#endif return true; } @@ -2830,10 +2855,9 @@ void TIntermediate::addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguag //} if (language == EShLangVertex) { - // the names won't be found in the symbol table unless the versions are right, - // so version logic does not need to be repeated here addSymbolLinkageNode(linkage, symbolTable, "gl_VertexID"); - addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID"); + if ((version < 140 && requestedExtensions.find(E_GL_EXT_draw_instanced) != requestedExtensions.end()) || version >= 140) + addSymbolLinkageNode(linkage, symbolTable, "gl_InstanceID"); } // Add a child to the root node for the linker objects @@ -3284,7 +3308,7 @@ bool TIntermediate::promoteUnary(TIntermUnary& node) void TIntermUnary::updatePrecision() { if (getBasicType() == EbtInt || getBasicType() == EbtUint || - getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { + getBasicType() == EbtFloat) { if (operand->getQualifier().precision > getQualifier().precision) getQualifier().precision = operand->getQualifier().precision; } @@ -3521,20 +3545,28 @@ bool TIntermediate::promoteBinary(TIntermBinary& node) } if (left->getType().isCoopMat() || right->getType().isCoopMat()) { + // Operations on two cooperative matrices must have identical types if (left->getType().isCoopMat() && right->getType().isCoopMat() && - *left->getType().getTypeParameters() != *right->getType().getTypeParameters()) { + left->getType() != right->getType()) { return false; } switch (op) { case EOpMul: case EOpMulAssign: - if (left->getType().isCoopMat() && right->getType().isCoopMat()) { + // Mul not supported in NV_cooperative_matrix + if (left->getType().isCoopMatNV() && right->getType().isCoopMatNV()) { return false; } - if (op == EOpMulAssign && right->getType().isCoopMat()) { + // NV_cooperative_matrix supports MulAssign is for mat*=scalar only. + // KHR_cooperative_matrix supports it for mat*=mat as well. + if (op == EOpMulAssign && right->getType().isCoopMatNV()) { return false; } - node.setOp(op == EOpMulAssign ? EOpMatrixTimesScalarAssign : EOpMatrixTimesScalar); + // Use MatrixTimesScalar if either operand is not a matrix. Otherwise use Mul. + if (!left->getType().isCoopMat() || !right->getType().isCoopMat()) { + node.setOp(op == EOpMulAssign ? EOpMatrixTimesScalarAssign : EOpMatrixTimesScalar); + } + // In case of scalar*matrix, take the result type from the matrix. if (right->getType().isCoopMat()) { node.setType(right->getType()); } @@ -3785,7 +3817,7 @@ bool TIntermediate::promoteAggregate(TIntermAggregate& node) void TIntermAggregate::updatePrecision() { if (getBasicType() == EbtInt || getBasicType() == EbtUint || - getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { + getBasicType() == EbtFloat) { TPrecisionQualifier maxPrecision = EpqNone; TIntermSequence operands = getSequence(); for (unsigned int i = 0; i < operands.size(); ++i) { @@ -3807,7 +3839,7 @@ void TIntermAggregate::updatePrecision() void TIntermBinary::updatePrecision() { if (getBasicType() == EbtInt || getBasicType() == EbtUint || - getBasicType() == EbtFloat || getBasicType() == EbtFloat16) { + getBasicType() == EbtFloat) { if (op == EOpRightShift || op == EOpLeftShift) { // For shifts get precision from left side only and thus no need to propagate getQualifier().precision = left->getQualifier().precision; @@ -3887,16 +3919,6 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC #define PROMOTE(Set, CType, Get) leftUnionArray[i].Set(static_cast(rightUnionArray[i].Get())) #define PROMOTE_TO_BOOL(Get) leftUnionArray[i].setBConst(rightUnionArray[i].Get() != 0) -#ifdef GLSLANG_WEB -#define TO_ALL(Get) \ - switch (promoteTo) { \ - case EbtFloat: PROMOTE(setDConst, double, Get); break; \ - case EbtInt: PROMOTE(setIConst, int, Get); break; \ - case EbtUint: PROMOTE(setUConst, unsigned int, Get); break; \ - case EbtBool: PROMOTE_TO_BOOL(Get); break; \ - default: return node; \ - } -#else #define TO_ALL(Get) \ switch (promoteTo) { \ case EbtFloat16: PROMOTE(setDConst, double, Get); break; \ @@ -3913,14 +3935,12 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC case EbtBool: PROMOTE_TO_BOOL(Get); break; \ default: return node; \ } -#endif switch (node->getType().getBasicType()) { case EbtFloat: TO_ALL(getDConst); break; case EbtInt: TO_ALL(getIConst); break; case EbtUint: TO_ALL(getUConst); break; case EbtBool: TO_ALL(getBConst); break; -#ifndef GLSLANG_WEB case EbtFloat16: TO_ALL(getDConst); break; case EbtDouble: TO_ALL(getDConst); break; case EbtInt8: TO_ALL(getI8Const); break; @@ -3929,7 +3949,6 @@ TIntermTyped* TIntermediate::promoteConstantUnion(TBasicType promoteTo, TIntermC case EbtUint8: TO_ALL(getU8Const); break; case EbtUint16: TO_ALL(getU16Const); break; case EbtUint64: TO_ALL(getU64Const); break; -#endif default: return node; } } diff --git a/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp b/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp index 1da50d62f..8e8bcd886 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/ParseContextBase.cpp @@ -67,13 +67,14 @@ 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, const char* szExtraInfoFormat, ...) { if (messages & EShMsgOnlyPreprocessor) return; + // If enhanced msg readability, only print one error + if (messages & EShMsgEnhanced && numErrors > 0) + return; va_list args; va_start(args, szExtraInfoFormat); outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args); @@ -115,8 +116,6 @@ void C_DECL TParseContextBase::ppWarn(const TSourceLoc& loc, const char* szReaso va_end(args); } -#endif - // // 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. @@ -137,7 +136,6 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, case EvqConst: 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; -#ifndef GLSLANG_WEB case EvqBuffer: if (node->getQualifier().isReadOnly()) message = "can't modify a readonly buffer"; @@ -148,7 +146,6 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, if (language != EShLangIntersect) message = "cannot modify hitAttributeNV in this stage"; break; -#endif default: // @@ -156,12 +153,12 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, // switch (node->getBasicType()) { case EbtSampler: - message = "can't modify a sampler"; + if (extensionTurnedOn(E_GL_ARB_bindless_texture) == false) + message = "can't modify a sampler"; break; case EbtVoid: message = "can't modify void"; break; -#ifndef GLSLANG_WEB case EbtAtomicUint: message = "can't modify an atomic_uint"; break; @@ -171,7 +168,9 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, case EbtRayQuery: message = "can't modify rayQueryEXT"; break; -#endif + case EbtHitObjectNV: + message = "can't modify hitObjectNV"; + break; default: break; } @@ -209,7 +208,7 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, // // If we get here, we have an error and a message. // - const TIntermTyped* leftMostTypeNode = TIntermediate::findLValueBase(node, true); + const TIntermTyped* leftMostTypeNode = TIntermediate::traverseLValueBase(node, true); if (symNode) error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message); @@ -228,14 +227,14 @@ bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, // Test for and give an error if the node can't be read from. void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node) { - TIntermBinary* binaryNode = node->getAsBinaryNode(); - const TIntermSymbol* symNode = node->getAsSymbolNode(); - if (! node) return; + TIntermBinary* binaryNode = node->getAsBinaryNode(); + const TIntermSymbol* symNode = node->getAsSymbolNode(); + if (node->getQualifier().isWriteOnly()) { - const TIntermTyped* leftMostTypeNode = TIntermediate::findLValueBase(node, true); + const TIntermTyped* leftMostTypeNode = TIntermediate::traverseLValueBase(node, true); if (symNode != nullptr) error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str()); @@ -627,10 +626,8 @@ void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& mem if (symbol) { if (memberType != symbol->getType()) { TString err; - err += "\"" + memberType.getCompleteString() + "\""; - err += " versus "; - err += "\"" + symbol->getType().getCompleteString() + "\""; - error(loc, "Types must match:", memberType.getFieldName().c_str(), err.c_str()); + err += "Redeclaration: already declared as \"" + symbol->getType().getCompleteString() + "\""; + error(loc, "", memberName.c_str(), err.c_str()); } return; } @@ -725,6 +722,24 @@ void TParseContextBase::finish() if (parsingBuiltins) return; + for (const TString& relaxedSymbol : relaxedSymbols) + { + TSymbol* symbol = symbolTable.find(relaxedSymbol); + TType& type = symbol->getWritableType(); + for (const TTypeLoc& typeLoc : *type.getStruct()) + { + if (typeLoc.type->isOpaque()) + { + typeLoc.type->getSampler() = TSampler{}; + typeLoc.type->setBasicType(EbtInt); + TString fieldName("/*"); + fieldName.append(typeLoc.type->getFieldName()); + fieldName.append("*/"); + typeLoc.type->setFieldName(fieldName); + } + } + } + // Transfer the linkage symbols to AST nodes, preserving order. TIntermAggregate* linkage = new TIntermAggregate; for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i) diff --git a/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp b/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp index 0f8d05e9a..f84dc9bec 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.cpp @@ -38,6 +38,7 @@ // #include "ParseHelper.h" +#include "Initialize.h" #include "Scan.h" #include "../OSDependent/osinclude.h" @@ -57,11 +58,8 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b infoSink, forwardCompatible, messages, entryPoint), inMain(false), blockName(nullptr), - limits(resources.limits) -#ifndef GLSLANG_WEB - , + limits(resources.limits), atomicUintOffsets(nullptr), anyIndexLimits(false) -#endif { // decide whether precision qualifiers should be ignored or respected if (isEsProfile() || spvVersion.vulkan > 0) { @@ -80,10 +78,6 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b globalBufferDefaults.layoutMatrix = ElmColumnMajor; globalBufferDefaults.layoutPacking = spvVersion.spv != 0 ? ElpStd430 : ElpShared; - // use storage buffer on SPIR-V 1.3 and up - if (spvVersion.spv >= EShTargetSpv_1_3) - intermediate.setUseStorageBuffer(); - globalInputDefaults.clear(); globalOutputDefaults.clear(); @@ -91,7 +85,6 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b globalSharedDefaults.layoutMatrix = ElmColumnMajor; globalSharedDefaults.layoutPacking = ElpStd430; -#ifndef GLSLANG_WEB // "Shaders in the transform // feedback capturing mode have an initial global default of // layout(xfb_buffer = 0) out;" @@ -103,7 +96,6 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b if (language == EShLangGeometry) globalOutputDefaults.layoutStream = 0; -#endif if (entryPoint != nullptr && entryPoint->size() > 0 && *entryPoint != "main") infoSink.info.message(EPrefixError, "Source entry point must be \"main\""); @@ -111,9 +103,7 @@ TParseContext::TParseContext(TSymbolTable& symbolTable, TIntermediate& interm, b TParseContext::~TParseContext() { -#ifndef GLSLANG_WEB delete [] atomicUintOffsets; -#endif } // Set up all default precisions as needed by the current environment. @@ -177,7 +167,6 @@ void TParseContext::setLimits(const TBuiltInResource& r) resources = r; intermediate.setLimits(r); -#ifndef GLSLANG_WEB anyIndexLimits = ! limits.generalAttributeMatrixVectorIndexing || ! limits.generalConstantMatrixVectorIndexing || ! limits.generalSamplerIndexing || @@ -192,7 +181,6 @@ void TParseContext::setLimits(const TBuiltInResource& r) atomicUintOffsets = new int[resources.maxAtomicCounterBindings]; for (int b = 0; b < resources.maxAtomicCounterBindings; ++b) atomicUintOffsets[b] = 0; -#endif } // @@ -339,7 +327,6 @@ void TParseContext::setInvariant(const TSourceLoc& loc, const char* builtin) { void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& tokens) { -#ifndef GLSLANG_WEB if (pragmaCallback) pragmaCallback(loc.line, tokens); @@ -441,7 +428,6 @@ void TParseContext::handlePragma(const TSourceLoc& loc, const TVector& setInvariant(loc, "gl_FragColor"); setInvariant(loc, "gl_FragData"); } -#endif } // @@ -455,7 +441,6 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb if (symbol && symbol->getNumExtensions()) requireExtensions(loc, symbol->getNumExtensions(), symbol->getExtensions(), symbol->getName().c_str()); -#ifndef GLSLANG_WEB if (symbol && symbol->isReadOnly()) { // All shared things containing an unsized array must be copied up // on first use, so that all future references will share its array structure, @@ -475,7 +460,6 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb makeEditable(symbol); } } -#endif const TVariable* variable; const TAnonMember* anon = symbol ? symbol->getAsAnonMember() : nullptr; @@ -502,6 +486,16 @@ TIntermTyped* TParseContext::handleVariable(const TSourceLoc& loc, TSymbol* symb error(loc, "cannot be used (maybe an instance name is needed)", string->c_str(), ""); variable = nullptr; } + + if (language == EShLangMesh && variable) { + TLayoutGeometry primitiveType = intermediate.getOutputPrimitive(); + if ((variable->getMangledName() == "gl_PrimitiveTriangleIndicesEXT" && primitiveType != ElgTriangles) || + (variable->getMangledName() == "gl_PrimitiveLineIndicesEXT" && primitiveType != ElgLines) || + (variable->getMangledName() == "gl_PrimitivePointIndicesEXT" && primitiveType != ElgPoints)) { + error(loc, "cannot be used (ouput primitive type mismatch)", string->c_str(), ""); + variable = nullptr; + } + } } else { if (symbol) error(loc, "variable name expected", string->c_str(), ""); @@ -570,7 +564,6 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn // at least one of base and index is not a front-end constant variable... TIntermTyped* result = nullptr; -#ifndef GLSLANG_WEB if (base->isReference() && ! base->isArray()) { requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "buffer reference indexing"); if (base->getType().getReferentType()->containsUnsizedArray()) { @@ -589,15 +582,22 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn } if (base->getAsSymbolNode() && isIoResizeArray(base->getType())) handleIoResizeArrayAccess(loc, base); -#endif if (index->getQualifier().isFrontEndConstant()) checkIndex(loc, base->getType(), indexValue); if (index->getQualifier().isFrontEndConstant()) { -#ifndef GLSLANG_WEB if (base->getType().isUnsizedArray()) { base->getWritableType().updateImplicitArraySize(indexValue + 1); + base->getWritableType().setImplicitlySized(true); + if (base->getQualifier().builtIn == EbvClipDistance && + indexValue >= resources.maxClipDistances) { + error(loc, "gl_ClipDistance", "[", "array index out of range '%d'", indexValue); + } + else if (base->getQualifier().builtIn == EbvCullDistance && + indexValue >= resources.maxCullDistances) { + error(loc, "gl_CullDistance", "[", "array index out of range '%d'", indexValue); + } // For 2D per-view builtin arrays, update the inner dimension size in parent type if (base->getQualifier().isPerView() && base->getQualifier().builtIn != EbvNone) { TIntermBinary* binaryNode = base->getAsBinaryNode(); @@ -609,11 +609,9 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn } } } else -#endif checkIndex(loc, base->getType(), indexValue); result = intermediate.addIndex(EOpIndexDirect, base, index, loc); } else { -#ifndef GLSLANG_WEB if (base->getType().isUnsizedArray()) { // we have a variable index into an unsized array, which is okay, // depending on the situation @@ -625,7 +623,6 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn } base->getWritableType().setArrayVariablyIndexed(); } -#endif if (base->getBasicType() == EbtBlock) { if (base->getQualifier().storage == EvqBuffer) requireProfile(base->getLoc(), ~EEsProfile, "variable indexing buffer block array"); @@ -635,7 +632,7 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn else { // input/output blocks either don't exist or can't be variably indexed } - } else if (language == EShLangFragment && base->getQualifier().isPipeOutput()) + } else if (language == EShLangFragment && base->getQualifier().isPipeOutput() && base->getQualifier().builtIn != EbvSampleMask) requireProfile(base->getLoc(), ~EEsProfile, "variable indexing fragment shader output array"); else if (base->getBasicType() == EbtSampler && version >= 130) { const char* explanation = "variable indexing sampler array"; @@ -661,7 +658,6 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn } result->setType(newType); -#ifndef GLSLANG_WEB inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier()); // Propagate nonuniform @@ -670,13 +666,10 @@ TIntermTyped* TParseContext::handleBracketDereference(const TSourceLoc& loc, TIn if (anyIndexLimits) handleIndexLimits(loc, base, index); -#endif return result; } -#ifndef GLSLANG_WEB - // for ES 2.0 (version 100) limitations for almost all index operations except vertex-shader uniforms void TParseContext::handleIndexLimits(const TSourceLoc& /*loc*/, TIntermTyped* base, TIntermTyped* index) { @@ -716,8 +709,8 @@ bool TParseContext::isIoResizeArray(const TType& type) const (language == EShLangTessControl && type.getQualifier().storage == EvqVaryingOut && ! type.getQualifier().patch) || (language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn && - type.getQualifier().pervertexNV) || - (language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut && + (type.getQualifier().pervertexNV || type.getQualifier().pervertexEXT)) || + (language == EShLangMesh && type.getQualifier().storage == EvqVaryingOut && !type.getQualifier().perTaskNV)); } @@ -794,7 +787,7 @@ void TParseContext::checkIoArraysConsistency(const TSourceLoc &loc, bool tailOnl // As I/O array sizes don't change, fetch requiredSize only once, // except for mesh shaders which could have different I/O array sizes based on type qualifiers. - if (firstIteration || (language == EShLangMeshNV)) { + if (firstIteration || (language == EShLangMesh)) { requiredSize = getIoArrayImplicitSize(type.getQualifier(), &featureString); if (requiredSize == 0) break; @@ -823,7 +816,7 @@ int TParseContext::getIoArrayImplicitSize(const TQualifier &qualifier, TString * // Number of vertices for Fragment shader is always three. expectedSize = 3; str = "vertices"; - } else if (language == EShLangMeshNV) { + } else if (language == EShLangMesh) { unsigned int maxPrimitives = intermediate.getPrimitives() != TQualifier::layoutNotSet ? intermediate.getPrimitives() : 0; if (qualifier.builtIn == EbvPrimitiveIndicesNV) { @@ -831,6 +824,11 @@ int TParseContext::getIoArrayImplicitSize(const TQualifier &qualifier, TString * str = "max_primitives*"; str += TQualifier::getGeometryString(intermediate.getOutputPrimitive()); } + else if (qualifier.builtIn == EbvPrimitiveTriangleIndicesEXT || qualifier.builtIn == EbvPrimitiveLineIndicesEXT || + qualifier.builtIn == EbvPrimitivePointIndicesEXT) { + expectedSize = maxPrimitives; + str = "max_primitives"; + } else if (qualifier.isPerPrimitive()) { expectedSize = maxPrimitives; str = "max_primitives"; @@ -856,17 +854,15 @@ void TParseContext::checkIoArrayConsistency(const TSourceLoc& loc, int requiredS error(loc, "inconsistent output number of vertices for array size of", feature, name.c_str()); else if (language == EShLangFragment) { if (type.getOuterArraySize() > requiredSize) - error(loc, " cannot be greater than 3 for pervertexNV", feature, name.c_str()); + error(loc, " cannot be greater than 3 for pervertexEXT", feature, name.c_str()); } - else if (language == EShLangMeshNV) + else if (language == EShLangMesh) error(loc, "inconsistent output array size of", feature, name.c_str()); else assert(0); } } -#endif // GLSLANG_WEB - // Handle seeing a binary node with a math operation. // Returns nullptr if not semantically allowed. TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* str, TOperator op, TIntermTyped* left, TIntermTyped* right) @@ -902,8 +898,10 @@ TIntermTyped* TParseContext::handleBinaryMath(const TSourceLoc& loc, const char* result = intermediate.addBinaryMath(op, left, right, loc); } - if (result == nullptr) - binaryOpError(loc, str, left->getCompleteString(), right->getCompleteString()); + if (result == nullptr) { + bool enhanced = intermediate.getEnhancedMsgs(); + binaryOpError(loc, str, left->getCompleteString(enhanced), right->getCompleteString(enhanced)); + } return result; } @@ -926,8 +924,10 @@ TIntermTyped* TParseContext::handleUnaryMath(const TSourceLoc& loc, const char* if (result) return result; - else - unaryOpError(loc, str, childNode->getCompleteString()); + else { + bool enhanced = intermediate.getEnhancedMsgs(); + unaryOpError(loc, str, childNode->getCompleteString(enhanced)); + } return childNode; } @@ -953,8 +953,8 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm requireProfile(loc, ~EEsProfile, feature); profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, feature); } else if (!base->getType().isCoopMat()) { - error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString().c_str()); - + bool enhanced = intermediate.getEnhancedMsgs(); + error(loc, "does not operate on this type:", field.c_str(), base->getType().getCompleteString(enhanced).c_str()); return base; } @@ -993,22 +993,44 @@ TIntermTyped* TParseContext::handleDotDereference(const TSourceLoc& loc, TInterm break; } } + if (fieldFound) { - if (base->getType().getQualifier().isFrontEndConstant()) - result = intermediate.foldDereference(base, member, loc); - else { - blockMemberExtensionCheck(loc, base, member, field); - TIntermTyped* index = intermediate.addConstantUnion(member, loc); - result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc); - result->setType(*(*fields)[member].type); - if ((*fields)[member].type->getQualifier().isIo()) - intermediate.addIoAccessed(field); + if (spvVersion.vulkan != 0 && spvVersion.vulkanRelaxed) + result = vkRelaxedRemapDotDereference(loc, *base, *(*fields)[member].type, field); + + if (result == base) + { + if (base->getType().getQualifier().isFrontEndConstant()) + result = intermediate.foldDereference(base, member, loc); + else { + blockMemberExtensionCheck(loc, base, member, field); + TIntermTyped* index = intermediate.addConstantUnion(member, loc); + result = intermediate.addIndex(EOpIndexDirectStruct, base, index, loc); + result->setType(*(*fields)[member].type); + if ((*fields)[member].type->getQualifier().isIo()) + intermediate.addIoAccessed(field); + } } + inheritMemoryQualifiers(base->getQualifier(), result->getWritableType().getQualifier()); - } else - error(loc, "no such field in structure", field.c_str(), ""); + } else { + auto baseSymbol = base; + while (baseSymbol->getAsSymbolNode() == nullptr) { + auto binaryNode = baseSymbol->getAsBinaryNode(); + if (binaryNode == nullptr) break; + baseSymbol = binaryNode->getLeft(); + } + if (baseSymbol->getAsSymbolNode() != nullptr) { + TString structName; + structName.append("\'").append(baseSymbol->getAsSymbolNode()->getName().c_str()).append("\'"); + error(loc, "no such field in structure", field.c_str(), structName.c_str()); + } else { + error(loc, "no such field in structure", field.c_str(), ""); + } + } } else - error(loc, "does not apply to this type:", field.c_str(), base->getType().getCompleteString().c_str()); + error(loc, "does not apply to this type:", field.c_str(), + base->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str()); // Propagate noContraction up the dereference chain if (base->getQualifier().isNoContraction()) @@ -1127,7 +1149,6 @@ TFunction* TParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunct TSymbol* symbol = symbolTable.find(function.getMangledName(), &builtIn); if (symbol && symbol->getAsFunction() && builtIn) requireProfile(loc, ~EEsProfile, "redefinition of built-in function"); -#ifndef GLSLANG_WEB // Check the validity of using spirv_literal qualifier for (int i = 0; i < function.getParamCount(); ++i) { if (function[i].type->getQualifier().isSpirvLiteral() && function.getBuiltInOp() != EOpSpirvInst) @@ -1139,19 +1160,16 @@ TFunction* TParseContext::handleFunctionDeclarator(const TSourceLoc& loc, TFunct // respect this redeclared one. if (symbol && builtIn && function.getBuiltInOp() == EOpSpirvInst) symbol = nullptr; -#endif - const TFunction* prevDec = symbol ? symbol->getAsFunction() : 0; + const TFunction* prevDec = symbol ? symbol->getAsFunction() : nullptr; if (prevDec) { if (prevDec->isPrototyped() && prototype) profileRequires(loc, EEsProfile, 300, nullptr, "multiple prototypes for same function"); if (prevDec->getType() != function.getType()) error(loc, "overloaded functions must have the same return type", function.getName().c_str(), ""); -#ifndef GLSLANG_WEB if (prevDec->getSpirvInstruction() != function.getSpirvInstruction()) { error(loc, "overloaded functions must have the same qualifiers", function.getName().c_str(), "spirv_instruction"); } -#endif for (int i = 0; i < prevDec->getParamCount(); ++i) { if ((*prevDec)[i].type->getQualifier().storage != function[i].type->getQualifier().storage) error(loc, "overloaded functions must have the same parameter storage qualifiers for argument", function[i].type->getStorageQualifierString(), "%d", i+1); @@ -1233,6 +1251,8 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc, error(loc, "function cannot take any parameter(s)", function.getName().c_str(), ""); if (function.getType().getBasicType() != EbtVoid) error(loc, "", function.getType().getBasicTypeString().c_str(), "entry point cannot return a value"); + if (function.getLinkType() != ELinkNone) + error(loc, "main function cannot be exported", "", ""); } // @@ -1269,6 +1289,7 @@ TIntermAggregate* TParseContext::handleFunctionDefinition(const TSourceLoc& loc, } else paramNodes = intermediate.growAggregate(paramNodes, intermediate.addSymbol(*param.type, loc), loc); } + paramNodes->setLinkType(function.getLinkType()); intermediate.setAggregateOperator(paramNodes, EOpParameters, TType(EbtVoid), loc); loopNestingLevel = 0; statementNestingLevel = 0; @@ -1314,14 +1335,14 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction // result = addConstructor(loc, arguments, type); if (result == nullptr) - error(loc, "cannot construct with these arguments", type.getCompleteString().c_str(), ""); + error(loc, "cannot construct with these arguments", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str(), ""); } } else { // // Find it in the symbol table. // const TFunction* fnCandidate; - bool builtIn; + bool builtIn {false}; fnCandidate = findFunction(loc, *function, builtIn); if (fnCandidate) { // This is a declared function that might map to @@ -1339,7 +1360,10 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction requireInt16Arithmetic(loc, "built-in function", "(u)int16 types can only be in uniform block or buffer storage"); if (builtIn && fnCandidate->getType().contains8BitInt()) requireInt8Arithmetic(loc, "built-in function", "(u)int8 types can only be in uniform block or buffer storage"); - + if (builtIn && (fnCandidate->getBuiltInOp() == EOpTextureFetch || fnCandidate->getBuiltInOp() == EOpTextureQuerySize)) { + if ((*fnCandidate)[0].type->getSampler().isMultiSample() && version <= 140) + requireExtensions(loc, 1, &E_GL_ARB_texture_multisample, fnCandidate->getName().c_str()); + } if (arguments != nullptr) { // Make sure qualifications work for these arguments. TIntermAggregate* aggregate = arguments->getAsAggregate(); @@ -1353,7 +1377,6 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction if (lValueErrorCheck(arguments->getLoc(), "assign", arg->getAsTyped())) error(arguments->getLoc(), "Non-L-value cannot be passed for 'out' or 'inout' parameters.", "out", ""); } -#ifndef GLSLANG_WEB if (formalQualifier.isSpirvLiteral()) { if (!arg->getAsTyped()->getQualifier().isFrontEndConstant()) { error(arguments->getLoc(), @@ -1361,12 +1384,11 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction "spirv_literal", ""); } } -#endif const TType& argType = arg->getAsTyped()->getType(); const TQualifier& argQualifier = argType.getQualifier(); - if (argQualifier.isMemory() && (argType.containsOpaque() || argType.isReference())) { + bool containsBindlessSampler = intermediate.getBindlessMode() && argType.containsSampler(); + if (argQualifier.isMemory() && !containsBindlessSampler && (argType.containsOpaque() || argType.isReference())) { const char* message = "argument cannot drop memory qualifier when passed to formal parameter"; -#ifndef GLSLANG_WEB if (argQualifier.volatil && ! formalQualifier.volatil) error(arguments->getLoc(), message, "volatile", ""); if (argQualifier.coherent && ! (formalQualifier.devicecoherent || formalQualifier.coherent)) @@ -1386,7 +1408,6 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction // Don't check 'restrict', it is different than the rest: // "...but only restrict can be taken away from a calling argument, by a formal parameter that // lacks the restrict qualifier..." -#endif } if (!builtIn && argQualifier.getFormat() != formalQualifier.getFormat()) { // we have mismatched formats, which should only be allowed if writeonly @@ -1416,11 +1437,9 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction if (builtIn && fnCandidate->getBuiltInOp() != EOpNull) { // A function call mapped to a built-in operation. result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate); -#ifndef GLSLANG_WEB } else if (fnCandidate->getBuiltInOp() == EOpSpirvInst) { // When SPIR-V instruction qualifier is specified, the function call is still mapped to a built-in operation. result = handleBuiltInFunctionCall(loc, arguments, *fnCandidate); -#endif } else { // This is a function call not mapped to built-in operator. // It could still be a built-in function, but only if PureOperatorBuiltins == false. @@ -1440,11 +1459,9 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction intermediate.addToCallGraph(infoSink, currentCaller, fnCandidate->getMangledName()); } -#ifndef GLSLANG_WEB if (builtIn) nonOpBuiltInCheck(loc, *fnCandidate, *call); else -#endif userFunctionCallCheck(loc, *call); } @@ -1462,7 +1479,8 @@ TIntermTyped* TParseContext::handleFunctionCall(const TSourceLoc& loc, TFunction if (result->getAsTyped()->getType().isCoopMat() && !result->getAsTyped()->getType().isParameterized()) { - assert(fnCandidate->getBuiltInOp() == EOpCooperativeMatrixMulAdd); + assert(fnCandidate->getBuiltInOp() == EOpCooperativeMatrixMulAdd || + fnCandidate->getBuiltInOp() == EOpCooperativeMatrixMulAddNV); result->setType(result->getAsAggregate()->getSequence()[2]->getAsTyped()->getType()); } @@ -1494,11 +1512,10 @@ TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNo else error(arguments->getLoc(), " wrong operand type", "Internal Error", "built in unary operator function. Type: %s", - static_cast(arguments)->getCompleteString().c_str()); + static_cast(arguments)->getCompleteString(intermediate.getEnhancedMsgs()).c_str()); } else if (result->getAsOperator()) builtInOpCheck(loc, function, *result->getAsOperator()); -#ifndef GLSLANG_WEB // Special handling for function call with SPIR-V instruction qualifier specified if (function.getBuiltInOp() == EOpSpirvInst) { if (auto agg = result->getAsAggregate()) { @@ -1525,7 +1542,6 @@ TIntermTyped* TParseContext::handleBuiltInFunctionCall(TSourceLoc loc, TIntermNo } else assert(0); } -#endif return result; } @@ -1628,9 +1644,7 @@ void TParseContext::computeBuiltinPrecisions(TIntermTyped& node, const TFunction TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermTyped* value) { -#ifndef GLSLANG_WEB storage16BitAssignmentCheck(loc, value->getType(), "return"); -#endif functionReturnsValue = true; TIntermBranch* branch = nullptr; @@ -1650,9 +1664,15 @@ TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermType error(loc, "type does not match, or is not convertible to, the function's return type", "return", ""); branch = intermediate.addBranch(EOpReturn, value, loc); } - } else + } else { + if (value->getType().isTexture() || value->getType().isImage()) { + if (spvVersion.spv != 0) + error(loc, "sampler or image cannot be used as return type when generating SPIR-V", "return", ""); + else if (!extensionTurnedOn(E_GL_ARB_bindless_texture)) + error(loc, "sampler or image can be used as return type only when the extension GL_ARB_bindless_texture enabled", "return", ""); + } branch = intermediate.addBranch(EOpReturn, value, loc); - + } branch->updatePrecision(currentFunctionType->getQualifier().precision); return branch; } @@ -1660,7 +1680,6 @@ TIntermNode* TParseContext::handleReturnValue(const TSourceLoc& loc, TIntermType // See if the operation is being done in an illegal location. void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op) { -#ifndef GLSLANG_WEB switch (op) { case EOpBarrier: if (language == EShLangTessControl) { @@ -1713,7 +1732,6 @@ void TParseContext::checkLocation(const TSourceLoc& loc, TOperator op) default: break; } -#endif } // Finish processing object.length(). This started earlier in handleDotDereference(), where @@ -1731,7 +1749,6 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction const TType& type = intermNode->getAsTyped()->getType(); if (type.isArray()) { if (type.isUnsizedArray()) { -#ifndef GLSLANG_WEB if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) { // We could be between a layout declaration that gives a built-in io array implicit size and // a user redeclaration of that array, meaning we have to substitute its implicit size here @@ -1742,17 +1759,19 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction name == "gl_MeshPrimitivesNV") { length = getIoArrayImplicitSize(type.getQualifier()); } + } else if (const auto typed = intermNode->getAsTyped()) { + if (typed->getQualifier().builtIn == EbvSampleMask) { + requireProfile(loc, EEsProfile, "the array size of gl_SampleMask and gl_SampleMaskIn is ceil(gl_MaxSamples/32)"); + length = (resources.maxSamples + 31) / 32; + } } -#endif if (length == 0) { -#ifndef GLSLANG_WEB if (intermNode->getAsSymbolNode() && isIoResizeArray(type)) error(loc, "", function->getName().c_str(), "array must first be sized by a redeclaration or layout qualifier"); else if (isRuntimeLength(*intermNode->getAsTyped())) { // Create a unary op and let the back end handle it return intermediate.addBuiltInFunctionCall(loc, EOpArrayLength, true, intermNode, TType(EbtInt)); } else -#endif error(loc, "", function->getName().c_str(), "array must be declared with a size before using this method"); } } else if (type.getOuterArrayNode()) { @@ -1785,7 +1804,6 @@ TIntermTyped* TParseContext::handleLengthMethod(const TSourceLoc& loc, TFunction // void TParseContext::addInputArgumentConversions(const TFunction& function, TIntermNode*& arguments) const { -#ifndef GLSLANG_WEB TIntermAggregate* aggregate = arguments->getAsAggregate(); // Process each argument's conversion @@ -1813,7 +1831,6 @@ void TParseContext::addInputArgumentConversions(const TFunction& function, TInte } } } -#endif } // @@ -1825,9 +1842,6 @@ void TParseContext::addInputArgumentConversions(const TFunction& function, TInte // TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& function, TIntermAggregate& intermNode) const { -#ifdef GLSLANG_WEB - return &intermNode; -#else TIntermSequence& arguments = intermNode.getSequence(); // Will there be any output conversions? @@ -1895,7 +1909,6 @@ TIntermTyped* TParseContext::addOutputArgumentConversions(const TFunction& funct conversionTree = intermediate.setAggregateOperator(conversionTree, EOpComma, intermNode.getType(), intermNode.getLoc()); return conversionTree; -#endif } TIntermTyped* TParseContext::addAssign(const TSourceLoc& loc, TOperator op, TIntermTyped* left, TIntermTyped* right) @@ -1903,6 +1916,9 @@ TIntermTyped* TParseContext::addAssign(const TSourceLoc& loc, TOperator op, TInt if ((op == EOpAddAssign || op == EOpSubAssign) && left->isReference()) requireExtensions(loc, 1, &E_GL_EXT_buffer_reference2, "+= and -= on a buffer reference"); + if (op == EOpAssign && left->getBasicType() == EbtSampler && right->getBasicType() == EbtSampler) + requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "sampler assignment for bindless texture"); + return intermediate.addAssign(op, left, right, loc); } @@ -1990,18 +2006,18 @@ void TParseContext::memorySemanticsCheck(const TSourceLoc& loc, const TFunction& break; } - if ((semantics & gl_SemanticsAcquire) && + if ((semantics & gl_SemanticsAcquire) && (callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore)) { error(loc, "gl_SemanticsAcquire must not be used with (image) atomic store", fnCandidate.getName().c_str(), ""); } - if ((semantics & gl_SemanticsRelease) && + if ((semantics & gl_SemanticsRelease) && (callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpImageAtomicLoad)) { error(loc, "gl_SemanticsRelease must not be used with (image) atomic load", fnCandidate.getName().c_str(), ""); } - if ((semantics & gl_SemanticsAcquireRelease) && - (callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore || + if ((semantics & gl_SemanticsAcquireRelease) && + (callNode.getOp() == EOpAtomicStore || callNode.getOp() == EOpImageAtomicStore || callNode.getOp() == EOpAtomicLoad || callNode.getOp() == EOpImageAtomicLoad)) { error(loc, "gl_SemanticsAcquireRelease must not be used with (image) atomic load/store", fnCandidate.getName().c_str(), ""); @@ -2102,7 +2118,6 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan TString featureString; const char* feature = nullptr; switch (callNode.getOp()) { -#ifndef GLSLANG_WEB case EOpTextureGather: case EOpTextureGatherOffset: case EOpTextureGatherOffsets: @@ -2175,6 +2190,37 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } break; } + + case EOpTexture: + case EOpTextureLod: + { + if ((fnCandidate.getParamCount() > 2) && ((*argp)[1]->getAsTyped()->getType().getBasicType() == EbtFloat) && + ((*argp)[1]->getAsTyped()->getType().getVectorSize() == 4) && fnCandidate[0].type->getSampler().shadow) { + featureString = fnCandidate.getName(); + if (callNode.getOp() == EOpTexture) + featureString += "(..., float bias)"; + else + featureString += "(..., float lod)"; + feature = featureString.c_str(); + + if ((fnCandidate[0].type->getSampler().dim == Esd2D && fnCandidate[0].type->getSampler().arrayed) || //2D Array Shadow + (fnCandidate[0].type->getSampler().dim == EsdCube && fnCandidate[0].type->getSampler().arrayed && fnCandidate.getParamCount() > 3) || // Cube Array Shadow + (fnCandidate[0].type->getSampler().dim == EsdCube && callNode.getOp() == EOpTextureLod)) { // Cube Shadow + requireExtensions(loc, 1, &E_GL_EXT_texture_shadow_lod, feature); + if (isEsProfile()) { + if (version < 320 && + !extensionsTurnedOn(Num_AEP_texture_cube_map_array, AEP_texture_cube_map_array)) + error(loc, "GL_EXT_texture_shadow_lod not supported for this ES version", feature, ""); + else + profileRequires(loc, EEsProfile, 320, nullptr, feature); + } else { // Desktop + profileRequires(loc, ~EEsProfile, 130, nullptr, feature); + } + } + } + break; + } + case EOpSparseTextureGather: case EOpSparseTextureGatherOffset: case EOpSparseTextureGatherOffsets: @@ -2243,7 +2289,6 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan break; } -#endif case EOpTextureOffset: case EOpTextureFetchOffset: @@ -2271,12 +2316,10 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan if (arg > 0) { -#ifndef GLSLANG_WEB bool f16ShadowCompare = (*argp)[1]->getAsTyped()->getBasicType() == EbtFloat16 && arg0->getType().getSampler().shadow; if (f16ShadowCompare) ++arg; -#endif if (! (*argp)[arg]->getAsTyped()->getQualifier().isConstant()) error(loc, "argument must be compile-time constant", "texel offset", ""); else if ((*argp)[arg]->getAsConstantUnion()) { @@ -2292,18 +2335,41 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan if (callNode.getOp() == EOpTextureOffset) { TSampler s = arg0->getType().getSampler(); if (s.is2D() && s.isArrayed() && s.isShadow()) { - if (isEsProfile()) + if ( + ((*argp)[1]->getAsTyped()->getType().getBasicType() == EbtFloat) && + ((*argp)[1]->getAsTyped()->getType().getVectorSize() == 4) && + (fnCandidate.getParamCount() == 4)) { + featureString = fnCandidate.getName() + " for sampler2DArrayShadow"; + feature = featureString.c_str(); + requireExtensions(loc, 1, &E_GL_EXT_texture_shadow_lod, feature); + profileRequires(loc, EEsProfile, 300, nullptr, feature); + profileRequires(loc, ~EEsProfile, 130, nullptr, feature); + } + else if (isEsProfile()) error(loc, "TextureOffset does not support sampler2DArrayShadow : ", "sampler", "ES Profile"); else if (version <= 420) error(loc, "TextureOffset does not support sampler2DArrayShadow : ", "sampler", "version <= 420"); } } + + if (callNode.getOp() == EOpTextureLodOffset) { + TSampler s = arg0->getType().getSampler(); + if (s.is2D() && s.isArrayed() && s.isShadow() && + ((*argp)[1]->getAsTyped()->getType().getBasicType() == EbtFloat) && + ((*argp)[1]->getAsTyped()->getType().getVectorSize() == 4) && + (fnCandidate.getParamCount() == 4)) { + featureString = fnCandidate.getName() + " for sampler2DArrayShadow"; + feature = featureString.c_str(); + profileRequires(loc, EEsProfile, 300, nullptr, feature); + profileRequires(loc, ~EEsProfile, 130, nullptr, feature); + requireExtensions(loc, 1, &E_GL_EXT_texture_shadow_lod, feature); + } + } } break; } -#ifndef GLSLANG_WEB case EOpTraceNV: if (!(*argp)[10]->getAsConstantUnion()) error(loc, "argument must be compile-time constant", "payload number", "a"); @@ -2317,7 +2383,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan error(loc, "argument must be compile-time constant", "payload number", "a"); else { unsigned int location = (*argp)[10]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst(); - if (intermediate.checkLocationRT(0, location) < 0) + if (!extensionTurnedOn(E_GL_EXT_spirv_intrinsics) && intermediate.checkLocationRT(0, location) < 0) error(loc, "with layout(location =", "no rayPayloadEXT/rayPayloadInEXT declared", "%d)", location); } break; @@ -2330,11 +2396,84 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan error(loc, "argument must be compile-time constant", "callable data number", ""); else { unsigned int location = (*argp)[1]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst(); - if (intermediate.checkLocationRT(1, location) < 0) + if (!extensionTurnedOn(E_GL_EXT_spirv_intrinsics) && intermediate.checkLocationRT(1, location) < 0) error(loc, "with layout(location =", "no callableDataEXT/callableDataInEXT declared", "%d)", location); } break; + case EOpHitObjectTraceRayNV: + if (!(*argp)[11]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "payload number", ""); + else { + unsigned int location = (*argp)[11]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst(); + if (!extensionTurnedOn(E_GL_EXT_spirv_intrinsics) && intermediate.checkLocationRT(0, location) < 0) + error(loc, "with layout(location =", "no rayPayloadEXT/rayPayloadInEXT declared", "%d)", location); + } + break; + case EOpHitObjectTraceRayMotionNV: + if (!(*argp)[12]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "payload number", ""); + else { + unsigned int location = (*argp)[12]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst(); + if (!extensionTurnedOn(E_GL_EXT_spirv_intrinsics) && intermediate.checkLocationRT(0, location) < 0) + error(loc, "with layout(location =", "no rayPayloadEXT/rayPayloadInEXT declared", "%d)", location); + } + break; + case EOpHitObjectExecuteShaderNV: + if (!(*argp)[1]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "payload number", ""); + else { + unsigned int location = (*argp)[1]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst(); + if (!extensionTurnedOn(E_GL_EXT_spirv_intrinsics) && intermediate.checkLocationRT(0, location) < 0) + error(loc, "with layout(location =", "no rayPayloadEXT/rayPayloadInEXT declared", "%d)", location); + } + break; + case EOpHitObjectRecordHitNV: + if (!(*argp)[12]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "hitobjectattribute number", ""); + else { + unsigned int location = (*argp)[12]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst(); + if (!extensionTurnedOn(E_GL_EXT_spirv_intrinsics) && intermediate.checkLocationRT(2, location) < 0) + error(loc, "with layout(location =", "no hitObjectAttributeNV declared", "%d)", location); + } + break; + case EOpHitObjectRecordHitMotionNV: + if (!(*argp)[13]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "hitobjectattribute number", ""); + else { + unsigned int location = (*argp)[13]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst(); + if (!extensionTurnedOn(E_GL_EXT_spirv_intrinsics) && intermediate.checkLocationRT(2, location) < 0) + error(loc, "with layout(location =", "no hitObjectAttributeNV declared", "%d)", location); + } + break; + case EOpHitObjectRecordHitWithIndexNV: + if (!(*argp)[11]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "hitobjectattribute number", ""); + else { + unsigned int location = (*argp)[11]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst(); + if (!extensionTurnedOn(E_GL_EXT_spirv_intrinsics) && intermediate.checkLocationRT(2, location) < 0) + error(loc, "with layout(location =", "no hitObjectAttributeNV declared", "%d)", location); + } + break; + case EOpHitObjectRecordHitWithIndexMotionNV: + if (!(*argp)[12]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "hitobjectattribute number", ""); + else { + unsigned int location = (*argp)[12]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst(); + if (!extensionTurnedOn(E_GL_EXT_spirv_intrinsics) && intermediate.checkLocationRT(2, location) < 0) + error(loc, "with layout(location =", "no hitObjectAttributeNV declared", "%d)", location); + } + break; + case EOpHitObjectGetAttributesNV: + if (!(*argp)[1]->getAsConstantUnion()) + error(loc, "argument must be compile-time constant", "hitobjectattribute number", ""); + else { + unsigned int location = (*argp)[1]->getAsConstantUnion()->getAsConstantUnion()->getConstArray()[0].getUConst(); + if (!extensionTurnedOn(E_GL_EXT_spirv_intrinsics) && intermediate.checkLocationRT(2, location) < 0) + error(loc, "with layout(location =", "no hitObjectAttributeNV declared", "%d)", location); + } + break; + case EOpRayQueryGetIntersectionType: case EOpRayQueryGetIntersectionT: case EOpRayQueryGetIntersectionInstanceCustomIndex: @@ -2348,6 +2487,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan case EOpRayQueryGetIntersectionObjectRayOrigin: case EOpRayQueryGetIntersectionObjectToWorld: case EOpRayQueryGetIntersectionWorldToObject: + case EOpRayQueryGetIntersectionTriangleVertexPositionsEXT: if (!(*argp)[1]->getAsConstantUnion()) error(loc, "argument must be compile-time constant", "committed", ""); break; @@ -2449,12 +2589,19 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan requireExtensions(loc, 1, &E_GL_EXT_shader_atomic_float2, fnCandidate.getName().c_str()); } - const TIntermTyped* base = TIntermediate::findLValueBase(arg0, true , true); - const TType* refType = (base->getType().isReference()) ? base->getType().getReferentType() : nullptr; - const TQualifier& qualifier = (refType != nullptr) ? refType->getQualifier() : base->getType().getQualifier(); - if (qualifier.storage != EvqShared && qualifier.storage != EvqBuffer) - error(loc,"Atomic memory function can only be used for shader storage block member or shared variable.", - fnCandidate.getName().c_str(), ""); + const TIntermTyped* base = TIntermediate::traverseLValueBase(arg0, true, true); + const char* errMsg = "Only l-values corresponding to shader block storage or shared variables can be used with " + "atomic memory functions."; + if (base) { + const TType* refType = (base->getType().isReference()) ? base->getType().getReferentType() : nullptr; + const TQualifier& qualifier = + (refType != nullptr) ? refType->getQualifier() : base->getType().getQualifier(); + if (qualifier.storage != EvqShared && qualifier.storage != EvqBuffer && + qualifier.storage != EvqtaskPayloadSharedEXT) + error(loc, errMsg, fnCandidate.getName().c_str(), ""); + } else { + error(loc, errMsg, fnCandidate.getName().c_str(), ""); + } break; } @@ -2462,20 +2609,57 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan case EOpInterpolateAtCentroid: case EOpInterpolateAtSample: case EOpInterpolateAtOffset: - case EOpInterpolateAtVertex: - // Make sure the first argument is an interpolant, or an array element of an interpolant + case EOpInterpolateAtVertex: { if (arg0->getType().getQualifier().storage != EvqVaryingIn) { - // It might still be an array element. + // Traverse down the left branch of arg0 to ensure this argument is a valid interpolant. + // + // For desktop GL >4.3 we effectively only need to ensure that arg0 represents an l-value from an + // input declaration. // - // We could check more, but the semantics of the first argument are already met; the - // only way to turn an array into a float/vec* is array dereference and swizzle. + // For desktop GL <= 4.3 and ES, we must also ensure that swizzling is not used // - // ES and desktop 4.3 and earlier: swizzles may not be used - // desktop 4.4 and later: swizzles may be used - bool swizzleOkay = (!isEsProfile()) && (version >= 440); - const TIntermTyped* base = TIntermediate::findLValueBase(arg0, swizzleOkay); - if (base == nullptr || base->getType().getQualifier().storage != EvqVaryingIn) - error(loc, "first argument must be an interpolant, or interpolant-array element", fnCandidate.getName().c_str(), ""); + // For ES, we must also ensure that a field selection operator (i.e., '.') is not used on a named + // struct. + + const bool esProfile = isEsProfile(); + const bool swizzleOkay = !esProfile && (version >= 440); + + std::string interpolantErrorMsg = "first argument must be an interpolant, or interpolant-array element"; + bool isValid = true; // Assume that the interpolant is valid until we find a condition making it invalid + bool isIn = false; // Checks whether or not the interpolant is a shader input + bool structAccessOp = false; // Whether or not the previous node in the chain is a struct accessor + TIntermediate::traverseLValueBase( + arg0, swizzleOkay, false, + [&isValid, &isIn, &interpolantErrorMsg, esProfile, &structAccessOp](const TIntermNode& n) -> bool { + auto* type = n.getAsTyped(); + if (type) { + if (type->getType().getQualifier().storage == EvqVaryingIn) { + isIn = true; + } + // If a field accessor was used, it can only be used to access a field with an input block, not a struct. + if (structAccessOp && (type->getType().getBasicType() != EbtBlock)) { + interpolantErrorMsg += + ". Using the field of a named struct as an interpolant argument is not " + "allowed (ES-only)."; + isValid = false; + } + } + + // ES has different requirements for interpolants than GL + if (esProfile) { + // Swizzling will be taken care of by the 'swizzleOkay' argument passsed to traverseLValueBase, + // so we only ned to check whether or not a field accessor has been used with a named struct. + auto* binary = n.getAsBinaryNode(); + if (binary && (binary->getOp() == EOpIndexDirectStruct)) { + structAccessOp = true; + } + } + // Don't continue traversing if we know we have an invalid interpolant at this point. + return isValid; + }); + if (!isIn || !isValid) { + error(loc, interpolantErrorMsg.c_str(), fnCandidate.getName().c_str(), ""); + } } if (callNode.getOp() == EOpInterpolateAtVertex) { @@ -2491,10 +2675,12 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } } } - break; + } break; case EOpEmitStreamVertex: case EOpEndStreamPrimitive: + if (version == 150) + requireExtensions(loc, 1, &E_GL_ARB_gpu_shader5, "if the verison is 150 , the EmitStreamVertex and EndStreamPrimitive only support at extension GL_ARB_gpu_shader5"); intermediate.setMultiStream(); break; @@ -2548,7 +2734,7 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } if (profile != EEsProfile && version < 450) { - if ((*argp)[0]->getAsTyped()->getBasicType() != EbtFloat && + if ((*argp)[0]->getAsTyped()->getBasicType() != EbtFloat && (*argp)[0]->getAsTyped()->getBasicType() != EbtDouble && (*argp)[1]->getAsTyped()->getBasicType() != EbtFloat && (*argp)[1]->getAsTyped()->getBasicType() != EbtDouble && @@ -2558,7 +2744,6 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan } break; -#endif default: break; @@ -2597,32 +2782,30 @@ void TParseContext::builtInOpCheck(const TSourceLoc& loc, const TFunction& fnCan // Check that if extended types are being used that the correct extensions are enabled. if (arg0 != nullptr) { const TType& type = arg0->getType(); + bool enhanced = intermediate.getEnhancedMsgs(); switch (type.getBasicType()) { default: break; case EbtInt8: case EbtUint8: - requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int8, type.getCompleteString().c_str()); + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int8, type.getCompleteString(enhanced).c_str()); break; case EbtInt16: case EbtUint16: - requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int16, type.getCompleteString().c_str()); + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int16, type.getCompleteString(enhanced).c_str()); break; case EbtInt64: case EbtUint64: - requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int64, type.getCompleteString().c_str()); + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_int64, type.getCompleteString(enhanced).c_str()); break; case EbtFloat16: - requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_float16, type.getCompleteString().c_str()); + requireExtensions(loc, 1, &E_GL_EXT_shader_subgroup_extended_types_float16, type.getCompleteString(enhanced).c_str()); break; } } } } -#ifndef GLSLANG_WEB - -extern bool PureOperatorBuiltins; // Deprecated! Use PureOperatorBuiltins == true instead, in which case this // functionality is handled in builtInOpCheck() instead of here. @@ -2748,8 +2931,6 @@ void TParseContext::nonOpBuiltInCheck(const TSourceLoc& loc, const TFunction& fn } } -#endif - // // Do any extra checking for a user function call. // @@ -2783,10 +2964,21 @@ TFunction* TParseContext::handleConstructorCall(const TSourceLoc& loc, const TPu profileRequires(loc, EEsProfile, 300, nullptr, "arrayed constructor"); } + // Reuse EOpConstructTextureSampler for bindless image constructor + // uvec2 imgHandle; + // imageLoad(image1D(imgHandle), 0); + if (type.isImage() && extensionTurnedOn(E_GL_ARB_bindless_texture)) + { + intermediate.setBindlessImageMode(currentCaller, AstRefTypeFunc); + } + TOperator op = intermediate.mapTypeToConstructorOp(type); if (op == EOpNull) { - error(loc, "cannot construct this type", type.getBasicString(), ""); + if (intermediate.getEnhancedMsgs() && type.getBasicType() == EbtSampler) + error(loc, "function not supported in this version; use texture() instead", "texture*D*", ""); + else + error(loc, "cannot construct this type", type.getBasicString(), ""); op = EOpConstructFloat; TType errorType(EbtFloat); type.shallowCopy(errorType); @@ -2897,7 +3089,6 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt bool errorReturn = false; switch(binaryNode->getOp()) { -#ifndef GLSLANG_WEB case EOpIndexDirect: case EOpIndexIndirect: // ... tessellation control shader ... @@ -2914,7 +3105,6 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt } } break; // left node is checked by base class -#endif case EOpVectorSwizzle: errorReturn = lValueErrorCheck(loc, op, binaryNode->getLeft()); if (!errorReturn) { @@ -2972,7 +3162,17 @@ bool TParseContext::lValueErrorCheck(const TSourceLoc& loc, const char* op, TInt if (isEsProfile() && intermediate.getEarlyFragmentTests()) message = "can't modify gl_FragDepth if using early_fragment_tests"; break; + case EvqFragStencil: + intermediate.setStencilReplacing(); + // "In addition, it is an error to statically write to gl_FragDepth in the fragment shader." + if (isEsProfile() && intermediate.getEarlyFragmentTests()) + message = "can't modify EvqFragStencil if using early_fragment_tests"; + break; + case EvqtaskPayloadSharedEXT: + if (language == EShLangMesh) + message = "can't modify variable with storage qualifier taskPayloadSharedEXT in mesh shaders"; + break; default: break; } @@ -3011,7 +3211,7 @@ void TParseContext::rValueErrorCheck(const TSourceLoc& loc, const char* op, TInt if (symNode && symNode->getQualifier().isExplicitInterpolation()) error(loc, "can't read from explicitly-interpolated object: ", op, symNode->getName().c_str()); - // local_size_{xyz} must be assigned or specialized before gl_WorkGroupSize can be assigned. + // local_size_{xyz} must be assigned or specialized before gl_WorkGroupSize can be assigned. if(node->getQualifier().builtIn == EbvWorkGroupSize && !(intermediate.isLocalSizeSet() || intermediate.isLocalSizeSpecialized())) error(loc, "can't read from gl_WorkGroupSize before a fixed workgroup size has been declared", op, ""); @@ -3099,7 +3299,7 @@ void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* iden ppWarn(loc, "\"defined\" is (un)defined:", op, identifier); else ppError(loc, "\"defined\" can't be (un)defined:", op, identifier); - else if (strstr(identifier, "__") != 0 && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) { + else if (strstr(identifier, "__") != nullptr && !extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) { // The extension GL_EXT_spirv_intrinsics allows us to declare macros prefixed with "__". if (isEsProfile() && version >= 300 && (strcmp(identifier, "__LINE__") == 0 || @@ -3122,10 +3322,6 @@ void TParseContext::reservedPpErrorCheck(const TSourceLoc& loc, const char* iden // bool TParseContext::lineContinuationCheck(const TSourceLoc& loc, bool endOfComment) { -#ifdef GLSLANG_WEB - return true; -#endif - const char* message = "line continuation"; bool lineContinuationAllowed = (isEsProfile() && version >= 300) || @@ -3182,7 +3378,6 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T // it, in which case the type comes from the argument instead of from the // constructor function. switch (op) { -#ifndef GLSLANG_WEB case EOpConstructNonuniform: if (node != nullptr && node->getAsTyped() != nullptr) { type.shallowCopy(node->getAsTyped()->getType()); @@ -3190,12 +3385,17 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T type.getQualifier().nonUniform = true; } break; -#endif default: type.shallowCopy(function.getType()); break; } + TString constructorString; + if (intermediate.getEnhancedMsgs()) + constructorString.append(type.getCompleteString(true, false, false, true)).append(" constructor"); + else + constructorString.append("constructor"); + // See if it's a matrix bool constructingMatrix = false; switch (op) { @@ -3210,7 +3410,6 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructMat4x2: case EOpConstructMat4x3: case EOpConstructMat4x4: -#ifndef GLSLANG_WEB case EOpConstructDMat2x2: case EOpConstructDMat2x3: case EOpConstructDMat2x4: @@ -3229,7 +3428,6 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructF16Mat4x2: case EOpConstructF16Mat4x3: case EOpConstructF16Mat4x4: -#endif constructingMatrix = true; break; default: @@ -3253,7 +3451,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T if (function[arg].type->isArray()) { if (function[arg].type->isUnsizedArray()) { // Can't construct from an unsized array. - error(loc, "array argument must be sized", "constructor", ""); + error(loc, "array argument must be sized", constructorString.c_str(), ""); return true; } arrayArg = true; @@ -3283,29 +3481,28 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T intArgument = true; if (type.isStruct()) { if (function[arg].type->contains16BitFloat()) { - requireFloat16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type"); + requireFloat16Arithmetic(loc, constructorString.c_str(), "can't construct structure containing 16-bit type"); } if (function[arg].type->contains16BitInt()) { - requireInt16Arithmetic(loc, "constructor", "can't construct structure containing 16-bit type"); + requireInt16Arithmetic(loc, constructorString.c_str(), "can't construct structure containing 16-bit type"); } if (function[arg].type->contains8BitInt()) { - requireInt8Arithmetic(loc, "constructor", "can't construct structure containing 8-bit type"); + requireInt8Arithmetic(loc, constructorString.c_str(), "can't construct structure containing 8-bit type"); } } } if (op == EOpConstructNonuniform) constType = false; -#ifndef GLSLANG_WEB switch (op) { case EOpConstructFloat16: case EOpConstructF16Vec2: case EOpConstructF16Vec3: case EOpConstructF16Vec4: if (type.isArray()) - requireFloat16Arithmetic(loc, "constructor", "16-bit arrays not supported"); + requireFloat16Arithmetic(loc, constructorString.c_str(), "16-bit arrays not supported"); if (type.isVector() && function.getParamCount() != 1) - requireFloat16Arithmetic(loc, "constructor", "16-bit vectors only take vector types"); + requireFloat16Arithmetic(loc, constructorString.c_str(), "16-bit vectors only take vector types"); break; case EOpConstructUint16: case EOpConstructU16Vec2: @@ -3316,9 +3513,9 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructI16Vec3: case EOpConstructI16Vec4: if (type.isArray()) - requireInt16Arithmetic(loc, "constructor", "16-bit arrays not supported"); + requireInt16Arithmetic(loc, constructorString.c_str(), "16-bit arrays not supported"); if (type.isVector() && function.getParamCount() != 1) - requireInt16Arithmetic(loc, "constructor", "16-bit vectors only take vector types"); + requireInt16Arithmetic(loc, constructorString.c_str(), "16-bit vectors only take vector types"); break; case EOpConstructUint8: case EOpConstructU8Vec2: @@ -3329,14 +3526,13 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructI8Vec3: case EOpConstructI8Vec4: if (type.isArray()) - requireInt8Arithmetic(loc, "constructor", "8-bit arrays not supported"); + requireInt8Arithmetic(loc, constructorString.c_str(), "8-bit arrays not supported"); if (type.isVector() && function.getParamCount() != 1) - requireInt8Arithmetic(loc, "constructor", "8-bit vectors only take vector types"); + requireInt8Arithmetic(loc, constructorString.c_str(), "8-bit vectors only take vector types"); break; default: break; } -#endif // inherit constness from children if (constType) { @@ -3357,7 +3553,6 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructUVec2: case EOpConstructUVec3: case EOpConstructUVec4: -#ifndef GLSLANG_WEB case EOpConstructUint8: case EOpConstructInt16: case EOpConstructUint16: @@ -3381,7 +3576,6 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T case EOpConstructU64Vec2: case EOpConstructU64Vec3: case EOpConstructU64Vec4: -#endif // This was the list of valid ones, if they aren't converting from float // and aren't making an array. makeSpecConst = ! floatArgument && ! type.isArray(); @@ -3413,7 +3607,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T if (type.isArray()) { if (function.getParamCount() == 0) { - error(loc, "array constructor must have at least one argument", "constructor", ""); + error(loc, "array constructor must have at least one argument", constructorString.c_str(), ""); return true; } @@ -3421,7 +3615,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T // auto adapt the constructor type to the number of arguments type.changeOuterArraySize(function.getParamCount()); } else if (type.getOuterArraySize() != function.getParamCount()) { - error(loc, "array constructor needs one argument per array element", "constructor", ""); + error(loc, "array constructor needs one argument per array element", constructorString.c_str(), ""); return true; } @@ -3434,7 +3628,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T // At least the dimensionalities have to match. if (! function[0].type->isArray() || arraySizes.getNumDims() != function[0].type->getArraySizes()->getNumDims() + 1) { - error(loc, "array constructor argument not correct type to construct array element", "constructor", ""); + error(loc, "array constructor argument not correct type to construct array element", constructorString.c_str(), ""); return true; } @@ -3451,7 +3645,7 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T } if (arrayArg && op != EOpConstructStruct && ! type.isArrayOfArrays()) { - error(loc, "constructing non-array constituent from array argument", "constructor", ""); + error(loc, "constructing non-array constituent from array argument", constructorString.c_str(), ""); return true; } @@ -3461,51 +3655,62 @@ bool TParseContext::constructorError(const TSourceLoc& loc, TIntermNode* node, T // "If a matrix argument is given to a matrix constructor, // it is a compile-time error to have any other arguments." if (function.getParamCount() != 1) - error(loc, "matrix constructed from matrix can only have one argument", "constructor", ""); + error(loc, "matrix constructed from matrix can only have one argument", constructorString.c_str(), ""); return false; } if (overFull) { - error(loc, "too many arguments", "constructor", ""); + error(loc, "too many arguments", constructorString.c_str(), ""); return true; } if (op == EOpConstructStruct && ! type.isArray() && (int)type.getStruct()->size() != function.getParamCount()) { - error(loc, "Number of constructor parameters does not match the number of structure fields", "constructor", ""); + error(loc, "Number of constructor parameters does not match the number of structure fields", constructorString.c_str(), ""); return true; } if ((op != EOpConstructStruct && size != 1 && size < type.computeNumComponents()) || (op == EOpConstructStruct && size < type.computeNumComponents())) { - error(loc, "not enough data provided for construction", "constructor", ""); + error(loc, "not enough data provided for construction", constructorString.c_str(), ""); return true; } if (type.isCoopMat() && function.getParamCount() != 1) { - error(loc, "wrong number of arguments", "constructor", ""); + error(loc, "wrong number of arguments", constructorString.c_str(), ""); return true; } if (type.isCoopMat() && !(function[0].type->isScalar() || function[0].type->isCoopMat())) { - error(loc, "Cooperative matrix constructor argument must be scalar or cooperative matrix", "constructor", ""); + error(loc, "Cooperative matrix constructor argument must be scalar or cooperative matrix", constructorString.c_str(), ""); return true; } TIntermTyped* typed = node->getAsTyped(); + if (type.isCoopMat() && typed->getType().isCoopMat() && + !type.sameCoopMatShapeAndUse(typed->getType())) { + error(loc, "Cooperative matrix type parameters mismatch", constructorString.c_str(), ""); + return true; + } + if (typed == nullptr) { - error(loc, "constructor argument does not have a type", "constructor", ""); + error(loc, "constructor argument does not have a type", constructorString.c_str(), ""); return true; } if (op != EOpConstructStruct && op != EOpConstructNonuniform && typed->getBasicType() == EbtSampler) { - error(loc, "cannot convert a sampler", "constructor", ""); - return true; + if (op == EOpConstructUVec2 && extensionTurnedOn(E_GL_ARB_bindless_texture)) { + intermediate.setBindlessTextureMode(currentCaller, AstRefTypeFunc); + } + else { + error(loc, "cannot convert a sampler", constructorString.c_str(), ""); + return true; + } } if (op != EOpConstructStruct && typed->isAtomic()) { - error(loc, "cannot convert an atomic_uint", "constructor", ""); + error(loc, "cannot convert an atomic_uint", constructorString.c_str(), ""); return true; } if (typed->getBasicType() == EbtVoid) { - error(loc, "cannot convert a void", "constructor", ""); + error(loc, "cannot convert a void", constructorString.c_str(), ""); return true; } @@ -3518,6 +3723,26 @@ bool TParseContext::constructorTextureSamplerError(const TSourceLoc& loc, const { TString constructorName = function.getType().getBasicTypeString(); // TODO: performance: should not be making copy; interface needs to change const char* token = constructorName.c_str(); + // verify the constructor for bindless texture, the input must be ivec2 or uvec2 + if (function.getParamCount() == 1) { + TType* pType = function[0].type; + TBasicType basicType = pType->getBasicType(); + bool isIntegerVec2 = ((basicType == EbtUint || basicType == EbtInt) && pType->getVectorSize() == 2); + bool bindlessMode = extensionTurnedOn(E_GL_ARB_bindless_texture); + if (isIntegerVec2 && bindlessMode) { + if (pType->getSampler().isImage()) + intermediate.setBindlessImageMode(currentCaller, AstRefTypeFunc); + else + intermediate.setBindlessTextureMode(currentCaller, AstRefTypeFunc); + return false; + } else { + if (!bindlessMode) + error(loc, "sampler-constructor requires the extension GL_ARB_bindless_texture enabled", token, ""); + else + error(loc, "sampler-constructor requires the input to be ivec2 or uvec2", token, ""); + return true; + } + } // exactly two arguments needed if (function.getParamCount() != 2) { @@ -3613,18 +3838,38 @@ void TParseContext::samplerCheck(const TSourceLoc& loc, const TType& type, const if (type.getQualifier().storage == EvqUniform) return; - if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtSampler)) - error(loc, "non-uniform struct contains a sampler or image:", type.getBasicTypeString().c_str(), identifier.c_str()); + if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtSampler)) { + // For bindless texture, sampler can be declared as an struct member + if (extensionTurnedOn(E_GL_ARB_bindless_texture)) { + if (type.getSampler().isImage()) + intermediate.setBindlessImageMode(currentCaller, AstRefTypeVar); + else + intermediate.setBindlessTextureMode(currentCaller, AstRefTypeVar); + } + else { + error(loc, "non-uniform struct contains a sampler or image:", type.getBasicTypeString().c_str(), identifier.c_str()); + } + } else if (type.getBasicType() == EbtSampler && type.getQualifier().storage != EvqUniform) { - // non-uniform sampler - // not yet: okay if it has an initializer - // if (! initializer) - error(loc, "sampler/image types can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str()); + // For bindless texture, sampler can be declared as an input/output/block member + if (extensionTurnedOn(E_GL_ARB_bindless_texture)) { + if (type.getSampler().isImage()) + intermediate.setBindlessImageMode(currentCaller, AstRefTypeVar); + else + intermediate.setBindlessTextureMode(currentCaller, AstRefTypeVar); + } + else { + // non-uniform sampler + // not yet: okay if it has an initializer + // if (! initializer) + if (type.getSampler().isAttachmentEXT() && type.getQualifier().storage != EvqTileImageEXT) + error(loc, "can only be used in tileImageEXT variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str()); + else if (type.getQualifier().storage != EvqTileImageEXT) + error(loc, "sampler/image types can only be used in uniform variables or function parameters:", type.getBasicTypeString().c_str(), identifier.c_str()); + } } } -#ifndef GLSLANG_WEB - void TParseContext::atomicUintCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) { if (type.getQualifier().storage == EvqUniform) @@ -3649,8 +3894,6 @@ void TParseContext::accStructCheck(const TSourceLoc& loc, const TType& type, con } -#endif // GLSLANG_WEB - void TParseContext::transparentOpaqueCheck(const TSourceLoc& loc, const TType& type, const TString& identifier) { if (parsingBuiltins) @@ -3685,7 +3928,7 @@ void TParseContext::memberQualifierCheck(glslang::TPublicType& publicType) // // Check/fix just a full qualifier (no variables or types yet, but qualifier is complete) at global level. // -void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier, bool isMemberCheck) +void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& qualifier, bool isMemberCheck, const TPublicType* publicType) { bool nonuniformOkay = false; @@ -3721,6 +3964,11 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q { requireExtensions(loc, 1, &E_GL_EXT_scalar_block_layout, "default std430 layout for uniform"); } + + if (publicType != nullptr && publicType->isImage() && + (qualifier.layoutFormat > ElfExtSizeGuard && qualifier.layoutFormat < ElfCount)) + qualifier.layoutFormat = mapLegacyLayoutFormat(qualifier.layoutFormat, publicType->sampler.getBasicType()); + break; default: break; @@ -3729,13 +3977,11 @@ void TParseContext::globalQualifierFixCheck(const TSourceLoc& loc, TQualifier& q if (!nonuniformOkay && qualifier.isNonUniform()) error(loc, "for non-parameter, can only apply to 'in' or no storage qualifier", "nonuniformEXT", ""); -#ifndef GLSLANG_WEB if (qualifier.isSpirvByReference()) error(loc, "can only apply to parameter", "spirv_by_reference", ""); if (qualifier.isSpirvLiteral()) error(loc, "can only apply to parameter", "spirv_literal", ""); -#endif // Storage qualifier isn't ready for memberQualifierCheck, we should skip invariantCheck for it. if (!isMemberCheck || structNestingLevel > 0) @@ -3781,10 +4027,12 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali return; } - if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble) - profileRequires(loc, EEsProfile, 300, nullptr, "shader input/output"); + if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble) { + profileRequires(loc, EEsProfile, 300, nullptr, "non-float shader input/output"); + profileRequires(loc, ~EEsProfile, 130, nullptr, "non-float shader input/output"); + } - if (!qualifier.flat && !qualifier.isExplicitInterpolation() && !qualifier.isPervertexNV()) { + if (!qualifier.flat && !qualifier.isExplicitInterpolation() && !qualifier.isPervertexNV() && !qualifier.isPervertexEXT()) { if (isTypeInt(publicType.basicType) || publicType.basicType == EbtDouble || (publicType.userDef && ( publicType.userDef->containsBasicType(EbtInt) @@ -3803,6 +4051,9 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali if (qualifier.isPatch() && qualifier.isInterpolation()) error(loc, "cannot use interpolation qualifiers with patch", "patch", ""); + if (qualifier.isTaskPayload() && publicType.basicType == EbtBlock) + error(loc, "taskPayloadSharedEXT variables should not be declared as interface blocks", "taskPayloadSharedEXT", ""); + if (qualifier.isTaskMemory() && publicType.basicType != EbtBlock) error(loc, "taskNV variables can be declared only as blocks", "taskNV", ""); @@ -3810,7 +4061,7 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali switch (language) { case EShLangVertex: if (publicType.basicType == EbtStruct) { - error(loc, "cannot be a structure or array", GetStorageQualifierString(qualifier.storage), ""); + error(loc, "cannot be a structure", GetStorageQualifierString(qualifier.storage), ""); return; } if (publicType.arraySizes) { @@ -3836,12 +4087,10 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali if (! symbolTable.atBuiltInLevel()) error(loc, "global storage input qualifier cannot be used in a compute shader", "in", ""); break; -#ifndef GLSLANG_WEB case EShLangTessControl: if (qualifier.patch) error(loc, "can only use on output in tessellation-control shader", "patch", ""); break; -#endif default: break; } @@ -3880,12 +4129,10 @@ void TParseContext::globalQualifierTypeCheck(const TSourceLoc& loc, const TQuali case EShLangCompute: error(loc, "global storage output qualifier cannot be used in a compute shader", "out", ""); break; -#ifndef GLSLANG_WEB case EShLangTessEvaluation: if (qualifier.patch) error(loc, "can only use on input in tessellation-evaluation shader", "patch", ""); break; -#endif default: break; } @@ -3953,17 +4200,16 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons if (dst.precision == EpqNone || (force && src.precision != EpqNone)) dst.precision = src.precision; -#ifndef GLSLANG_WEB if (!force && ((src.coherent && (dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) || (src.devicecoherent && (dst.coherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) || (src.queuefamilycoherent && (dst.coherent || dst.devicecoherent || dst.workgroupcoherent || dst.subgroupcoherent || dst.shadercallcoherent)) || (src.workgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.subgroupcoherent || dst.shadercallcoherent)) || (src.subgroupcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.shadercallcoherent)) || (src.shadercallcoherent && (dst.coherent || dst.devicecoherent || dst.queuefamilycoherent || dst.workgroupcoherent || dst.subgroupcoherent)))) { - error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent/shadercallcoherent qualifier allowed", + error(loc, "only one coherent/devicecoherent/queuefamilycoherent/workgroupcoherent/subgroupcoherent/shadercallcoherent qualifier allowed", GetPrecisionQualifierString(src.precision), ""); } -#endif + // Layout qualifiers mergeObjectLayoutQualifiers(dst, src, false); @@ -3975,7 +4221,6 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons MERGE_SINGLETON(smooth); MERGE_SINGLETON(flat); MERGE_SINGLETON(specConstant); -#ifndef GLSLANG_WEB MERGE_SINGLETON(noContraction); MERGE_SINGLETON(nopersp); MERGE_SINGLETON(explicitInterp); @@ -3996,15 +4241,13 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons MERGE_SINGLETON(readonly); MERGE_SINGLETON(writeonly); MERGE_SINGLETON(nonUniform); -#endif -#ifndef GLSLANG_WEB // SPIR-V storage class qualifier (GL_EXT_spirv_intrinsics) dst.spirvStorageClass = src.spirvStorageClass; // SPIR-V decorate qualifiers (GL_EXT_spirv_intrinsics) - if (src.hasSprivDecorate()) { - if (dst.hasSprivDecorate()) { + if (src.hasSpirvDecorate()) { + if (dst.hasSpirvDecorate()) { const TSpirvDecorate& srcSpirvDecorate = src.getSpirvDecorate(); TSpirvDecorate& dstSpirvDecorate = dst.getSpirvDecorate(); for (auto& decorate : srcSpirvDecorate.decorates) { @@ -4025,13 +4268,12 @@ void TParseContext::mergeQualifiers(const TSourceLoc& loc, TQualifier& dst, cons if (dstSpirvDecorate.decorates.find(decorateString.first) != dstSpirvDecorate.decorates.end()) error(loc, "too many SPIR-V decorate qualifiers", "spirv_decorate_string", "(decoration=%u)", decorateString.first); else - dstSpirvDecorate.decorates.insert(decorateString); + dstSpirvDecorate.decorateStrings.insert(decorateString); } } else { dst.spirvDecorate = src.spirvDecorate; } } -#endif if (repeated) error(loc, "replicated qualifiers", "", ""); @@ -4095,17 +4337,18 @@ TPrecisionQualifier TParseContext::getDefaultPrecision(TPublicType& publicType) return defaultPrecision[publicType.basicType]; } -void TParseContext::precisionQualifierCheck(const TSourceLoc& loc, TBasicType baseType, TQualifier& qualifier) +void TParseContext::precisionQualifierCheck(const TSourceLoc& loc, TBasicType baseType, TQualifier& qualifier, bool isCoopMat) { // Built-in symbols are allowed some ambiguous precisions, to be pinned down // later by context. if (! obeyPrecisionQualifiers() || parsingBuiltins) return; -#ifndef GLSLANG_WEB if (baseType == EbtAtomicUint && qualifier.precision != EpqNone && qualifier.precision != EpqHigh) error(loc, "atomic counters can only be highp", "atomic_uint", ""); -#endif + + if (isCoopMat) + return; if (baseType == EbtFloat || baseType == EbtUint || baseType == EbtInt || baseType == EbtSampler || baseType == EbtAtomicUint) { if (qualifier.precision == EpqNone) { @@ -4122,7 +4365,7 @@ void TParseContext::precisionQualifierCheck(const TSourceLoc& loc, TBasicType ba void TParseContext::parameterTypeCheck(const TSourceLoc& loc, TStorageQualifier qualifier, const TType& type) { - if ((qualifier == EvqOut || qualifier == EvqInOut) && type.isOpaque()) + if ((qualifier == EvqOut || qualifier == EvqInOut) && type.isOpaque() && !intermediate.getBindlessMode()) error(loc, "samplers and atomic_uints cannot be output parameters", type.getBasicTypeString().c_str(), ""); if (!parsingBuiltins && type.contains16BitFloat()) requireFloat16Arithmetic(loc, type.getBasicTypeString().c_str(), "float16 types can only be in uniform block or buffer storage"); @@ -4151,7 +4394,8 @@ bool TParseContext::containsFieldWithBasicType(const TType& type, TBasicType bas // // Do size checking for an array type's size. // -void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TArraySize& sizePair, const char *sizeType) +void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TArraySize& sizePair, + const char* sizeType, const bool allowZero) { bool isConst = false; sizePair.node = nullptr; @@ -4171,9 +4415,8 @@ void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TA TIntermSymbol* symbol = expr->getAsSymbolNode(); if (symbol && symbol->getConstArray().size() > 0) size = symbol->getConstArray()[0].getIConst(); - } else if (expr->getAsUnaryNode() && - expr->getAsUnaryNode()->getOp() == glslang::EOpArrayLength && - expr->getAsUnaryNode()->getOperand()->getType().isCoopMat()) { + } else if (expr->getAsUnaryNode() && expr->getAsUnaryNode()->getOp() == glslang::EOpArrayLength && + expr->getAsUnaryNode()->getOperand()->getType().isCoopMatNV()) { isConst = true; size = 1; sizePair.node = expr->getAsUnaryNode(); @@ -4187,9 +4430,16 @@ void TParseContext::arraySizeCheck(const TSourceLoc& loc, TIntermTyped* expr, TA return; } - if (size <= 0) { - error(loc, sizeType, "", "must be a positive integer"); - return; + if (allowZero) { + if (size < 0) { + error(loc, sizeType, "", "must be a non-negative integer"); + return; + } + } else { + if (size <= 0) { + error(loc, sizeType, "", "must be a positive integer"); + return; + } } } @@ -4287,8 +4537,6 @@ void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qua (qualifier.storage != EvqTemporary && qualifier.storage != EvqGlobal && qualifier.storage != EvqShared && qualifier.storage != EvqConst)) error(loc, "only outermost dimension of an array of arrays can be a specialization constant", "[]", ""); -#ifndef GLSLANG_WEB - // desktop always allows outer-dimension-unsized variable arrays, if (!isEsProfile()) return; @@ -4318,18 +4566,16 @@ void TParseContext::arraySizesCheck(const TSourceLoc& loc, const TQualifier& qua extensionsTurnedOn(Num_AEP_tessellation_shader, AEP_tessellation_shader)) return; break; - case EShLangMeshNV: + case EShLangMesh: if (qualifier.storage == EvqVaryingOut) if ((isEsProfile() && version >= 320) || - extensionTurnedOn(E_GL_NV_mesh_shader)) + extensionsTurnedOn(Num_AEP_mesh_shader, AEP_mesh_shader)) return; break; default: break; } -#endif - // last member of ssbo block exception: if (qualifier.storage == EvqBuffer && lastMember) return; @@ -4374,7 +4620,6 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie if (symbolTable.atGlobalLevel()) trackLinkage(*symbol); -#ifndef GLSLANG_WEB if (! symbolTable.atBuiltInLevel()) { if (isIoResizeArray(type)) { ioArraySymbolResizeList.push_back(symbol); @@ -4382,7 +4627,6 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie } else fixIoArraySize(loc, symbol->getWritableType()); } -#endif return; } @@ -4420,7 +4664,6 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie return; } -#ifndef GLSLANG_WEB if (existingType.isSizedArray()) { // be more leniant for input arrays to geometry shaders and tessellation control outputs, where the redeclaration is the same size if (! (isIoResizeArray(type) && existingType.getOuterArraySize() == type.getOuterArraySize())) @@ -4434,11 +4677,8 @@ void TParseContext::declareArray(const TSourceLoc& loc, const TString& identifie if (isIoResizeArray(type)) checkIoArraysConsistency(loc); -#endif } -#ifndef GLSLANG_WEB - // Policy and error check for needing a runtime sized array. void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermTyped& base) { @@ -4466,7 +4706,7 @@ void TParseContext::checkRuntimeSizable(const TSourceLoc& loc, const TIntermType // check for additional things allowed by GL_EXT_nonuniform_qualifier if (base.getBasicType() == EbtSampler || base.getBasicType() == EbtAccStruct || base.getBasicType() == EbtRayQuery || - (base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer())) + base.getBasicType() == EbtHitObjectNV || (base.getBasicType() == EbtBlock && base.getType().getQualifier().isUniformOrBuffer())) requireExtensions(loc, 1, &E_GL_EXT_nonuniform_qualifier, "variable index"); else error(loc, "", "[", "array must be redeclared with a size before being indexed with a variable"); @@ -4521,8 +4761,6 @@ void TParseContext::checkAndResizeMeshViewDim(const TSourceLoc& loc, TType& type } } -#endif // GLSLANG_WEB - // Returns true if the first argument to the #line directive is the line number for the next line. // // Desktop, pre-version 3.30: "After processing this directive @@ -4565,7 +4803,6 @@ void TParseContext::nonInitConstCheck(const TSourceLoc& loc, TString& identifier TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TString& identifier, const TQualifier& qualifier, const TShaderQualifiers& publicType) { -#ifndef GLSLANG_WEB if (! builtInName(identifier) || symbolTable.atBuiltInLevel() || ! symbolTable.atGlobalLevel()) return nullptr; @@ -4589,7 +4826,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS if (ssoPre150 || (identifier == "gl_FragDepth" && ((nonEsRedecls && version >= 420) || esRedecls)) || - (identifier == "gl_FragCoord" && ((nonEsRedecls && version >= 150) || esRedecls)) || + (identifier == "gl_FragCoord" && ((nonEsRedecls && version >= 140) || esRedecls)) || identifier == "gl_ClipDistance" || identifier == "gl_CullDistance" || identifier == "gl_ShadingRateEXT" || @@ -4605,6 +4842,9 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS identifier == "gl_SampleMask" || identifier == "gl_Layer" || identifier == "gl_PrimitiveIndicesNV" || + identifier == "gl_PrimitivePointIndicesEXT" || + identifier == "gl_PrimitiveLineIndicesEXT" || + identifier == "gl_PrimitiveTriangleIndicesEXT" || identifier == "gl_TexCoord") { // Find the existing symbol, if any. @@ -4658,7 +4898,7 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS symbolQualifier.storage != qualifier.storage) error(loc, "cannot change qualification of", "redeclaration", symbol->getName().c_str()); } else if (identifier == "gl_FragCoord") { - if (intermediate.inIoAccessed("gl_FragCoord")) + if (!intermediate.getTexCoordRedeclared() && intermediate.inIoAccessed("gl_FragCoord")) error(loc, "cannot redeclare after use", "gl_FragCoord", ""); if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat || qualifier.isMemory() || qualifier.isAuxiliary()) @@ -4668,6 +4908,9 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS if (! builtIn && (publicType.pixelCenterInteger != intermediate.getPixelCenterInteger() || publicType.originUpperLeft != intermediate.getOriginUpperLeft())) error(loc, "cannot redeclare with different qualification:", "redeclaration", symbol->getName().c_str()); + + + intermediate.setTexCoordRedeclared(); if (publicType.pixelCenterInteger) intermediate.setPixelCenterInteger(); if (publicType.originUpperLeft) @@ -4684,10 +4927,22 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS if (! intermediate.setDepth(publicType.layoutDepth)) error(loc, "all redeclarations must use the same depth layout on", "redeclaration", symbol->getName().c_str()); } + } else if (identifier == "gl_FragStencilRefARB") { + if (qualifier.nopersp != symbolQualifier.nopersp || qualifier.flat != symbolQualifier.flat || + qualifier.isMemory() || qualifier.isAuxiliary()) + error(loc, "can only change layout qualification of", "redeclaration", symbol->getName().c_str()); + if (qualifier.storage != EvqVaryingOut) + error(loc, "cannot change output storage qualification of", "redeclaration", symbol->getName().c_str()); + if (publicType.layoutStencil != ElsNone) { + if (intermediate.inIoAccessed("gl_FragStencilRefARB")) + error(loc, "cannot redeclare after use", "gl_FragStencilRefARB", ""); + if (!intermediate.setStencil(publicType.layoutStencil)) + error(loc, "all redeclarations must use the same stencil layout on", "redeclaration", + symbol->getName().c_str()); + } } else if ( - identifier == "gl_PrimitiveIndicesNV" || - identifier == "gl_FragStencilRefARB") { + identifier == "gl_PrimitiveIndicesNV") { if (qualifier.hasLayout()) error(loc, "cannot apply layout qualifier to", "redeclaration", symbol->getName().c_str()); if (qualifier.storage != EvqVaryingOut) @@ -4710,7 +4965,6 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS return symbol; } -#endif return nullptr; } @@ -4722,13 +4976,13 @@ TSymbol* TParseContext::redeclareBuiltinVariable(const TSourceLoc& loc, const TS void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newTypeList, const TString& blockName, const TString* instanceName, TArraySizes* arraySizes) { -#ifndef GLSLANG_WEB const char* feature = "built-in block redeclaration"; profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature); profileRequires(loc, ~EEsProfile, 410, E_GL_ARB_separate_shader_objects, feature); if (blockName != "gl_PerVertex" && blockName != "gl_PerFragment" && - blockName != "gl_MeshPerVertexNV" && blockName != "gl_MeshPerPrimitiveNV") { + blockName != "gl_MeshPerVertexNV" && blockName != "gl_MeshPerPrimitiveNV" && + blockName != "gl_MeshPerVertexEXT" && blockName != "gl_MeshPerPrimitiveEXT") { error(loc, "cannot redeclare block: ", "block declaration", blockName.c_str()); return; } @@ -4937,7 +5191,6 @@ void TParseContext::redeclareBuiltinBlock(const TSourceLoc& loc, TTypeList& newT // Save it in the AST for linker use. trackLinkage(*block); -#endif // GLSLANG_WEB } void TParseContext::paramCheckFixStorage(const TSourceLoc& loc, const TStorageQualifier& qualifier, TType& type) @@ -4950,6 +5203,7 @@ void TParseContext::paramCheckFixStorage(const TSourceLoc& loc, const TStorageQu case EvqIn: case EvqOut: case EvqInOut: + case EvqTileImageEXT: type.getQualifier().storage = qualifier; break; case EvqGlobal: @@ -4965,7 +5219,6 @@ void TParseContext::paramCheckFixStorage(const TSourceLoc& loc, const TStorageQu void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& qualifier, TType& type) { -#ifndef GLSLANG_WEB if (qualifier.isMemory()) { type.getQualifier().volatil = qualifier.volatil; type.getQualifier().coherent = qualifier.coherent; @@ -4979,7 +5232,6 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali type.getQualifier().writeonly = qualifier.writeonly; type.getQualifier().restrict = qualifier.restrict; } -#endif if (qualifier.isAuxiliary() || qualifier.isInterpolation()) @@ -4996,7 +5248,6 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali } if (qualifier.isNonUniform()) type.getQualifier().nonUniform = qualifier.nonUniform; -#ifndef GLSLANG_WEB if (qualifier.isSpirvByReference()) type.getQualifier().setSpirvByReference(); if (qualifier.isSpirvLiteral()) { @@ -5005,7 +5256,6 @@ void TParseContext::paramCheckFix(const TSourceLoc& loc, const TQualifier& quali type.getQualifier().setSpirvLiteral(); else error(loc, "cannot use spirv_literal qualifier", type.getBasicTypeString().c_str(), ""); -#endif } paramCheckFixStorage(loc, qualifier.storage, type); @@ -5036,21 +5286,18 @@ void TParseContext::arrayObjectCheck(const TSourceLoc& loc, const TType& type, c void TParseContext::opaqueCheck(const TSourceLoc& loc, const TType& type, const char* op) { - if (containsFieldWithBasicType(type, EbtSampler)) + if (containsFieldWithBasicType(type, EbtSampler) && !extensionTurnedOn(E_GL_ARB_bindless_texture)) error(loc, "can't use with samplers or structs containing samplers", op, ""); } void TParseContext::referenceCheck(const TSourceLoc& loc, const TType& type, const char* op) { -#ifndef GLSLANG_WEB if (containsFieldWithBasicType(type, EbtReference)) error(loc, "can't use with reference types", op, ""); -#endif } void TParseContext::storage16BitAssignmentCheck(const TSourceLoc& loc, const TType& type, const char* op) { -#ifndef GLSLANG_WEB if (type.getBasicType() == EbtStruct && containsFieldWithBasicType(type, EbtFloat16)) requireFloat16Arithmetic(loc, op, "can't use with structs containing float16"); @@ -5080,7 +5327,6 @@ void TParseContext::storage16BitAssignmentCheck(const TSourceLoc& loc, const TTy if (type.isArray() && type.getBasicType() == EbtUint8) requireInt8Arithmetic(loc, op, "can't use with arrays containing uint8"); -#endif } void TParseContext::specializationCheck(const TSourceLoc& loc, const TType& type, const char* op) @@ -5132,12 +5378,11 @@ void TParseContext::structTypeCheck(const TSourceLoc& /*loc*/, TPublicType& publ // void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, TIntermLoop* loop) { -#ifndef GLSLANG_WEB // loop index init must exist and be a declaration, which shows up in the AST as an aggregate of size 1 of the declaration bool badInit = false; if (! init || ! init->getAsAggregate() || init->getAsAggregate()->getSequence().size() != 1) badInit = true; - TIntermBinary* binaryInit = 0; + TIntermBinary* binaryInit = nullptr; if (! badInit) { // get the declaration assignment binaryInit = init->getAsAggregate()->getSequence()[0]->getAsBinaryNode(); @@ -5228,10 +5473,8 @@ void TParseContext::inductiveLoopCheck(const TSourceLoc& loc, TIntermNode* init, // the body inductiveLoopBodyCheck(loop->getBody(), loopIndex, symbolTable); -#endif } -#ifndef GLSLANG_WEB // Do limit checks for built-in arrays. void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identifier, int size) { @@ -5246,7 +5489,6 @@ void TParseContext::arrayLimitCheck(const TSourceLoc& loc, const TString& identi else if (identifier.compare("gl_CullDistancePerViewNV") == 0) limitCheck(loc, size, "gl_MaxCullDistances", "gl_CullDistancePerViewNV array size"); } -#endif // GLSLANG_WEB // See if the provided value is less than or equal to the symbol indicated by limit, // which should be a constant in the symbol table. @@ -5260,8 +5502,6 @@ void TParseContext::limitCheck(const TSourceLoc& loc, int value, const char* lim error(loc, "must be less than or equal to", feature, "%s (%d)", limit, constArray[0].getIConst()); } -#ifndef GLSLANG_WEB - // // Do any additional error checking, etc., once we know the parsing is done. // @@ -5297,11 +5537,11 @@ void TParseContext::finish() if (!isEsProfile() && version < 430) requireExtensions(getCurrentLoc(), 1, &E_GL_ARB_compute_shader, "compute shaders"); break; - case EShLangTaskNV: - requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "task shaders"); + case EShLangTask: + requireExtensions(getCurrentLoc(), Num_AEP_mesh_shader, AEP_mesh_shader, "task shaders"); break; - case EShLangMeshNV: - requireExtensions(getCurrentLoc(), 1, &E_GL_NV_mesh_shader, "mesh shaders"); + case EShLangMesh: + requireExtensions(getCurrentLoc(), Num_AEP_mesh_shader, AEP_mesh_shader, "mesh shaders"); break; default: break; @@ -5327,7 +5567,6 @@ void TParseContext::finish() } } } -#endif // GLSLANG_WEB // // Layout qualifier stuff. @@ -5371,7 +5610,6 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.qualifier.layoutPacking = ElpStd140; return; } -#ifndef GLSLANG_WEB if (id == TQualifier::getLayoutPackingString(ElpStd430)) { requireProfile(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, "std430"); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_shader_storage_buffer_object, "std430"); @@ -5411,12 +5649,34 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi intermediate.setUsePhysicalStorageBuffer(); return; } - if (language == EShLangGeometry || language == EShLangTessEvaluation || language == EShLangMeshNV) { + if (id == "bindless_sampler") { + requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "bindless_sampler"); + publicType.qualifier.layoutBindlessSampler = true; + intermediate.setBindlessTextureMode(currentCaller, AstRefTypeLayout); + return; + } + if (id == "bindless_image") { + requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "bindless_image"); + publicType.qualifier.layoutBindlessImage = true; + intermediate.setBindlessImageMode(currentCaller, AstRefTypeLayout); + return; + } + if (id == "bound_sampler") { + requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "bound_sampler"); + publicType.qualifier.layoutBindlessSampler = false; + return; + } + if (id == "bound_image") { + requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "bound_image"); + publicType.qualifier.layoutBindlessImage = false; + return; + } + if (language == EShLangGeometry || language == EShLangTessEvaluation || language == EShLangMesh) { if (id == TQualifier::getGeometryString(ElgTriangles)) { publicType.shaderQualifiers.geometry = ElgTriangles; return; } - if (language == EShLangGeometry || language == EShLangMeshNV) { + if (language == EShLangGeometry || language == EShLangMesh) { if (id == TQualifier::getGeometryString(ElgPoints)) { publicType.shaderQualifiers.geometry = ElgPoints; return; @@ -5499,12 +5759,19 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi } if (language == EShLangFragment) { if (id == "origin_upper_left") { - requireProfile(loc, ECoreProfile | ECompatibilityProfile, "origin_upper_left"); + requireProfile(loc, ECoreProfile | ECompatibilityProfile | ENoProfile, "origin_upper_left"); + if (profile == ENoProfile) { + profileRequires(loc,ECoreProfile | ECompatibilityProfile, 140, E_GL_ARB_fragment_coord_conventions, "origin_upper_left"); + } + publicType.shaderQualifiers.originUpperLeft = true; return; } if (id == "pixel_center_integer") { - requireProfile(loc, ECoreProfile | ECompatibilityProfile, "pixel_center_integer"); + requireProfile(loc, ECoreProfile | ECompatibilityProfile | ENoProfile, "pixel_center_integer"); + if (profile == ENoProfile) { + profileRequires(loc,ECoreProfile | ECompatibilityProfile, 140, E_GL_ARB_fragment_coord_conventions, "pixel_center_integer"); + } publicType.shaderQualifiers.pixelCenterInteger = true; return; } @@ -5514,6 +5781,12 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.shaderQualifiers.earlyFragmentTests = true; return; } + if (id == "early_and_late_fragment_tests_amd") { + profileRequires(loc, ENoProfile | ECoreProfile | ECompatibilityProfile, 420, E_GL_AMD_shader_early_and_late_fragment_tests, "early_and_late_fragment_tests_amd"); + profileRequires(loc, EEsProfile, 310, nullptr, "early_and_late_fragment_tests_amd"); + publicType.shaderQualifiers.earlyAndLateFragmentTestsAMD = true; + return; + } if (id == "post_depth_coverage") { requireExtensions(loc, Num_post_depth_coverageEXTs, post_depth_coverageEXTs, "post depth coverage"); if (extensionTurnedOn(E_GL_ARB_post_depth_coverage)) { @@ -5522,6 +5795,22 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.shaderQualifiers.postDepthCoverage = true; return; } + /* id is transformed into lower case in the beginning of this function. */ + if (id == "non_coherent_color_attachment_readext") { + requireExtensions(loc, 1, &E_GL_EXT_shader_tile_image, "non_coherent_color_attachment_readEXT"); + publicType.shaderQualifiers.nonCoherentColorAttachmentReadEXT = true; + return; + } + if (id == "non_coherent_depth_attachment_readext") { + requireExtensions(loc, 1, &E_GL_EXT_shader_tile_image, "non_coherent_depth_attachment_readEXT"); + publicType.shaderQualifiers.nonCoherentDepthAttachmentReadEXT = true; + return; + } + if (id == "non_coherent_stencil_attachment_readext") { + requireExtensions(loc, 1, &E_GL_EXT_shader_tile_image, "non_coherent_stencil_attachment_readEXT"); + publicType.shaderQualifiers.nonCoherentStencilAttachmentReadEXT = true; + return; + } for (TLayoutDepth depth = (TLayoutDepth)(EldNone + 1); depth < EldCount; depth = (TLayoutDepth)(depth+1)) { if (id == TQualifier::getLayoutDepthString(depth)) { requireProfile(loc, ECoreProfile | ECompatibilityProfile, "depth layout qualifier"); @@ -5530,6 +5819,14 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi return; } } + for (TLayoutStencil stencil = (TLayoutStencil)(ElsNone + 1); stencil < ElsCount; stencil = (TLayoutStencil)(stencil+1)) { + if (id == TQualifier::getLayoutStencilString(stencil)) { + requireProfile(loc, ECoreProfile | ECompatibilityProfile, "stencil layout qualifier"); + profileRequires(loc, ECoreProfile | ECompatibilityProfile, 420, nullptr, "stencil layout qualifier"); + publicType.shaderQualifiers.layoutStencil = stencil; + return; + } + } for (TInterlockOrdering order = (TInterlockOrdering)(EioNone + 1); order < EioCount; order = (TInterlockOrdering)(order+1)) { if (id == TQualifier::getInterlockOrderingString(order)) { requireProfile(loc, ECoreProfile | ECompatibilityProfile, "fragment shader interlock layout qualifier"); @@ -5584,6 +5881,10 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi } publicType.qualifier.layoutShaderRecord = true; return; + } else if (id == "hitobjectshaderrecordnv") { + requireExtensions(loc, 1, &E_GL_NV_shader_invocation_reorder, "hitobject shader record NV"); + publicType.qualifier.layoutHitObjectShaderRecordNV = true; + return; } } @@ -5606,7 +5907,6 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi publicType.shaderQualifiers.layoutPrimitiveCulling = true; return; } -#endif error(loc, "unrecognized layout identifier, or qualifier requires assignment (e.g., binding = 4)", id.c_str(), ""); } @@ -5673,7 +5973,7 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi return; } else if (id == "location") { profileRequires(loc, EEsProfile, 300, nullptr, "location"); - const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; + const char* exts[2] = { E_GL_ARB_separate_shader_objects, E_GL_ARB_explicit_attrib_location }; // GL_ARB_explicit_uniform_location requires 330 or GL_ARB_explicit_attrib_location we do not need to add it here profileRequires(loc, ~EEsProfile, 330, 2, exts, "location"); if ((unsigned int)value >= TQualifier::layoutLocationEnd) @@ -5694,10 +5994,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "needs a literal integer", "set", ""); return; } else if (id == "binding") { -#ifndef GLSLANG_WEB profileRequires(loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, "binding"); profileRequires(loc, EEsProfile, 310, nullptr, "binding"); -#endif if ((unsigned int)value >= TQualifier::layoutBindingEnd) error(loc, "binding is too large", id.c_str(), ""); else @@ -5720,7 +6018,6 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "needs a literal integer", "constant_id", ""); return; } -#ifndef GLSLANG_WEB if (id == "component") { requireProfile(loc, ECoreProfile | ECompatibilityProfile, "component"); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 440, E_GL_ARB_enhanced_layouts, "component"); @@ -5818,10 +6115,8 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi error(loc, "needs a literal integer", "buffer_reference_align", ""); return; } -#endif switch (language) { -#ifndef GLSLANG_WEB case EShLangTessControl: if (id == "vertices") { if (value == 0) @@ -5883,40 +6178,49 @@ void TParseContext::setLayoutQualifier(const TSourceLoc& loc, TPublicType& publi } break; - case EShLangMeshNV: + case EShLangMesh: if (id == "max_vertices") { - requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "max_vertices"); + requireExtensions(loc, Num_AEP_mesh_shader, AEP_mesh_shader, "max_vertices"); publicType.shaderQualifiers.vertices = value; - if (value > resources.maxMeshOutputVerticesNV) - error(loc, "too large, must be less than gl_MaxMeshOutputVerticesNV", "max_vertices", ""); + int max = extensionTurnedOn(E_GL_EXT_mesh_shader) ? resources.maxMeshOutputVerticesEXT + : resources.maxMeshOutputVerticesNV; + if (value > max) { + TString maxsErrtring = "too large, must be less than "; + maxsErrtring.append(extensionTurnedOn(E_GL_EXT_mesh_shader) ? "gl_MaxMeshOutputVerticesEXT" + : "gl_MaxMeshOutputVerticesNV"); + error(loc, maxsErrtring.c_str(), "max_vertices", ""); + } if (nonLiteral) error(loc, "needs a literal integer", "max_vertices", ""); return; } if (id == "max_primitives") { - requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "max_primitives"); + requireExtensions(loc, Num_AEP_mesh_shader, AEP_mesh_shader, "max_primitives"); publicType.shaderQualifiers.primitives = value; - if (value > resources.maxMeshOutputPrimitivesNV) - error(loc, "too large, must be less than gl_MaxMeshOutputPrimitivesNV", "max_primitives", ""); + int max = extensionTurnedOn(E_GL_EXT_mesh_shader) ? resources.maxMeshOutputPrimitivesEXT + : resources.maxMeshOutputPrimitivesNV; + if (value > max) { + TString maxsErrtring = "too large, must be less than "; + maxsErrtring.append(extensionTurnedOn(E_GL_EXT_mesh_shader) ? "gl_MaxMeshOutputPrimitivesEXT" + : "gl_MaxMeshOutputPrimitivesNV"); + error(loc, maxsErrtring.c_str(), "max_primitives", ""); + } if (nonLiteral) error(loc, "needs a literal integer", "max_primitives", ""); return; } // Fall through - case EShLangTaskNV: + case EShLangTask: // Fall through -#endif case EShLangCompute: if (id.compare(0, 11, "local_size_") == 0) { -#ifndef GLSLANG_WEB - if (language == EShLangMeshNV || language == EShLangTaskNV) { - requireExtensions(loc, 1, &E_GL_NV_mesh_shader, "gl_WorkGroupSize"); + if (language == EShLangMesh || language == EShLangTask) { + requireExtensions(loc, Num_AEP_mesh_shader, AEP_mesh_shader, "gl_WorkGroupSize"); } else { - profileRequires(loc, EEsProfile, 310, 0, "gl_WorkGroupSize"); + profileRequires(loc, EEsProfile, 310, nullptr, "gl_WorkGroupSize"); profileRequires(loc, ~EEsProfile, 430, E_GL_ARB_compute_shader, "gl_WorkGroupSize"); } -#endif if (nonLiteral) error(loc, "needs a literal integer", "local_size", ""); if (id.size() == 12 && value == 0) { @@ -5983,7 +6287,6 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie if (src.hasPacking()) dst.layoutPacking = src.layoutPacking; -#ifndef GLSLANG_WEB if (src.hasStream()) dst.layoutStream = src.layoutStream; if (src.hasFormat()) @@ -5992,7 +6295,6 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie dst.layoutXfbBuffer = src.layoutXfbBuffer; if (src.hasBufferReferenceAlign()) dst.layoutBufferReferenceAlign = src.layoutBufferReferenceAlign; -#endif if (src.hasAlign()) dst.layoutAlign = src.layoutAlign; @@ -6010,7 +6312,6 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie if (src.hasSpecConstantId()) dst.layoutSpecConstantId = src.layoutSpecConstantId; -#ifndef GLSLANG_WEB if (src.hasComponent()) dst.layoutComponent = src.layoutComponent; if (src.hasIndex()) @@ -6035,9 +6336,16 @@ void TParseContext::mergeObjectLayoutQualifiers(TQualifier& dst, const TQualifie dst.layoutSecondaryViewportRelativeOffset = src.layoutSecondaryViewportRelativeOffset; if (src.layoutShaderRecord) dst.layoutShaderRecord = true; + if (src.layoutBindlessSampler) + dst.layoutBindlessSampler = true; + if (src.layoutBindlessImage) + dst.layoutBindlessImage = true; if (src.pervertexNV) dst.pervertexNV = true; -#endif + if (src.pervertexEXT) + dst.pervertexEXT = true; + if (src.layoutHitObjectShaderRecordNV) + dst.layoutHitObjectShaderRecordNV = true; } } @@ -6073,10 +6381,7 @@ void TParseContext::layoutObjectCheck(const TSourceLoc& loc, const TSymbol& symb switch (qualifier.storage) { case EvqVaryingIn: case EvqVaryingOut: - if (!type.getQualifier().isTaskMemory() && -#ifndef GLSLANG_WEB - !type.getQualifier().hasSprivDecorate() && -#endif + if (!type.getQualifier().isTaskMemory() && !type.getQualifier().hasSpirvDecorate() && (type.getBasicType() != EbtBlock || (!(*type.getStruct())[0].type->getQualifier().hasLocation() && (*type.getStruct())[0].type->getQualifier().builtIn == EbvNone))) @@ -6138,11 +6443,6 @@ void TParseContext::layoutMemberLocationArrayCheck(const TSourceLoc& loc, bool m // Do layout error checking with respect to a type. void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) { -#ifndef GLSLANG_WEB - if (extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) - return; // Skip any check if GL_EXT_spirv_intrinsics is turned on -#endif - const TQualifier& qualifier = type.getQualifier(); // first, intra-layout qualifier-only error checking @@ -6184,15 +6484,22 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) case EvqBuffer: if (type.getBasicType() == EbtBlock) error(loc, "cannot apply to uniform or buffer block", "location", ""); + else if (type.getBasicType() == EbtSampler && type.getSampler().isAttachmentEXT()) + error(loc, "only applies to", "location", "%s with storage tileImageEXT", type.getBasicTypeString().c_str()); + break; + case EvqtaskPayloadSharedEXT: + error(loc, "cannot apply to taskPayloadSharedEXT", "location", ""); break; -#ifndef GLSLANG_WEB case EvqPayload: case EvqPayloadIn: case EvqHitAttr: case EvqCallableData: case EvqCallableDataIn: + case EvqHitObjectAttrNV: + case EvqSpirvStorageClass: + break; + case EvqTileImageEXT: break; -#endif default: error(loc, "can only apply to uniform, buffer, in, or out storage qualifiers", "location", ""); break; @@ -6202,19 +6509,20 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) int repeated = intermediate.addUsedLocation(qualifier, type, typeCollision); if (repeated >= 0 && ! typeCollision) error(loc, "overlapping use of location", "location", "%d", repeated); - // "fragment-shader outputs ... if two variables are placed within the same + // "fragment-shader outputs/tileImageEXT ... if two variables are placed within the same // location, they must have the same underlying type (floating-point or integer)" - if (typeCollision && language == EShLangFragment && qualifier.isPipeOutput()) - error(loc, "fragment outputs sharing the same location must be the same basic type", "location", "%d", repeated); + if (typeCollision && language == EShLangFragment && (qualifier.isPipeOutput() || qualifier.storage == EvqTileImageEXT)) + error(loc, "fragment outputs or tileImageEXTs sharing the same location", "location", "%d must be the same basic type", repeated); } -#ifndef GLSLANG_WEB if (qualifier.hasXfbOffset() && qualifier.hasXfbBuffer()) { - int repeated = intermediate.addXfbBufferOffset(type); - if (repeated >= 0) - error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer); - if (type.isUnsizedArray()) + if (type.isUnsizedArray()) { error(loc, "unsized array", "xfb_offset", "in buffer %d", qualifier.layoutXfbBuffer); + } else { + int repeated = intermediate.addXfbBufferOffset(type); + if (repeated >= 0) + error(loc, "overlapping offsets at", "xfb_offset", "offset %d in buffer %d", repeated, qualifier.layoutXfbBuffer); + } // "The offset must be a multiple of the size of the first component of the first // qualified variable or block member, or a compile-time error results. Further, if applied to an aggregate @@ -6235,7 +6543,6 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) if (! intermediate.setXfbBufferStride(qualifier.layoutXfbBuffer, qualifier.layoutXfbStride)) error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer); } -#endif if (qualifier.hasBinding()) { // Binding checking, from the spec: @@ -6246,7 +6553,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) // an array of size N, all elements of the array from binding through binding + N - 1 must be within this // range." // - if (! type.isOpaque() && type.getBasicType() != EbtBlock) + if (!type.isOpaque() && type.getBasicType() != EbtBlock && type.getBasicType() != EbtSpirvType) error(loc, "requires block, or sampler/image, or atomic-counter type", "binding", ""); if (type.getBasicType() == EbtSampler) { int lastBinding = qualifier.layoutBinding; @@ -6255,16 +6562,12 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) if (type.isSizedArray()) lastBinding += (type.getCumulativeArraySize() - 1); else { -#ifndef GLSLANG_WEB warn(loc, "assuming binding count of one for compile-time checking of binding numbers for unsized array", "[]", ""); -#endif } } } -#ifndef GLSLANG_WEB if (spvVersion.vulkan == 0 && lastBinding >= resources.maxCombinedTextureImageUnits) error(loc, "sampler binding not less than gl_MaxCombinedTextureImageUnits", "binding", type.isArray() ? "(using array)" : ""); -#endif } if (type.isAtomic() && !spvVersion.vulkanRelaxed) { if (qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) { @@ -6287,7 +6590,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) !qualifier.hasAttachment() && !qualifier.hasBufferReference()) error(loc, "uniform/buffer blocks require layout(binding=X)", "binding", ""); - else if (spvVersion.vulkan > 0 && type.getBasicType() == EbtSampler) + else if (spvVersion.vulkan > 0 && type.getBasicType() == EbtSampler && !type.getSampler().isAttachmentEXT()) error(loc, "sampler/texture/image requires layout(binding=X)", "binding", ""); } } @@ -6309,7 +6612,7 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) // Image format if (qualifier.hasFormat()) { - if (! type.isImage()) + if (! type.isImage() && !intermediate.getBindlessImageMode()) error(loc, "only apply to images", TQualifier::getLayoutFormatString(qualifier.getFormat()), ""); else { if (type.getSampler().type == EbtFloat && qualifier.getFormat() > ElfFloatGuard) @@ -6328,14 +6631,18 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) } } } - } else if (type.isImage() && ! qualifier.isWriteOnly()) { + } else if (type.isImage() && ! qualifier.isWriteOnly() && !intermediate.getBindlessImageMode()) { const char *explanation = "image variables not declared 'writeonly' and without a format layout qualifier"; requireProfile(loc, ECoreProfile | ECompatibilityProfile, explanation); profileRequires(loc, ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shader_image_load_formatted, explanation); } - if (qualifier.isPushConstant() && type.getBasicType() != EbtBlock) - error(loc, "can only be used with a block", "push_constant", ""); + if (qualifier.isPushConstant()) { + if (type.getBasicType() != EbtBlock) + error(loc, "can only be used with a block", "push_constant", ""); + if (type.isArray()) + error(loc, "Push constants blocks can't be an array", "push_constant", ""); + } if (qualifier.hasBufferReference() && type.getBasicType() != EbtBlock) error(loc, "can only be used with a block", "buffer_reference", ""); @@ -6345,6 +6652,8 @@ void TParseContext::layoutTypeCheck(const TSourceLoc& loc, const TType& type) // input attachment if (type.isSubpass()) { + if (extensionTurnedOn(E_GL_EXT_shader_tile_image)) + error(loc, "can not be used with GL_EXT_shader_tile_image enabled", type.getSampler().getString().c_str(), ""); if (! qualifier.hasAttachment()) error(loc, "requires an input_attachment_index layout qualifier", "subpass", ""); } else { @@ -6414,7 +6723,6 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier // output block declarations, and output block member declarations." switch (qualifier.storage) { -#ifndef GLSLANG_WEB case EvqVaryingIn: { const char* feature = "location qualifier on input"; @@ -6449,7 +6757,6 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier } break; } -#endif case EvqUniform: case EvqBuffer: { @@ -6512,6 +6819,14 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier error(loc, "cannot be used with shaderRecordNV", "set", ""); } + + if (qualifier.storage == EvqTileImageEXT) { + if (qualifier.hasSet()) + error(loc, "cannot be used with tileImageEXT", "set", ""); + if (!qualifier.hasLocation()) + error(loc, "can only be used with an explicit location", "tileImageEXT", ""); + } + if (qualifier.storage == EvqHitAttr && qualifier.hasLayout()) { error(loc, "cannot apply layout qualifiers to hitAttributeNV variable", "hitAttributeNV", ""); } @@ -6520,7 +6835,6 @@ void TParseContext::layoutQualifierCheck(const TSourceLoc& loc, const TQualifier // For places that can't have shader-level layout qualifiers void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQualifiers& shaderQualifiers) { -#ifndef GLSLANG_WEB const char* message = "can only apply to a standalone qualifier"; if (shaderQualifiers.geometry != ElgNone) @@ -6540,7 +6854,7 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua error(loc, message, "local_size id", ""); } if (shaderQualifiers.vertices != TQualifier::layoutNotSet) { - if (language == EShLangGeometry || language == EShLangMeshNV) + if (language == EShLangGeometry || language == EShLangMesh) error(loc, message, "max_vertices", ""); else if (language == EShLangTessControl) error(loc, message, "vertices", ""); @@ -6551,8 +6865,14 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua error(loc, message, "early_fragment_tests", ""); if (shaderQualifiers.postDepthCoverage) error(loc, message, "post_depth_coverage", ""); + if (shaderQualifiers.nonCoherentColorAttachmentReadEXT) + error(loc, message, "non_coherent_color_attachment_readEXT", ""); + if (shaderQualifiers.nonCoherentDepthAttachmentReadEXT) + error(loc, message, "non_coherent_depth_attachment_readEXT", ""); + if (shaderQualifiers.nonCoherentStencilAttachmentReadEXT) + error(loc, message, "non_coherent_stencil_attachment_readEXT", ""); if (shaderQualifiers.primitives != TQualifier::layoutNotSet) { - if (language == EShLangMeshNV) + if (language == EShLangMesh) error(loc, message, "max_primitives", ""); else assert(0); @@ -6565,14 +6885,12 @@ void TParseContext::checkNoShaderLayouts(const TSourceLoc& loc, const TShaderQua error(loc, message, TQualifier::getInterlockOrderingString(shaderQualifiers.interlockOrdering), ""); if (shaderQualifiers.layoutPrimitiveCulling) error(loc, "can only be applied as standalone", "primitive_culling", ""); -#endif } // Correct and/or advance an object's offset layout qualifier. void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol) { const TQualifier& qualifier = symbol.getType().getQualifier(); -#ifndef GLSLANG_WEB if (symbol.getType().isAtomic()) { if (qualifier.hasBinding() && (int)qualifier.layoutBinding < resources.maxAtomicCounterBindings) { @@ -6606,7 +6924,6 @@ void TParseContext::fixOffset(const TSourceLoc& loc, TSymbol& symbol) atomicUintOffsets[qualifier.layoutBinding] = offset + numOffsets; } } -#endif } // @@ -6621,10 +6938,6 @@ const TFunction* TParseContext::findFunction(const TSourceLoc& loc, const TFunct return nullptr; } -#ifdef GLSLANG_WEB - return findFunctionExact(loc, call, builtIn); -#endif - const TFunction* function = nullptr; // debugPrintfEXT has var args and is in the symbol table as "debugPrintfEXT()", @@ -6951,7 +7264,6 @@ TIntermTyped* TParseContext::vkRelaxedRemapFunctionCall(const TSourceLoc& loc, T { TIntermTyped* result = nullptr; -#ifndef GLSLANG_WEB if (function->getBuiltInOp() != EOpNull) { return nullptr; } @@ -6963,12 +7275,14 @@ TIntermTyped* TParseContext::vkRelaxedRemapFunctionCall(const TSourceLoc& loc, T TFunction realFunc(&name, function->getType()); + // Use copyParam to avoid shared ownership of the 'type' field + // of the parameter. for (int i = 0; i < function->getParamCount(); ++i) { - realFunc.addParameter((*function)[i]); + realFunc.addParameter(TParameter().copyParam((*function)[i])); } - TParameter tmpP = { 0, &uintType }; - realFunc.addParameter(tmpP); + TParameter tmpP = { nullptr, &uintType }; + realFunc.addParameter(TParameter().copyParam(tmpP)); arguments = intermediate.growAggregate(arguments, intermediate.addConstantUnion(1, loc, true)); result = handleFunctionCall(loc, &realFunc, arguments); @@ -6981,11 +7295,11 @@ TIntermTyped* TParseContext::vkRelaxedRemapFunctionCall(const TSourceLoc& loc, T TFunction realFunc(&name, function->getType()); for (int i = 0; i < function->getParamCount(); ++i) { - realFunc.addParameter((*function)[i]); + realFunc.addParameter(TParameter().copyParam((*function)[i])); } - TParameter tmpP = { 0, &uintType }; - realFunc.addParameter(tmpP); + TParameter tmpP = { nullptr, &uintType }; + realFunc.addParameter(TParameter().copyParam(tmpP)); arguments = intermediate.growAggregate(arguments, intermediate.addConstantUnion(-1, loc, true)); result = handleFunctionCall(loc, &realFunc, arguments); @@ -7000,7 +7314,6 @@ TIntermTyped* TParseContext::vkRelaxedRemapFunctionCall(const TSourceLoc& loc, T result = arguments->getAsTyped(); } } -#endif return result; } @@ -7009,7 +7322,6 @@ TIntermTyped* TParseContext::vkRelaxedRemapFunctionCall(const TSourceLoc& loc, T // to establish defaults. void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType& publicType) { -#ifndef GLSLANG_WEB if (publicType.basicType == EbtAtomicUint && publicType.qualifier.hasBinding()) { if (publicType.qualifier.layoutBinding >= (unsigned int)resources.maxAtomicCounterBindings) { error(loc, "atomic_uint binding is too large", "binding", ""); @@ -7026,19 +7338,51 @@ void TParseContext::declareTypeDefaults(const TSourceLoc& loc, const TPublicType if (publicType.qualifier.hasLayout() && !publicType.qualifier.hasBufferReference()) warn(loc, "useless application of layout qualifier", "layout", ""); -#endif } -bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString& identifier, const TPublicType&, +void TParseContext::coopMatTypeParametersCheck(const TSourceLoc& loc, const TPublicType& publicType) +{ + if (parsingBuiltins) + return; + if (publicType.isCoopmatKHR()) { + if (publicType.typeParameters == nullptr) { + error(loc, "coopmat missing type parameters", "", ""); + return; + } + switch (publicType.typeParameters->basicType) { + case EbtFloat: + case EbtFloat16: + case EbtInt: + case EbtInt8: + case EbtInt16: + case EbtUint: + case EbtUint8: + case EbtUint16: + break; + default: + error(loc, "coopmat invalid basic type", TType::getBasicString(publicType.typeParameters->basicType), ""); + break; + } + if (publicType.typeParameters->arraySizes->getNumDims() != 4) { + error(loc, "coopmat incorrect number of type parameters", "", ""); + return; + } + int use = publicType.typeParameters->arraySizes->getDimSize(3); + if (use < 0 || use > 2) { + error(loc, "coopmat invalid matrix Use", "", ""); + return; + } + } +} + +bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString& identifier, const TPublicType& publicType, TArraySizes*, TIntermTyped* initializer, TType& type) { + vkRelaxedRemapUniformMembers(loc, publicType, type, identifier); + if (parsingBuiltins || symbolTable.atBuiltInLevel() || !symbolTable.atGlobalLevel() || type.getQualifier().storage != EvqUniform || - !(type.containsNonOpaque() -#ifndef GLSLANG_WEB - || type.getBasicType() == EbtAtomicUint -#endif - )) { + !(type.containsNonOpaque() || type.getBasicType() == EbtAtomicUint || (type.containsSampler() && type.isStruct()))) { return false; } @@ -7067,7 +7411,6 @@ bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString int bufferBinding = TQualifier::layoutBindingEnd; TVariable* updatedBlock = nullptr; -#ifndef GLSLANG_WEB // Convert atomic_uint into members of a buffer block if (type.isAtomic()) { type.setBasicType(EbtUint); @@ -7083,7 +7426,6 @@ bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString growAtomicCounterBlock(bufferBinding, loc, type, identifier, nullptr); updatedBlock = atomicCounterBuffers[bufferBinding]; } -#endif if (!updatedBlock) { growGlobalUniformBlock(loc, type, identifier, nullptr); @@ -7114,6 +7456,251 @@ bool TParseContext::vkRelaxedRemapUniformVariable(const TSourceLoc& loc, TString return true; } +template +static void ForEachOpaque(const TType& type, const TString& path, Function callback) +{ + auto recursion = [&callback](const TType& type, const TString& path, bool skipArray, auto& recursion) -> void { + if (!skipArray && type.isArray()) + { + std::vector indices(type.getArraySizes()->getNumDims()); + for (int flatIndex = 0; + flatIndex < type.getArraySizes()->getCumulativeSize(); + ++flatIndex) + { + TString subscriptPath = path; + for (size_t dimIndex = 0; dimIndex < indices.size(); ++dimIndex) + { + int index = indices[dimIndex]; + subscriptPath.append("["); + subscriptPath.append(String(index)); + subscriptPath.append("]"); + } + + recursion(type, subscriptPath, true, recursion); + + for (size_t dimIndex = 0; dimIndex < indices.size(); ++dimIndex) + { + ++indices[dimIndex]; + if (indices[dimIndex] < type.getArraySizes()->getDimSize(dimIndex)) + break; + else + indices[dimIndex] = 0; + } + } + } + + else if (type.isStruct() && type.containsOpaque()) + { + const TTypeList& types = *type.getStruct(); + for (const TTypeLoc& typeLoc : types) + { + TString nextPath = path; + nextPath.append("."); + nextPath.append(typeLoc.type->getFieldName()); + + recursion(*(typeLoc.type), nextPath, false, recursion); + } + } + + else if (type.isOpaque()) + { + callback(type, path); + } + }; + + recursion(type, path, false, recursion); +} + +void TParseContext::vkRelaxedRemapUniformMembers(const TSourceLoc& loc, const TPublicType& publicType, const TType& type, + const TString& identifier) +{ + if (!type.isStruct() || !type.containsOpaque()) + return; + + ForEachOpaque(type, identifier, + [&publicType, &loc, this](const TType& type, const TString& path) { + TArraySizes arraySizes = {}; + if (type.getArraySizes()) arraySizes = *type.getArraySizes(); + TTypeParameters typeParameters = {}; + if (type.getTypeParameters()) typeParameters = *type.getTypeParameters(); + + TPublicType memberType{}; + memberType.basicType = type.getBasicType(); + memberType.sampler = type.getSampler(); + memberType.qualifier = type.getQualifier(); + memberType.vectorSize = type.getVectorSize(); + memberType.matrixCols = type.getMatrixCols(); + memberType.matrixRows = type.getMatrixRows(); + memberType.coopmatNV = type.isCoopMatNV(); + memberType.coopmatKHR = type.isCoopMatKHR(); + memberType.arraySizes = nullptr; + memberType.userDef = nullptr; + memberType.loc = loc; + memberType.typeParameters = (type.getTypeParameters() ? &typeParameters : nullptr); + memberType.spirvType = nullptr; + + memberType.qualifier.storage = publicType.qualifier.storage; + memberType.shaderQualifiers = publicType.shaderQualifiers; + + TString& structMemberName = *NewPoolTString(path.c_str()); // A copy is required due to declareVariable() signature. + declareVariable(loc, structMemberName, memberType, nullptr, nullptr); + }); +} + +void TParseContext::vkRelaxedRemapFunctionParameter(TFunction* function, TParameter& param, std::vector* newParams) +{ + function->addParameter(param); + + if (!param.type->isStruct() || !param.type->containsOpaque()) + return; + + ForEachOpaque(*param.type, (param.name ? *param.name : param.type->getFieldName()), + [function, param, newParams](const TType& type, const TString& path) { + TString* memberName = NewPoolTString(path.c_str()); + + TType* memberType = new TType(); + memberType->shallowCopy(type); + memberType->getQualifier().storage = param.type->getQualifier().storage; + memberType->clearArraySizes(); + + TParameter memberParam = {}; + memberParam.name = memberName; + memberParam.type = memberType; + memberParam.defaultValue = nullptr; + function->addParameter(memberParam); + if (newParams) + newParams->push_back(function->getParamCount()-1); + }); +} + +// +// Generates a valid GLSL dereferencing string for the input TIntermNode +// +struct AccessChainTraverser : public TIntermTraverser { + AccessChainTraverser() : TIntermTraverser(false, false, true) + {} + + TString path = ""; + + bool visitBinary(TVisit, TIntermBinary* binary) override { + if (binary->getOp() == EOpIndexDirectStruct) + { + const TTypeList& members = *binary->getLeft()->getType().getStruct(); + const TTypeLoc& member = + members[binary->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()]; + TString memberName = member.type->getFieldName(); + + if (path != "") + path.append("."); + + path.append(memberName); + } + + if (binary->getOp() == EOpIndexDirect) + { + const TConstUnionArray& indices = binary->getRight()->getAsConstantUnion()->getConstArray(); + for (int index = 0; index < indices.size(); ++index) + { + path.append("["); + path.append(String(indices[index].getIConst())); + path.append("]"); + } + } + + return true; + } + + void visitSymbol(TIntermSymbol* symbol) override { + if (!IsAnonymous(symbol->getName())) + path.append(symbol->getName()); + } +}; + +TIntermNode* TParseContext::vkRelaxedRemapFunctionArgument(const TSourceLoc& loc, TFunction* function, TIntermTyped* intermTyped) +{ + AccessChainTraverser accessChainTraverser{}; + intermTyped->traverse(&accessChainTraverser); + + TParameter param = { NewPoolTString(accessChainTraverser.path.c_str()), new TType }; + param.type->shallowCopy(intermTyped->getType()); + + std::vector newParams = {}; + vkRelaxedRemapFunctionParameter(function, param, &newParams); + + if (intermTyped->getType().isOpaque()) + { + TIntermNode* remappedArgument = intermTyped; + { + TIntermSymbol* intermSymbol = nullptr; + TSymbol* symbol = symbolTable.find(*param.name); + if (symbol && symbol->getAsVariable()) + intermSymbol = intermediate.addSymbol(*symbol->getAsVariable(), loc); + else + { + TVariable* variable = new TVariable(param.name, *param.type); + intermSymbol = intermediate.addSymbol(*variable, loc); + } + + remappedArgument = intermSymbol; + } + + return remappedArgument; + } + else if (!(intermTyped->isStruct() && intermTyped->getType().containsOpaque())) + return intermTyped; + else + { + TIntermNode* remappedArgument = intermTyped; + { + TSymbol* symbol = symbolTable.find(*param.name); + if (symbol && symbol->getAsVariable()) + remappedArgument = intermediate.addSymbol(*symbol->getAsVariable(), loc); + } + + if (!newParams.empty()) + remappedArgument = intermediate.makeAggregate(remappedArgument, loc); + + for (int paramIndex : newParams) + { + TParameter& newParam = function->operator[](paramIndex); + TIntermSymbol* intermSymbol = nullptr; + TSymbol* symbol = symbolTable.find(*newParam.name); + if (symbol && symbol->getAsVariable()) + intermSymbol = intermediate.addSymbol(*symbol->getAsVariable(), loc); + else + { + TVariable* variable = new TVariable(newParam.name, *newParam.type); + intermSymbol = intermediate.addSymbol(*variable, loc); + } + + remappedArgument = intermediate.growAggregate(remappedArgument, intermSymbol); + } + + return remappedArgument; + } +} + +TIntermTyped* TParseContext::vkRelaxedRemapDotDereference(const TSourceLoc&, TIntermTyped& base, const TType& member, + const TString& identifier) +{ + if (!member.isOpaque()) + return &base; + + AccessChainTraverser traverser{}; + base.traverse(&traverser); + if (!traverser.path.empty()) + traverser.path.append("."); + traverser.path.append(identifier); + + const TSymbol* symbol = symbolTable.find(traverser.path); + if (!symbol) + return &base; + + TIntermTyped* result = intermediate.addSymbol(*symbol->getAsVariable()); + result->setType(symbol->getType()); + return result; +} + // // Do everything necessary to handle a variable (non-block) declaration. // Either redeclaring a variable, or making a new one, updating the symbol @@ -7138,32 +7725,49 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden if (initializer) { if (type.getBasicType() == EbtRayQuery) { error(loc, "ray queries can only be initialized by using the rayQueryInitializeEXT intrinsic:", "=", identifier.c_str()); + } else if (type.getBasicType() == EbtHitObjectNV) { + error(loc, "hit objects cannot be initialized using initializers", "=", identifier.c_str()); } + } - if (type.isCoopMat()) { + if (type.isCoopMatKHR()) { intermediate.setUseVulkanMemoryModel(); intermediate.setUseStorageBuffer(); - if (!publicType.typeParameters || publicType.typeParameters->getNumDims() != 4) { + if (!publicType.typeParameters || !publicType.typeParameters->arraySizes || + publicType.typeParameters->arraySizes->getNumDims() != 3) { + error(loc, "unexpected number type parameters", identifier.c_str(), ""); + } + if (publicType.typeParameters) { + if (!isTypeFloat(publicType.typeParameters->basicType) && !isTypeInt(publicType.typeParameters->basicType)) { + error(loc, "expected 8, 16, 32, or 64 bit signed or unsigned integer or 16, 32, or 64 bit float type", identifier.c_str(), ""); + } + } + } + else if (type.isCoopMatNV()) { + intermediate.setUseVulkanMemoryModel(); + intermediate.setUseStorageBuffer(); + + if (!publicType.typeParameters || publicType.typeParameters->arraySizes->getNumDims() != 4) { error(loc, "expected four type parameters", identifier.c_str(), ""); } if (publicType.typeParameters) { if (isTypeFloat(publicType.basicType) && - publicType.typeParameters->getDimSize(0) != 16 && - publicType.typeParameters->getDimSize(0) != 32 && - publicType.typeParameters->getDimSize(0) != 64) { + publicType.typeParameters->arraySizes->getDimSize(0) != 16 && + publicType.typeParameters->arraySizes->getDimSize(0) != 32 && + publicType.typeParameters->arraySizes->getDimSize(0) != 64) { error(loc, "expected 16, 32, or 64 bits for first type parameter", identifier.c_str(), ""); } if (isTypeInt(publicType.basicType) && - publicType.typeParameters->getDimSize(0) != 8 && - publicType.typeParameters->getDimSize(0) != 32) { - error(loc, "expected 8 or 32 bits for first type parameter", identifier.c_str(), ""); + publicType.typeParameters->arraySizes->getDimSize(0) != 8 && + publicType.typeParameters->arraySizes->getDimSize(0) != 16 && + publicType.typeParameters->arraySizes->getDimSize(0) != 32) { + error(loc, "expected 8, 16, or 32 bits for first type parameter", identifier.c_str(), ""); } } - } else { - if (publicType.typeParameters && publicType.typeParameters->getNumDims() != 0) { + if (publicType.typeParameters && publicType.typeParameters->arraySizes->getNumDims() != 0) { error(loc, "unexpected type parameters", identifier.c_str(), ""); } } @@ -7178,11 +7782,9 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden samplerCheck(loc, type, identifier, initializer); transparentOpaqueCheck(loc, type, identifier); -#ifndef GLSLANG_WEB atomicUintCheck(loc, type, identifier); accStructCheck(loc, type, identifier); checkAndResizeMeshViewDim(loc, type, /*isBlockMember*/ false); -#endif if (type.getQualifier().storage == EvqConst && type.containsReference()) { error(loc, "variables with reference type can't have qualifier 'const'", "qualifier", ""); } @@ -7196,6 +7798,8 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden requireInt8Arithmetic(loc, "qualifier", "(u)int8 types can only be in uniform block or buffer storage"); } + if (type.getQualifier().storage == EvqtaskPayloadSharedEXT) + intermediate.addTaskPayloadEXTCount(); if (type.getQualifier().storage == EvqShared && type.containsCoopMat()) error(loc, "qualifier", "Cooperative matrix types must not be used in shared memory", ""); @@ -7219,6 +7823,8 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden error(loc, "can only apply origin_upper_left and pixel_center_origin to gl_FragCoord", "layout qualifier", ""); if (identifier != "gl_FragDepth" && publicType.shaderQualifiers.getDepth() != EldNone) error(loc, "can only apply depth layout to gl_FragDepth", "layout qualifier", ""); + if (identifier != "gl_FragStencilRefARB" && publicType.shaderQualifiers.getStencil() != ElsNone) + error(loc, "can only apply depth layout to gl_FragStencilRefARB", "layout qualifier", ""); // Check for redeclaration of built-ins and/or attempting to declare a reserved name TSymbol* symbol = redeclareBuiltinVariable(loc, identifier, type.getQualifier(), publicType.shaderQualifiers); @@ -7281,14 +7887,12 @@ TIntermNode* TParseContext::declareVariable(const TSourceLoc& loc, TString& iden // Pick up global defaults from the provide global defaults into dst. void TParseContext::inheritGlobalDefaults(TQualifier& dst) const { -#ifndef GLSLANG_WEB if (dst.storage == EvqVaryingOut) { if (! dst.hasStream() && language == EShLangGeometry) dst.layoutStream = globalOutputDefaults.layoutStream; if (! dst.hasXfbBuffer()) dst.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; } -#endif } // @@ -7317,9 +7921,7 @@ TVariable* TParseContext::declareNonArray(const TSourceLoc& loc, const TString& // make a new variable TVariable* variable = new TVariable(&identifier, type); -#ifndef GLSLANG_WEB ioArrayCheck(loc, type, identifier); -#endif // add variable to symbol table if (symbolTable.insert(*variable)) { @@ -7396,9 +7998,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp TType skeletalType; skeletalType.shallowCopy(variable->getType()); skeletalType.getQualifier().makeTemporary(); -#ifndef GLSLANG_WEB initializer = convertInitializerList(loc, skeletalType, initializer); -#endif if (! initializer) { // error recovery; don't leave const without constant values if (qualifier == EvqConst) @@ -7426,14 +8026,14 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp // Uniforms require a compile-time constant initializer if (qualifier == EvqUniform && ! initializer->getType().getQualifier().isFrontEndConstant()) { error(loc, "uniform initializers must be constant", "=", "'%s'", - variable->getType().getCompleteString().c_str()); + variable->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str()); variable->getWritableType().getQualifier().makeTemporary(); return nullptr; } // Global consts require a constant initializer (specialization constant is okay) if (qualifier == EvqConst && symbolTable.atGlobalLevel() && ! initializer->getType().getQualifier().isConstant()) { error(loc, "global const initializers must be constant", "=", "'%s'", - variable->getType().getCompleteString().c_str()); + variable->getType().getCompleteString(intermediate.getEnhancedMsgs()).c_str()); variable->getWritableType().getQualifier().makeTemporary(); return nullptr; } @@ -7496,7 +8096,7 @@ TIntermNode* TParseContext::executeInitializer(const TSourceLoc& loc, TIntermTyp TIntermSymbol* intermSymbol = intermediate.addSymbol(*variable, loc); TIntermTyped* initNode = intermediate.addAssign(EOpAssign, intermSymbol, initializer, loc); if (! initNode) - assignError(loc, "=", intermSymbol->getCompleteString(), initializer->getCompleteString()); + assignError(loc, "=", intermSymbol->getCompleteString(intermediate.getEnhancedMsgs()), initializer->getCompleteString(intermediate.getEnhancedMsgs())); return initNode; } @@ -7567,7 +8167,7 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const } } else if (type.isMatrix()) { if (type.getMatrixCols() != (int)initList->getSequence().size()) { - error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString().c_str()); + error(loc, "wrong number of matrix columns:", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str()); return nullptr; } TType vectorType(type, 0); // dereferenced type @@ -7578,20 +8178,20 @@ TIntermTyped* TParseContext::convertInitializerList(const TSourceLoc& loc, const } } else if (type.isVector()) { if (type.getVectorSize() != (int)initList->getSequence().size()) { - error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString().c_str()); + error(loc, "wrong vector size (or rows in a matrix column):", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str()); return nullptr; } TBasicType destType = type.getBasicType(); for (int i = 0; i < type.getVectorSize(); ++i) { TBasicType initType = initList->getSequence()[i]->getAsTyped()->getBasicType(); if (destType != initType && !intermediate.canImplicitlyPromote(initType, destType)) { - error(loc, "type mismatch in initializer list", "initializer list", type.getCompleteString().c_str()); + error(loc, "type mismatch in initializer list", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str()); return nullptr; } } } else { - error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString().c_str()); + error(loc, "unexpected initializer-list type:", "initializer list", type.getCompleteString(intermediate.getEnhancedMsgs()).c_str()); return nullptr; } @@ -7626,12 +8226,14 @@ TIntermTyped* TParseContext::addConstructor(const TSourceLoc& loc, TIntermNode* // Combined texture-sampler constructors are completely semantic checked // in constructorTextureSamplerError() if (op == EOpConstructTextureSampler) { - if (aggrNode->getSequence()[1]->getAsTyped()->getType().getSampler().shadow) { - // Transfer depth into the texture (SPIR-V image) type, as a hint - // for tools to know this texture/image is a depth image. - aggrNode->getSequence()[0]->getAsTyped()->getWritableType().getSampler().shadow = true; + if (aggrNode != nullptr) { + if (aggrNode->getSequence()[1]->getAsTyped()->getType().getSampler().shadow) { + // Transfer depth into the texture (SPIR-V image) type, as a hint + // for tools to know this texture/image is a depth image. + aggrNode->getSequence()[0]->getAsTyped()->getWritableType().getSampler().shadow = true; + } + return intermediate.setAggregateOperator(aggrNode, op, type, loc); } - return intermediate.setAggregateOperator(aggrNode, op, type, loc); } TTypeList::const_iterator memberTypes; @@ -7766,6 +8368,16 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T TIntermTyped* newNode = intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvPtrToUvec2, true, node, type); return newNode; + } else if (node->getType().getBasicType() == EbtSampler) { + requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "sampler conversion to uvec2"); + // force the basic type of the constructor param to uvec2, otherwise spv builder will + // report some errors + TIntermTyped* newSrcNode = intermediate.createConversion(EbtUint, node); + newSrcNode->getAsTyped()->getWritableType().setVectorSize(2); + + TIntermTyped* newNode = + intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConstructUVec2, false, newSrcNode, type); + return newNode; } case EOpConstructUVec3: case EOpConstructUVec4: @@ -7779,9 +8391,15 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructBool: basicOp = EOpConstructBool; break; - -#ifndef GLSLANG_WEB - + case EOpConstructTextureSampler: + if ((node->getType().getBasicType() == EbtUint || node->getType().getBasicType() == EbtInt) && + node->getType().getVectorSize() == 2) { + requireExtensions(loc, 1, &E_GL_ARB_bindless_texture, "ivec2/uvec2 convert to texture handle"); + // No matter ivec2 or uvec2, Set EOpPackUint2x32 just to generate an opBitcast op code + TIntermTyped* newNode = + intermediate.addBuiltInFunctionCall(node->getLoc(), EOpPackUint2x32, true, node, type); + return newNode; + } case EOpConstructDVec2: case EOpConstructDVec3: case EOpConstructDVec4: @@ -7967,14 +8585,18 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T return nullptr; } - case EOpConstructCooperativeMatrix: + case EOpConstructCooperativeMatrixNV: + case EOpConstructCooperativeMatrixKHR: + if (node->getType() == type) { + return node; + } if (!node->getType().isCoopMat()) { if (type.getBasicType() != node->getType().getBasicType()) { node = intermediate.addConversion(type.getBasicType(), node); if (node == nullptr) return nullptr; } - node = intermediate.setAggregateOperator(node, EOpConstructCooperativeMatrix, type, node->getLoc()); + node = intermediate.setAggregateOperator(node, op, type, node->getLoc()); } else { TOperator op = EOpNull; switch (type.getBasicType()) { @@ -7987,6 +8609,8 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EbtFloat16: op = EOpConvFloat16ToInt; break; case EbtUint8: op = EOpConvUint8ToInt; break; case EbtInt8: op = EOpConvInt8ToInt; break; + case EbtUint16: op = EOpConvUint16ToInt; break; + case EbtInt16: op = EOpConvInt16ToInt; break; case EbtUint: op = EOpConvUintToInt; break; default: assert(0); } @@ -7997,8 +8621,33 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EbtFloat16: op = EOpConvFloat16ToUint; break; case EbtUint8: op = EOpConvUint8ToUint; break; case EbtInt8: op = EOpConvInt8ToUint; break; + case EbtUint16: op = EOpConvUint16ToUint; break; + case EbtInt16: op = EOpConvInt16ToUint; break; case EbtInt: op = EOpConvIntToUint; break; - case EbtUint: op = EOpConvUintToInt8; break; + default: assert(0); + } + break; + case EbtInt16: + switch (node->getType().getBasicType()) { + case EbtFloat: op = EOpConvFloatToInt16; break; + case EbtFloat16: op = EOpConvFloat16ToInt16; break; + case EbtUint8: op = EOpConvUint8ToInt16; break; + case EbtInt8: op = EOpConvInt8ToInt16; break; + case EbtUint16: op = EOpConvUint16ToInt16; break; + case EbtInt: op = EOpConvIntToInt16; break; + case EbtUint: op = EOpConvUintToInt16; break; + default: assert(0); + } + break; + case EbtUint16: + switch (node->getType().getBasicType()) { + case EbtFloat: op = EOpConvFloatToUint16; break; + case EbtFloat16: op = EOpConvFloat16ToUint16; break; + case EbtUint8: op = EOpConvUint8ToUint16; break; + case EbtInt8: op = EOpConvInt8ToUint16; break; + case EbtInt16: op = EOpConvInt16ToUint16; break; + case EbtInt: op = EOpConvIntToUint16; break; + case EbtUint: op = EOpConvUintToUint16; break; default: assert(0); } break; @@ -8007,6 +8656,8 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EbtFloat: op = EOpConvFloatToInt8; break; case EbtFloat16: op = EOpConvFloat16ToInt8; break; case EbtUint8: op = EOpConvUint8ToInt8; break; + case EbtInt16: op = EOpConvInt16ToInt8; break; + case EbtUint16: op = EOpConvUint16ToInt8; break; case EbtInt: op = EOpConvIntToInt8; break; case EbtUint: op = EOpConvUintToInt8; break; default: assert(0); @@ -8017,6 +8668,8 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EbtFloat: op = EOpConvFloatToUint8; break; case EbtFloat16: op = EOpConvFloat16ToUint8; break; case EbtInt8: op = EOpConvInt8ToUint8; break; + case EbtInt16: op = EOpConvInt16ToUint8; break; + case EbtUint16: op = EOpConvUint16ToUint8; break; case EbtInt: op = EOpConvIntToUint8; break; case EbtUint: op = EOpConvUintToUint8; break; default: assert(0); @@ -8027,6 +8680,8 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EbtFloat16: op = EOpConvFloat16ToFloat; break; case EbtInt8: op = EOpConvInt8ToFloat; break; case EbtUint8: op = EOpConvUint8ToFloat; break; + case EbtInt16: op = EOpConvInt16ToFloat; break; + case EbtUint16: op = EOpConvUint16ToFloat; break; case EbtInt: op = EOpConvIntToFloat; break; case EbtUint: op = EOpConvUintToFloat; break; default: assert(0); @@ -8037,6 +8692,8 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EbtFloat: op = EOpConvFloatToFloat16; break; case EbtInt8: op = EOpConvInt8ToFloat16; break; case EbtUint8: op = EOpConvUint8ToFloat16; break; + case EbtInt16: op = EOpConvInt16ToFloat16; break; + case EbtUint16: op = EOpConvUint16ToFloat16; break; case EbtInt: op = EOpConvIntToFloat16; break; case EbtUint: op = EOpConvUintToFloat16; break; default: assert(0); @@ -8055,17 +8712,16 @@ TIntermTyped* TParseContext::constructBuiltIn(const TType& type, TOperator op, T case EOpConstructAccStruct: if ((node->getType().isScalar() && node->getType().getBasicType() == EbtUint64)) { // construct acceleration structure from uint64 - requireExtensions(loc, 1, &E_GL_EXT_ray_tracing, "uint64_t conversion to acclerationStructureEXT"); + requireExtensions(loc, Num_ray_tracing_EXTs, ray_tracing_EXTs, "uint64_t conversion to acclerationStructureEXT"); return intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUint64ToAccStruct, true, node, type); } else if (node->getType().isVector() && node->getType().getBasicType() == EbtUint && node->getVectorSize() == 2) { // construct acceleration structure from uint64 - requireExtensions(loc, 1, &E_GL_EXT_ray_tracing, "uvec2 conversion to accelerationStructureEXT"); + requireExtensions(loc, Num_ray_tracing_EXTs, ray_tracing_EXTs, "uvec2 conversion to accelerationStructureEXT"); return intermediate.addBuiltInFunctionCall(node->getLoc(), EOpConvUvec2ToAccStruct, true, node, type); } else return nullptr; -#endif // GLSLANG_WEB default: error(loc, "unsupported construction", "", ""); @@ -8099,8 +8755,9 @@ TIntermTyped* TParseContext::constructAggregate(TIntermNode* node, const TType& { TIntermTyped* converted = intermediate.addConversion(EOpConstructStruct, type, node->getAsTyped()); if (! converted || converted->getType() != type) { + bool enhanced = intermediate.getEnhancedMsgs(); error(loc, "", "constructor", "cannot convert parameter %d from '%s' to '%s'", paramCount, - node->getAsTyped()->getType().getCompleteString().c_str(), type.getCompleteString().c_str()); + node->getAsTyped()->getType().getCompleteString(enhanced).c_str(), type.getCompleteString(enhanced).c_str()); return nullptr; } @@ -8111,7 +8768,6 @@ TIntermTyped* TParseContext::constructAggregate(TIntermNode* node, const TType& // If a memory qualifier is present in 'to', also make it present in 'from'. void TParseContext::inheritMemoryQualifiers(const TQualifier& from, TQualifier& to) { -#ifndef GLSLANG_WEB if (from.isReadOnly()) to.readonly = from.readonly; if (from.isWriteOnly()) @@ -8122,7 +8778,30 @@ void TParseContext::inheritMemoryQualifiers(const TQualifier& from, TQualifier& to.volatil = from.volatil; if (from.restrict) to.restrict = from.restrict; -#endif +} + +// +// Update qualifier layoutBindlessImage & layoutBindlessSampler on block member +// +void TParseContext::updateBindlessQualifier(TType& memberType) +{ + if (memberType.containsSampler()) { + if (memberType.isStruct()) { + TTypeList* typeList = memberType.getWritableStruct(); + for (unsigned int member = 0; member < typeList->size(); ++member) { + TType* subMemberType = (*typeList)[member].type; + updateBindlessQualifier(*subMemberType); + } + } + else if (memberType.getSampler().isImage()) { + intermediate.setBindlessImageMode(currentCaller, AstRefTypeLayout); + memberType.getQualifier().layoutBindlessImage = true; + } + else { + intermediate.setBindlessTextureMode(currentCaller, AstRefTypeLayout); + memberType.getQualifier().layoutBindlessSampler = true; + } + } } // @@ -8151,7 +8830,6 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con error(memberLoc, "member storage qualifier cannot contradict block storage qualifier", memberType.getFieldName().c_str(), ""); memberQualifier.storage = currentBlockQualifier.storage; globalQualifierFixCheck(memberLoc, memberQualifier); -#ifndef GLSLANG_WEB inheritMemoryQualifiers(currentBlockQualifier, memberQualifier); if (currentBlockQualifier.perPrimitiveNV) memberQualifier.perPrimitiveNV = currentBlockQualifier.perPrimitiveNV; @@ -8159,11 +8837,12 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con memberQualifier.perViewNV = currentBlockQualifier.perViewNV; if (currentBlockQualifier.perTaskNV) memberQualifier.perTaskNV = currentBlockQualifier.perTaskNV; + if (currentBlockQualifier.storage == EvqtaskPayloadSharedEXT) + memberQualifier.storage = EvqtaskPayloadSharedEXT; if (memberQualifier.storage == EvqSpirvStorageClass) error(memberLoc, "member cannot have a spirv_storage_class qualifier", memberType.getFieldName().c_str(), ""); - if (memberQualifier.hasSprivDecorate() && !memberQualifier.getSpirvDecorate().decorateIds.empty()) + if (memberQualifier.hasSpirvDecorate() && !memberQualifier.getSpirvDecorate().decorateIds.empty()) error(memberLoc, "member cannot have a spirv_decorate_id qualifier", memberType.getFieldName().c_str(), ""); -#endif if ((currentBlockQualifier.storage == EvqUniform || currentBlockQualifier.storage == EvqBuffer) && (memberQualifier.isInterpolation() || memberQualifier.isAuxiliary())) error(memberLoc, "member of uniform or buffer block cannot have an auxiliary or interpolation qualifier", memberType.getFieldName().c_str(), ""); if (memberType.isArray()) @@ -8175,8 +8854,13 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con } } - if (memberType.containsOpaque()) - error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), ""); + // For bindless texture, sampler can be declared as uniform/storage block member, + if (memberType.containsOpaque()) { + if (memberType.containsSampler() && extensionTurnedOn(E_GL_ARB_bindless_texture)) + updateBindlessQualifier(memberType); + else + error(memberLoc, "member of block cannot be or contain a sampler, image, or atomic_uint type", typeList[member].type->getFieldName().c_str(), ""); + } if (memberType.containsCoopMat()) error(memberLoc, "member of block cannot be or contain a cooperative matrix type", typeList[member].type->getFieldName().c_str(), ""); @@ -8238,7 +8922,6 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con for (unsigned int member = 0; member < typeList.size(); ++member) { TQualifier& memberQualifier = typeList[member].type->getQualifier(); const TSourceLoc& memberLoc = typeList[member].loc; -#ifndef GLSLANG_WEB if (memberQualifier.hasStream()) { if (defaultQualification.layoutStream != memberQualifier.layoutStream) error(memberLoc, "member cannot contradict block", "stream", ""); @@ -8252,14 +8935,12 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con if (defaultQualification.layoutXfbBuffer != memberQualifier.layoutXfbBuffer) error(memberLoc, "member cannot contradict block (or what block inherited from global)", "xfb_buffer", ""); } -#endif if (memberQualifier.hasPacking()) error(memberLoc, "member of block cannot have a packing layout qualifier", typeList[member].type->getFieldName().c_str(), ""); if (memberQualifier.hasLocation()) { const char* feature = "location on block member"; switch (currentBlockQualifier.storage) { -#ifndef GLSLANG_WEB case EvqVaryingIn: case EvqVaryingOut: requireProfile(memberLoc, ECoreProfile | ECompatibilityProfile | EEsProfile, feature); @@ -8267,7 +8948,6 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con profileRequires(memberLoc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, feature); memberWithLocation = true; break; -#endif default: error(memberLoc, "can only use in an in/out block", feature, ""); break; @@ -8295,7 +8975,6 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con layoutMemberLocationArrayCheck(loc, memberWithLocation, arraySizes); -#ifndef GLSLANG_WEB // Ensure that the block has an XfbBuffer assigned. This is needed // because if the block has a XfbOffset assigned, then it is // assumed that it has implicitly assigned the current global @@ -8305,7 +8984,6 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con if (!currentBlockQualifier.hasXfbBuffer() && currentBlockQualifier.hasXfbOffset()) currentBlockQualifier.layoutXfbBuffer = globalOutputDefaults.layoutXfbBuffer; } -#endif // Process the members fixBlockLocations(loc, currentBlockQualifier, typeList, memberWithLocation, memberWithoutLocation); @@ -8316,13 +8994,11 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con for (unsigned int member = 0; member < typeList.size(); ++member) layoutTypeCheck(typeList[member].loc, *typeList[member].type); -#ifndef GLSLANG_WEB if (memberWithPerViewQualifier) { for (unsigned int member = 0; member < typeList.size(); ++member) { checkAndResizeMeshViewDim(typeList[member].loc, *typeList[member].type, /*isBlockMember*/ true); } } -#endif // reverse merge, so that currentBlockQualifier now has all layout information // (can't use defaultQualification directly, it's missing other non-layout-default-class qualifiers) @@ -8336,7 +9012,6 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con if (arraySizes != nullptr) blockType.transferArraySizes(arraySizes); -#ifndef GLSLANG_WEB if (arraySizes == nullptr) ioArrayCheck(loc, blockType, instanceName ? *instanceName : *blockName); if (currentBlockQualifier.hasBufferReference()) { @@ -8363,9 +9038,7 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con if (!instanceName) { return; } - } else -#endif - { + } else { // // Don't make a user-defined type out of block name; that will cause an error // if the same block name gets reused in a different interface. @@ -8413,14 +9086,12 @@ void TParseContext::declareBlock(const TSourceLoc& loc, TTypeList& typeList, con // Check for general layout qualifier errors layoutObjectCheck(loc, variable); -#ifndef GLSLANG_WEB // fix up if (isIoResizeArray(blockType)) { ioArraySymbolResizeList.push_back(&variable); checkIoArraysConsistency(loc, true); } else fixIoArraySize(loc, variable.getWritableType()); -#endif // Save it in the AST for linker use. trackLinkage(variable); @@ -8459,23 +9130,23 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q // It is a compile-time error to have an input block in a vertex shader or an output block in a fragment shader // "Compute shaders do not permit user-defined input variables..." requireStage(loc, (EShLanguageMask)(EShLangTessControlMask|EShLangTessEvaluationMask|EShLangGeometryMask| - EShLangFragmentMask|EShLangMeshNVMask), "input block"); + EShLangFragmentMask|EShLangMeshMask), "input block"); if (language == EShLangFragment) { profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "fragment input block"); - } else if (language == EShLangMeshNV && ! qualifier.isTaskMemory()) { + } else if (language == EShLangMesh && ! qualifier.isTaskMemory()) { error(loc, "input blocks cannot be used in a mesh shader", "out", ""); } break; case EvqVaryingOut: profileRequires(loc, ~EEsProfile, 150, E_GL_ARB_separate_shader_objects, "output block"); requireStage(loc, (EShLanguageMask)(EShLangVertexMask|EShLangTessControlMask|EShLangTessEvaluationMask| - EShLangGeometryMask|EShLangMeshNVMask|EShLangTaskNVMask), "output block"); + EShLangGeometryMask|EShLangMeshMask|EShLangTaskMask), "output block"); // ES 310 can have a block before shader_io is turned on, so skip this test for built-ins if (language == EShLangVertex && ! parsingBuiltins) { profileRequires(loc, EEsProfile, 320, Num_AEP_shader_io_blocks, AEP_shader_io_blocks, "vertex output block"); - } else if (language == EShLangMeshNV && qualifier.isTaskMemory()) { + } else if (language == EShLangMesh && qualifier.isTaskMemory()) { error(loc, "can only use on input blocks in mesh shader", "taskNV", ""); - } else if (language == EShLangTaskNV && ! qualifier.isTaskMemory()) { + } else if (language == EShLangTask && ! qualifier.isTaskMemory()) { error(loc, "output blocks cannot be used in a task shader", "out", ""); } break; @@ -8485,7 +9156,6 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q } profileRequires(loc, EEsProfile | ECoreProfile | ECompatibilityProfile, 0, E_GL_EXT_shared_memory_block, "shared block"); break; -#ifndef GLSLANG_WEB case EvqPayload: profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "rayPayloadNV block"); requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangAnyHitMask | EShLangClosestHitMask | EShLangMissMask), @@ -8509,7 +9179,10 @@ void TParseContext::blockStageIoCheck(const TSourceLoc& loc, const TQualifier& q profileRequires(loc, ~EEsProfile, 460, 2, extsrt, "callableDataInNV block"); requireStage(loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV block"); break; -#endif + case EvqHitObjectAttrNV: + profileRequires(loc, ~EEsProfile, 460, E_GL_NV_shader_invocation_reorder, "hitObjectAttributeNV block"); + requireStage(loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | EShLangMissMask), "hitObjectAttributeNV block"); + break; default: error(loc, "only uniform, buffer, in, or out blocks are supported", blockName->c_str(), ""); break; @@ -8598,7 +9271,6 @@ void TParseContext::fixBlockLocations(const TSourceLoc& loc, TQualifier& qualifi void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList) { -#ifndef GLSLANG_WEB // "If a block is qualified with xfb_offset, all its // members are assigned transform feedback buffer offsets. If a block is not qualified with xfb_offset, any // members of that block not qualified with an xfb_offset will not be assigned transform feedback buffer @@ -8632,7 +9304,6 @@ void TParseContext::fixXfbOffsets(TQualifier& qualifier, TTypeList& typeList) // The above gave all block members an offset, so we can take it off the block now, // which will avoid double counting the offset usage. qualifier.layoutXfbOffset = TQualifier::layoutXfbOffsetEnd; -#endif } // Calculate and save the offset of each block member, using the recursively @@ -8665,7 +9336,8 @@ void TParseContext::fixBlockUniformOffsets(TQualifier& qualifier, TTypeList& typ // "The specified offset must be a multiple // of the base alignment of the type of the block member it qualifies, or a compile-time error results." if (! IsMultipleOfPow2(memberQualifier.layoutOffset, memberAlignment)) - error(memberLoc, "must be a multiple of the member's alignment", "offset", ""); + error(memberLoc, "must be a multiple of the member's alignment", "offset", + "(layout offset = %d | member alignment = %d)", memberQualifier.layoutOffset, memberAlignment); // GLSL: "It is a compile-time error to specify an offset that is smaller than the offset of the previous // member in the block or that lies within the previous member of the block" @@ -8808,7 +9480,7 @@ void TParseContext::addQualifierToExisting(const TSourceLoc& loc, TQualifier qua // TParseContext::declareBlock. if (!symbol && qualifier.hasBufferReference()) { TTypeList typeList; - TType blockType(&typeList, identifier, qualifier);; + TType blockType(&typeList, identifier, qualifier); TType blockNameType(EbtReference, blockType, identifier); TVariable* blockNameVar = new TVariable(&identifier, blockNameType, true); if (! symbolTable.insert(*blockNameVar)) { @@ -8887,9 +9559,8 @@ void TParseContext::invariantCheck(const TSourceLoc& loc, const TQualifier& qual // void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, const TPublicType& publicType) { -#ifndef GLSLANG_WEB if (publicType.shaderQualifiers.vertices != TQualifier::layoutNotSet) { - assert(language == EShLangTessControl || language == EShLangGeometry || language == EShLangMeshNV); + assert(language == EShLangTessControl || language == EShLangGeometry || language == EShLangMesh); const char* id = (language == EShLangTessControl) ? "vertices" : "max_vertices"; if (publicType.qualifier.storage != EvqVaryingOut) @@ -8901,7 +9572,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con checkIoArraysConsistency(loc); } if (publicType.shaderQualifiers.primitives != TQualifier::layoutNotSet) { - assert(language == EShLangMeshNV); + assert(language == EShLangMesh); const char* id = "max_primitives"; if (publicType.qualifier.storage != EvqVaryingOut) @@ -8925,7 +9596,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con case ElgTrianglesAdjacency: case ElgQuads: case ElgIsolines: - if (language == EShLangMeshNV) { + if (language == EShLangMesh) { error(loc, "cannot apply to input", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), ""); break; } @@ -8942,7 +9613,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con switch (publicType.shaderQualifiers.geometry) { case ElgLines: case ElgTriangles: - if (language != EShLangMeshNV) { + if (language != EShLangMesh) { error(loc, "cannot apply to 'out'", TQualifier::getGeometryString(publicType.shaderQualifiers.geometry), ""); break; } @@ -8979,7 +9650,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con else error(loc, "can only apply to 'in'", "point_mode", ""); } -#endif + for (int i = 0; i < 3; ++i) { if (publicType.shaderQualifiers.localSizeNotDefault[i]) { if (publicType.qualifier.storage == EvqVaryingIn) { @@ -8996,29 +9667,57 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con } if (intermediate.getLocalSize(i) > (unsigned int)max) error(loc, "too large; see gl_MaxComputeWorkGroupSize", "local_size", ""); - } -#ifndef GLSLANG_WEB - else if (language == EShLangMeshNV) { + } else if (language == EShLangMesh) { switch (i) { - case 0: max = resources.maxMeshWorkGroupSizeX_NV; break; - case 1: max = resources.maxMeshWorkGroupSizeY_NV; break; - case 2: max = resources.maxMeshWorkGroupSizeZ_NV; break; + case 0: + max = extensionTurnedOn(E_GL_EXT_mesh_shader) ? + resources.maxMeshWorkGroupSizeX_EXT : + resources.maxMeshWorkGroupSizeX_NV; + break; + case 1: + max = extensionTurnedOn(E_GL_EXT_mesh_shader) ? + resources.maxMeshWorkGroupSizeY_EXT : + resources.maxMeshWorkGroupSizeY_NV ; + break; + case 2: + max = extensionTurnedOn(E_GL_EXT_mesh_shader) ? + resources.maxMeshWorkGroupSizeZ_EXT : + resources.maxMeshWorkGroupSizeZ_NV ; + break; default: break; } - if (intermediate.getLocalSize(i) > (unsigned int)max) - error(loc, "too large; see gl_MaxMeshWorkGroupSizeNV", "local_size", ""); - } else if (language == EShLangTaskNV) { + if (intermediate.getLocalSize(i) > (unsigned int)max) { + TString maxsErrtring = "too large, see "; + maxsErrtring.append(extensionTurnedOn(E_GL_EXT_mesh_shader) ? + "gl_MaxMeshWorkGroupSizeEXT" : "gl_MaxMeshWorkGroupSizeNV"); + error(loc, maxsErrtring.c_str(), "local_size", ""); + } + } else if (language == EShLangTask) { switch (i) { - case 0: max = resources.maxTaskWorkGroupSizeX_NV; break; - case 1: max = resources.maxTaskWorkGroupSizeY_NV; break; - case 2: max = resources.maxTaskWorkGroupSizeZ_NV; break; + case 0: + max = extensionTurnedOn(E_GL_EXT_mesh_shader) ? + resources.maxTaskWorkGroupSizeX_EXT : + resources.maxTaskWorkGroupSizeX_NV; + break; + case 1: + max = extensionTurnedOn(E_GL_EXT_mesh_shader) ? + resources.maxTaskWorkGroupSizeY_EXT: + resources.maxTaskWorkGroupSizeY_NV; + break; + case 2: + max = extensionTurnedOn(E_GL_EXT_mesh_shader) ? + resources.maxTaskWorkGroupSizeZ_EXT: + resources.maxTaskWorkGroupSizeZ_NV; + break; default: break; } - if (intermediate.getLocalSize(i) > (unsigned int)max) - error(loc, "too large; see gl_MaxTaskWorkGroupSizeNV", "local_size", ""); - } -#endif - else { + if (intermediate.getLocalSize(i) > (unsigned int)max) { + TString maxsErrtring = "too large, see "; + maxsErrtring.append(extensionTurnedOn(E_GL_EXT_mesh_shader) ? + "gl_MaxTaskWorkGroupSizeEXT" : "gl_MaxTaskWorkGroupSizeNV"); + error(loc, maxsErrtring.c_str(), "local_size", ""); + } + } else { assert(0); } @@ -9043,19 +9742,42 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con } } -#ifndef GLSLANG_WEB if (publicType.shaderQualifiers.earlyFragmentTests) { if (publicType.qualifier.storage == EvqVaryingIn) intermediate.setEarlyFragmentTests(); else error(loc, "can only apply to 'in'", "early_fragment_tests", ""); } + if (publicType.shaderQualifiers.earlyAndLateFragmentTestsAMD) { + if (publicType.qualifier.storage == EvqVaryingIn) + intermediate.setEarlyAndLateFragmentTestsAMD(); + else + error(loc, "can only apply to 'in'", "early_and_late_fragment_tests_amd", ""); + } if (publicType.shaderQualifiers.postDepthCoverage) { if (publicType.qualifier.storage == EvqVaryingIn) intermediate.setPostDepthCoverage(); else error(loc, "can only apply to 'in'", "post_coverage_coverage", ""); } + if (publicType.shaderQualifiers.nonCoherentColorAttachmentReadEXT) { + if (publicType.qualifier.storage == EvqVaryingIn) + intermediate.setNonCoherentColorAttachmentReadEXT(); + else + error(loc, "can only apply to 'in'", "non_coherent_color_attachment_readEXT", ""); + } + if (publicType.shaderQualifiers.nonCoherentDepthAttachmentReadEXT) { + if (publicType.qualifier.storage == EvqVaryingIn) + intermediate.setNonCoherentDepthAttachmentReadEXT(); + else + error(loc, "can only apply to 'in'", "non_coherent_depth_attachment_readEXT", ""); + } + if (publicType.shaderQualifiers.nonCoherentStencilAttachmentReadEXT) { + if (publicType.qualifier.storage == EvqVaryingIn) + intermediate.setNonCoherentStencilAttachmentReadEXT(); + else + error(loc, "can only apply to 'in'", "non_coherent_stencil_attachment_readEXT", ""); + } if (publicType.shaderQualifiers.hasBlendEquation()) { if (publicType.qualifier.storage != EvqVaryingOut) error(loc, "can only apply to 'out'", "blend equation", ""); @@ -9098,7 +9820,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con error(loc, "can only apply to 'in'", "derivative_group_linearNV", ""); } // Check mesh out array sizes, once all the necessary out qualifiers are defined. - if ((language == EShLangMeshNV) && + if ((language == EShLangMesh) && (intermediate.getVertices() != TQualifier::layoutNotSet) && (intermediate.getPrimitives() != TQualifier::layoutNotSet) && (intermediate.getOutputPrimitive() != ElgNone)) @@ -9115,7 +9837,7 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con // Exit early as further checks are not valid return; } -#endif + const TQualifier& qualifier = publicType.qualifier; if (qualifier.isAuxiliary() || @@ -9148,7 +9870,6 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con case EvqVaryingIn: break; case EvqVaryingOut: -#ifndef GLSLANG_WEB if (qualifier.hasStream()) globalOutputDefaults.layoutStream = qualifier.layoutStream; if (qualifier.hasXfbBuffer()) @@ -9157,7 +9878,6 @@ void TParseContext::updateStandaloneQualifierDefaults(const TSourceLoc& loc, con if (! intermediate.setXfbBufferStride(globalOutputDefaults.layoutXfbBuffer, qualifier.layoutXfbStride)) error(loc, "all stride settings must match for xfb buffer", "xfb_stride", "%d", qualifier.layoutXfbBuffer); } -#endif break; case EvqShared: if (qualifier.hasMatrix()) @@ -9312,5 +10032,38 @@ const TTypeList* TParseContext::recordStructCopy(TStructRecord& record, const TT return originStruct; } -} // end namespace glslang +TLayoutFormat TParseContext::mapLegacyLayoutFormat(TLayoutFormat legacyLayoutFormat, TBasicType imageType) +{ + TLayoutFormat layoutFormat = ElfNone; + if (imageType == EbtFloat) { + switch (legacyLayoutFormat) { + case ElfSize1x16: layoutFormat = ElfR16f; break; + case ElfSize1x32: layoutFormat = ElfR32f; break; + case ElfSize2x32: layoutFormat = ElfRg32f; break; + case ElfSize4x32: layoutFormat = ElfRgba32f; break; + default: break; + } + } else if (imageType == EbtUint) { + switch (legacyLayoutFormat) { + case ElfSize1x8: layoutFormat = ElfR8ui; break; + case ElfSize1x16: layoutFormat = ElfR16ui; break; + case ElfSize1x32: layoutFormat = ElfR32ui; break; + case ElfSize2x32: layoutFormat = ElfRg32ui; break; + case ElfSize4x32: layoutFormat = ElfRgba32ui; break; + default: break; + } + } else if (imageType == EbtInt) { + switch (legacyLayoutFormat) { + case ElfSize1x8: layoutFormat = ElfR8i; break; + case ElfSize1x16: layoutFormat = ElfR16i; break; + case ElfSize1x32: layoutFormat = ElfR32i; break; + case ElfSize2x32: layoutFormat = ElfRg32i; break; + case ElfSize4x32: layoutFormat = ElfRgba32i; break; + default: break; + } + } + return layoutFormat; +} + +} // end namespace glslang diff --git a/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h b/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h index 885fd9081..16902aefe 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h +++ b/src/libraries/glslang/glslang/MachineIndependent/ParseHelper.h @@ -95,12 +95,15 @@ class TParseContextBase : public TParseVersions { globalUniformSet(TQualifier::layoutSetEnd), atomicCounterBlockSet(TQualifier::layoutSetEnd) { + // use storage buffer on SPIR-V 1.3 and up + if (spvVersion.spv >= EShTargetSpv_1_3) + intermediate.setUseStorageBuffer(); + if (entryPoint != nullptr) sourceEntryPointName = *entryPoint; } virtual ~TParseContextBase() { } -#if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL) virtual void C_DECL error(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...); virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, @@ -109,7 +112,6 @@ class TParseContextBase : public TParseVersions { const char* szExtraInfoFormat, ...); virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...); -#endif virtual void setLimits(const TBuiltInResource&) = 0; @@ -178,6 +180,7 @@ class TParseContextBase : public TParseVersions { // Basic parsing state, easily accessible to the grammar TSymbolTable& symbolTable; // symbol table that goes with the current language, version, and profile + TVector relaxedSymbols; int statementNestingLevel; // 0 if outside all flow control or compound statements int loopNestingLevel; // 0 if outside all loops int structNestingLevel; // 0 if outside structures @@ -194,6 +197,7 @@ class TParseContextBase : public TParseVersions { struct TPragma contextPragma; int beginInvocationInterlockCount; int endInvocationInterlockCount; + bool compileOnly = false; protected: TParseContextBase(TParseContextBase&); @@ -327,10 +331,8 @@ class TParseContext : public TParseContextBase { TIntermTyped* handleBracketDereference(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index); void handleIndexLimits(const TSourceLoc&, TIntermTyped* base, TIntermTyped* index); -#ifndef GLSLANG_WEB void makeEditable(TSymbol*&) override; void ioArrayCheck(const TSourceLoc&, const TType&, const TString& identifier); -#endif bool isIoResizeArray(const TType&) const; void fixIoArraySize(const TSourceLoc&, TType&); void handleIoResizeArrayAccess(const TSourceLoc&, TIntermTyped* base); @@ -366,6 +368,10 @@ class TParseContext : public TParseContextBase { TIntermTyped* vkRelaxedRemapFunctionCall(const TSourceLoc&, TFunction*, TIntermNode*); // returns true if the variable was remapped to something else bool vkRelaxedRemapUniformVariable(const TSourceLoc&, TString&, const TPublicType&, TArraySizes*, TIntermTyped*, TType&); + void vkRelaxedRemapUniformMembers(const TSourceLoc&, const TPublicType&, const TType&, const TString&); + void vkRelaxedRemapFunctionParameter(TFunction*, TParameter&, std::vector* newParams = nullptr); + TIntermNode* vkRelaxedRemapFunctionArgument(const TSourceLoc&, TFunction*, TIntermTyped*); + TIntermTyped* vkRelaxedRemapDotDereference(const TSourceLoc&, TIntermTyped&, const TType&, const TString&); void assignError(const TSourceLoc&, const char* op, TString left, TString right); void unaryOpError(const TSourceLoc&, const char* op, TString operand); @@ -378,7 +384,7 @@ class TParseContext : public TParseContextBase { void globalCheck(const TSourceLoc&, const char* token); bool constructorError(const TSourceLoc&, TIntermNode*, TFunction&, TOperator, TType&); bool constructorTextureSamplerError(const TSourceLoc&, const TFunction&); - void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&, const char *sizeType); + void arraySizeCheck(const TSourceLoc&, TIntermTyped* expr, TArraySize&, const char *sizeType, const bool allowZero = false); bool arrayQualifierError(const TSourceLoc&, const TQualifier&); bool arrayError(const TSourceLoc&, const TType&); void arraySizeRequiredCheck(const TSourceLoc&, const TArraySizes&); @@ -393,14 +399,14 @@ class TParseContext : public TParseContextBase { void accStructCheck(const TSourceLoc & loc, const TType & type, const TString & identifier); void transparentOpaqueCheck(const TSourceLoc&, const TType&, const TString& identifier); void memberQualifierCheck(glslang::TPublicType&); - void globalQualifierFixCheck(const TSourceLoc&, TQualifier&, bool isMemberCheck = false); + void globalQualifierFixCheck(const TSourceLoc&, TQualifier&, bool isMemberCheck = false, const TPublicType* publicType = nullptr); void globalQualifierTypeCheck(const TSourceLoc&, const TQualifier&, const TPublicType&); bool structQualifierErrorCheck(const TSourceLoc&, const TPublicType& pType); void mergeQualifiers(const TSourceLoc&, TQualifier& dst, const TQualifier& src, bool force); void setDefaultPrecision(const TSourceLoc&, TPublicType&, TPrecisionQualifier); int computeSamplerTypeIndex(TSampler&); TPrecisionQualifier getDefaultPrecision(TPublicType&); - void precisionQualifierCheck(const TSourceLoc&, TBasicType, TQualifier&); + void precisionQualifierCheck(const TSourceLoc&, TBasicType, TQualifier&, bool isCoopMat); void parameterTypeCheck(const TSourceLoc&, TStorageQualifier qualifier, const TType& type); bool containsFieldWithBasicType(const TType& type ,TBasicType basicType); TSymbol* redeclareBuiltinVariable(const TSourceLoc&, const TString&, const TQualifier&, const TShaderQualifiers&); @@ -418,6 +424,7 @@ class TParseContext : public TParseContextBase { void inductiveLoopCheck(const TSourceLoc&, TIntermNode* init, TIntermLoop* loop); void arrayLimitCheck(const TSourceLoc&, const TString&, int size); void limitCheck(const TSourceLoc&, int value, const char* limit, const char* feature); + void coopMatTypeParametersCheck(const TSourceLoc&, const TPublicType&); void inductiveLoopBodyCheck(TIntermNode*, long long loopIndexId, TSymbolTable&); void constantIndexExpressionCheck(TIntermNode*); @@ -438,12 +445,12 @@ class TParseContext : public TParseContextBase { const TFunction* findFunction400(const TSourceLoc& loc, const TFunction& call, bool& builtIn); const TFunction* findFunctionExplicitTypes(const TSourceLoc& loc, const TFunction& call, bool& builtIn); void declareTypeDefaults(const TSourceLoc&, const TPublicType&); - TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TPublicType&, TArraySizes* typeArray = 0, TIntermTyped* initializer = 0); + TIntermNode* declareVariable(const TSourceLoc&, TString& identifier, const TPublicType&, TArraySizes* typeArray = nullptr, TIntermTyped* initializer = nullptr); TIntermTyped* addConstructor(const TSourceLoc&, TIntermNode*, const TType&); TIntermTyped* constructAggregate(TIntermNode*, const TType&, int, const TSourceLoc&); 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 = nullptr, TArraySizes* arraySizes = nullptr); void blockStorageRemap(const TSourceLoc&, const TString*, TQualifier&); void blockStageIoCheck(const TSourceLoc&, const TQualifier&); void blockQualifierCheck(const TSourceLoc&, const TQualifier&, bool instanceName); @@ -456,11 +463,12 @@ class TParseContext : public TParseContextBase { void addQualifierToExisting(const TSourceLoc&, TQualifier, TIdentifierList&); void invariantCheck(const TSourceLoc&, const TQualifier&); void updateStandaloneQualifierDefaults(const TSourceLoc&, const TPublicType&); + void updateBindlessQualifier(TType& memberType); void wrapupSwitchSubsequence(TIntermAggregate* statements, TIntermNode* branchNode); TIntermNode* addSwitch(const TSourceLoc&, TIntermTyped* expression, TIntermAggregate* body); const TTypeList* recordStructCopy(TStructRecord&, const TType*, const TType*); + TLayoutFormat mapLegacyLayoutFormat(TLayoutFormat legacyLayoutFormat, TBasicType imageType); -#ifndef GLSLANG_WEB TAttributeType attributeFromName(const TString& name) const; TAttributes* makeAttributes(const TString& identifier) const; TAttributes* makeAttributes(const TString& identifier, TIntermNode* node) const; @@ -480,14 +488,13 @@ class TParseContext : public TParseContextBase { TSpirvRequirement* mergeSpirvRequirements(const TSourceLoc& loc, TSpirvRequirement* spirvReq1, TSpirvRequirement* spirvReq2); TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TIntermConstantUnion* constant); + TSpirvTypeParameters* makeSpirvTypeParameters(const TSourceLoc& loc, const TPublicType& type); TSpirvTypeParameters* mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1, TSpirvTypeParameters* spirvTypeParams2); TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, const TString& value); TSpirvInstruction* makeSpirvInstruction(const TSourceLoc& loc, const TString& name, int value); TSpirvInstruction* mergeSpirvInstruction(const TSourceLoc& loc, TSpirvInstruction* spirvInst1, TSpirvInstruction* spirvInst2); -#endif - void checkAndResizeMeshViewDim(const TSourceLoc&, TType&, bool isBlockMember); protected: @@ -500,9 +507,7 @@ class TParseContext : public TParseContextBase { bool isRuntimeLength(const TIntermTyped&) const; TIntermNode* executeInitializer(const TSourceLoc&, TIntermTyped* initializer, TVariable* variable); TIntermTyped* convertInitializerList(const TSourceLoc&, const TType&, TIntermTyped* initializer); -#ifndef GLSLANG_WEB void finish() override; -#endif virtual const char* getGlobalUniformBlockName() const override; virtual void finalizeGlobalUniformBlockLayout(TVariable&) override; @@ -539,7 +544,6 @@ class TParseContext : public TParseContextBase { TQualifier globalOutputDefaults; TQualifier globalSharedDefaults; TString currentCaller; // name of last function body entered (not valid when at global scope) -#ifndef GLSLANG_WEB int* atomicUintOffsets; // to become an array of the right size to hold an offset per binding point bool anyIndexLimits; TIdSetType inductiveLoopIds; @@ -580,7 +584,6 @@ class TParseContext : public TParseContextBase { // array-sizing declarations // TVector ioArraySymbolResizeList; -#endif }; } // end namespace glslang diff --git a/src/libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp b/src/libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp index 84c40f4e7..5d7173c9d 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/PoolAlloc.cpp @@ -35,34 +35,28 @@ #include "../Include/Common.h" #include "../Include/PoolAlloc.h" -#include "../Include/InitializeGlobals.h" -#include "../OSDependent/osinclude.h" - namespace glslang { -// Process-wide TLS index -OS_TLSIndex PoolIndex; +namespace { +thread_local TPoolAllocator* threadPoolAllocator = nullptr; + +TPoolAllocator* GetDefaultThreadPoolAllocator() +{ + thread_local TPoolAllocator defaultAllocator; + return &defaultAllocator; +} +} // anonymous namespace // Return the thread-specific current pool. TPoolAllocator& GetThreadPoolAllocator() { - return *static_cast(OS_GetTLSValue(PoolIndex)); + return *(threadPoolAllocator ? threadPoolAllocator : GetDefaultThreadPoolAllocator()); } // Set the thread-specific current pool. void SetThreadPoolAllocator(TPoolAllocator* poolAllocator) { - OS_SetTLSValue(PoolIndex, poolAllocator); -} - -// Process-wide set up of the TLS pool storage. -bool InitializePoolIndex() -{ - // Allocate a TLS index. - if ((PoolIndex = OS_AllocTLSIndex()) == OS_INVALID_TLS_INDEX) - return false; - - return true; + threadPoolAllocator = poolAllocator; } // @@ -137,16 +131,6 @@ TPoolAllocator::~TPoolAllocator() } } -const unsigned char TAllocation::guardBlockBeginVal = 0xfb; -const unsigned char TAllocation::guardBlockEndVal = 0xfe; -const unsigned char TAllocation::userDataFill = 0xcd; - -# ifdef GUARD_BLOCKS - const size_t TAllocation::guardBlockSize = 16; -# else - const size_t TAllocation::guardBlockSize = 0; -# endif - // // Check a single guard block for damage // @@ -267,8 +251,8 @@ void* TPoolAllocator::allocate(size_t numBytes) // size_t numBytesToAlloc = allocationSize + headerSkip; tHeader* memory = reinterpret_cast(::new char[numBytesToAlloc]); - if (memory == 0) - return 0; + if (memory == nullptr) + return nullptr; // Use placement-new to initialize header new(memory) tHeader(inUseList, (numBytesToAlloc + pageSize - 1) / pageSize); @@ -289,8 +273,8 @@ void* TPoolAllocator::allocate(size_t numBytes) freeList = freeList->nextPage; } else { memory = reinterpret_cast(::new char[pageSize]); - if (memory == 0) - return 0; + if (memory == nullptr) + return nullptr; } // Use placement-new to initialize header @@ -308,7 +292,7 @@ void* TPoolAllocator::allocate(size_t numBytes) // void TAllocation::checkAllocList() const { - for (const TAllocation* alloc = this; alloc != 0; alloc = alloc->prevAlloc) + for (const TAllocation* alloc = this; alloc != nullptr; alloc = alloc->prevAlloc) alloc->check(); } diff --git a/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp b/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp index ce6a6199d..b3f3dc4d4 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/Scan.cpp @@ -324,11 +324,9 @@ struct str_hash // A single global usable by all threads, by all versions, by all languages. // After a single process-level initialization, this is read only and thread safe std::unordered_map* KeywordMap = nullptr; -#ifndef GLSLANG_WEB std::unordered_set* ReservedSet = nullptr; -#endif -}; +} namespace glslang { @@ -343,6 +341,7 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["const"] = CONST; (*KeywordMap)["uniform"] = UNIFORM; + (*KeywordMap)["tileImageEXT"] = TILEIMAGEEXT; (*KeywordMap)["buffer"] = BUFFER; (*KeywordMap)["in"] = IN; (*KeywordMap)["out"] = OUT; @@ -408,7 +407,6 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["uvec3"] = UVEC3; (*KeywordMap)["uvec4"] = UVEC4; -#ifndef GLSLANG_WEB (*KeywordMap)["nonuniformEXT"] = NONUNIFORM; (*KeywordMap)["demote"] = DEMOTE; (*KeywordMap)["attribute"] = ATTRIBUTE; @@ -598,7 +596,6 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["spirv_storage_class"] = SPIRV_STORAGE_CLASS; (*KeywordMap)["spirv_by_reference"] = SPIRV_BY_REFERENCE; (*KeywordMap)["spirv_literal"] = SPIRV_LITERAL; -#endif (*KeywordMap)["sampler2D"] = SAMPLER2D; (*KeywordMap)["samplerCube"] = SAMPLERCUBE; @@ -632,7 +629,6 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["sampler"] = SAMPLER; (*KeywordMap)["samplerShadow"] = SAMPLERSHADOW; -#ifndef GLSLANG_WEB (*KeywordMap)["textureCubeArray"] = TEXTURECUBEARRAY; (*KeywordMap)["itextureCubeArray"] = ITEXTURECUBEARRAY; (*KeywordMap)["utextureCubeArray"] = UTEXTURECUBEARRAY; @@ -685,6 +681,10 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["texture2DRect"] = TEXTURE2DRECT; (*KeywordMap)["texture1DArray"] = TEXTURE1DARRAY; + (*KeywordMap)["attachmentEXT"] = ATTACHMENTEXT; + (*KeywordMap)["iattachmentEXT"] = IATTACHMENTEXT; + (*KeywordMap)["uattachmentEXT"] = UATTACHMENTEXT; + (*KeywordMap)["subpassInput"] = SUBPASSINPUT; (*KeywordMap)["subpassInputMS"] = SUBPASSINPUTMS; (*KeywordMap)["isubpassInput"] = ISUBPASSINPUT; @@ -739,6 +739,7 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["f16subpassInputMS"] = F16SUBPASSINPUTMS; (*KeywordMap)["__explicitInterpAMD"] = EXPLICITINTERPAMD; (*KeywordMap)["pervertexNV"] = PERVERTEXNV; + (*KeywordMap)["pervertexEXT"] = PERVERTEXEXT; (*KeywordMap)["precise"] = PRECISE; (*KeywordMap)["rayPayloadNV"] = PAYLOADNV; @@ -757,11 +758,18 @@ void TScanContext::fillInKeywordMap() (*KeywordMap)["perprimitiveNV"] = PERPRIMITIVENV; (*KeywordMap)["perviewNV"] = PERVIEWNV; (*KeywordMap)["taskNV"] = PERTASKNV; + (*KeywordMap)["perprimitiveEXT"] = PERPRIMITIVEEXT; + (*KeywordMap)["taskPayloadSharedEXT"] = TASKPAYLOADWORKGROUPEXT; (*KeywordMap)["fcoopmatNV"] = FCOOPMATNV; (*KeywordMap)["icoopmatNV"] = ICOOPMATNV; (*KeywordMap)["ucoopmatNV"] = UCOOPMATNV; + (*KeywordMap)["coopmat"] = COOPMAT; + + (*KeywordMap)["hitObjectNV"] = HITOBJECTNV; + (*KeywordMap)["hitObjectAttributeNV"] = HITOBJECTATTRNV; + ReservedSet = new std::unordered_set; ReservedSet->insert("common"); @@ -801,17 +809,14 @@ void TScanContext::fillInKeywordMap() ReservedSet->insert("cast"); ReservedSet->insert("namespace"); ReservedSet->insert("using"); -#endif } void TScanContext::deleteKeywordMap() { delete KeywordMap; KeywordMap = nullptr; -#ifndef GLSLANG_WEB delete ReservedSet; ReservedSet = nullptr; -#endif } // Called by yylex to get the next token. @@ -892,14 +897,12 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token) case PpAtomConstInt: parserToken->sType.lex.i = ppToken.ival; return INTCONSTANT; case PpAtomConstUint: parserToken->sType.lex.i = ppToken.ival; return UINTCONSTANT; case PpAtomConstFloat: parserToken->sType.lex.d = ppToken.dval; return FLOATCONSTANT; -#ifndef GLSLANG_WEB case PpAtomConstInt16: parserToken->sType.lex.i = ppToken.ival; return INT16CONSTANT; case PpAtomConstUint16: parserToken->sType.lex.i = ppToken.ival; return UINT16CONSTANT; case PpAtomConstInt64: parserToken->sType.lex.i64 = ppToken.i64val; return INT64CONSTANT; case PpAtomConstUint64: parserToken->sType.lex.i64 = ppToken.i64val; return UINT64CONSTANT; case PpAtomConstDouble: parserToken->sType.lex.d = ppToken.dval; return DOUBLECONSTANT; case PpAtomConstFloat16: parserToken->sType.lex.d = ppToken.dval; return FLOAT16CONSTANT; -#endif case PpAtomIdentifier: { int token = tokenizeIdentifier(); @@ -921,10 +924,8 @@ int TScanContext::tokenize(TPpContext* pp, TParserToken& token) int TScanContext::tokenizeIdentifier() { -#ifndef GLSLANG_WEB if (ReservedSet->find(tokenText) != ReservedSet->end()) return reservedWord(); -#endif auto it = KeywordMap->find(tokenText); if (it == KeywordMap->end()) { @@ -936,6 +937,7 @@ int TScanContext::tokenizeIdentifier() switch (keyword) { case CONST: case UNIFORM: + case TILEIMAGEEXT: case IN: case OUT: case INOUT: @@ -1046,7 +1048,6 @@ int TScanContext::tokenizeIdentifier() return identifierOrReserved(reserved); } -#ifndef GLSLANG_WEB case NOPERSPECTIVE: if (parseContext.extensionTurnedOn(E_GL_NV_shader_noperspective_interpolation)) return keyword; @@ -1072,12 +1073,18 @@ int TScanContext::tokenizeIdentifier() parseContext.extensionTurnedOn(E_GL_NV_ray_tracing)) return keyword; return identifierOrType(); + case ACCSTRUCTEXT: + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_EXT_ray_tracing) || + parseContext.extensionTurnedOn(E_GL_EXT_ray_query) || + parseContext.extensionTurnedOn(E_GL_NV_displacement_micromap)) + return keyword; + return identifierOrType(); case PAYLOADEXT: case PAYLOADINEXT: case HITATTREXT: case CALLDATAEXT: case CALLDATAINEXT: - case ACCSTRUCTEXT: if (parseContext.symbolTable.atBuiltInLevel() || parseContext.extensionTurnedOn(E_GL_EXT_ray_tracing) || parseContext.extensionTurnedOn(E_GL_EXT_ray_query)) @@ -1133,7 +1140,7 @@ int TScanContext::tokenizeIdentifier() case SUBROUTINE: return es30ReservedFromGLSL(400); -#endif + case SHARED: if ((parseContext.isEsProfile() && parseContext.version < 300) || (!parseContext.isEsProfile() && parseContext.version < 140)) @@ -1168,7 +1175,6 @@ int TScanContext::tokenizeIdentifier() case MAT4X4: return matNxM(); -#ifndef GLSLANG_WEB case DMAT2: case DMAT3: case DMAT4: @@ -1473,13 +1479,14 @@ int TScanContext::tokenizeIdentifier() return keyword; else return identifierOrType(); -#endif case UINT: case UVEC2: case UVEC3: case UVEC4: case SAMPLERCUBESHADOW: + case SAMPLER2DARRAY: + case SAMPLER2DARRAYSHADOW: case ISAMPLER2D: case ISAMPLER3D: case ISAMPLERCUBE: @@ -1489,6 +1496,12 @@ int TScanContext::tokenizeIdentifier() case USAMPLERCUBE: case USAMPLER2DARRAY: afterType = true; + if (keyword == SAMPLER2DARRAY || keyword == SAMPLER2DARRAYSHADOW) { + if ((keyword == SAMPLER2DARRAY || !parseContext.isEsProfile()) && + (parseContext.extensionTurnedOn(E_GL_EXT_texture_array) || parseContext.symbolTable.atBuiltInLevel())) { + return keyword; + } + } return nonreservedKeyword(300, 130); case SAMPLER3D: @@ -1526,12 +1539,18 @@ int TScanContext::tokenizeIdentifier() else return identifierOrType(); -#ifndef GLSLANG_WEB case ISAMPLER1D: case ISAMPLER1DARRAY: + case SAMPLER1DARRAYSHADOW: case USAMPLER1D: case USAMPLER1DARRAY: afterType = true; + if (keyword == SAMPLER1DARRAYSHADOW) { + if (!parseContext.isEsProfile() && + (parseContext.extensionTurnedOn(E_GL_EXT_texture_array) || parseContext.symbolTable.atBuiltInLevel())) { + return keyword; + } + } return es30ReservedFromGLSL(130); case ISAMPLER2DRECT: case USAMPLER2DRECT: @@ -1583,19 +1602,6 @@ int TScanContext::tokenizeIdentifier() reservedWord(); return keyword; - case SAMPLER2DARRAY: - case SAMPLER2DARRAYSHADOW: - afterType = true; - if (parseContext.symbolTable.atBuiltInLevel()) - return keyword; - else if (parseContext.version < 130 && ((parseContext.isEsProfile() && keyword != SAMPLER2DARRAY) || !parseContext.extensionsTurnedOn(1, &E_GL_EXT_texture_array))) { - if (parseContext.forwardCompatible) - parseContext.warn(loc, "using future keyword", tokenText, ""); - - return identifierOrType(); - } - return keyword; - case SAMPLER2DRECT: case SAMPLER2DRECTSHADOW: afterType = true; @@ -1610,20 +1616,14 @@ int TScanContext::tokenizeIdentifier() return keyword; case SAMPLER1DARRAY: - case SAMPLER1DARRAYSHADOW: afterType = true; - if (parseContext.symbolTable.atBuiltInLevel()) - return keyword; - if (parseContext.isEsProfile()) { - if (parseContext.version >= 300) - reservedWord(); - else - return identifierOrType(); - } else if (parseContext.version < 130 && !parseContext.extensionsTurnedOn(1, &E_GL_EXT_texture_array)) { - if (parseContext.forwardCompatible) - parseContext.warn(loc, "using future keyword", tokenText, ""); - return identifierOrType(); - } + if (parseContext.isEsProfile() && parseContext.version == 300) + reservedWord(); + else if ((parseContext.isEsProfile() && parseContext.version < 300) || + ((!parseContext.isEsProfile() && parseContext.version < 130) && + !parseContext.symbolTable.atBuiltInLevel() && + !parseContext.extensionTurnedOn(E_GL_EXT_texture_array))) + return identifierOrType(); return keyword; case SAMPLEREXTERNALOES: @@ -1670,6 +1670,9 @@ int TScanContext::tokenizeIdentifier() case ISUBPASSINPUTMS: case USUBPASSINPUT: case USUBPASSINPUTMS: + case ATTACHMENTEXT: + case IATTACHMENTEXT: + case UATTACHMENTEXT: if (parseContext.spvVersion.vulkan > 0) return keyword; else @@ -1737,6 +1740,12 @@ int TScanContext::tokenizeIdentifier() return keyword; return identifierOrType(); + case PERVERTEXEXT: + if ((!parseContext.isEsProfile() && parseContext.version >= 450) || + parseContext.extensionTurnedOn(E_GL_EXT_fragment_shader_barycentric)) + return keyword; + return identifierOrType(); + case PRECISE: if ((parseContext.isEsProfile() && (parseContext.version >= 320 || parseContext.extensionsTurnedOn(Num_AEP_gpu_shader5, AEP_gpu_shader5))) || @@ -1751,12 +1760,18 @@ int TScanContext::tokenizeIdentifier() case PERPRIMITIVENV: case PERVIEWNV: case PERTASKNV: - if ((!parseContext.isEsProfile() && parseContext.version >= 450) || - (parseContext.isEsProfile() && parseContext.version >= 320) || + if (parseContext.symbolTable.atBuiltInLevel() || parseContext.extensionTurnedOn(E_GL_NV_mesh_shader)) return keyword; return identifierOrType(); + case PERPRIMITIVEEXT: + case TASKPAYLOADWORKGROUPEXT: + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_EXT_mesh_shader)) + return keyword; + return identifierOrType(); + case FCOOPMATNV: afterType = true; if (parseContext.symbolTable.atBuiltInLevel() || @@ -1772,6 +1787,13 @@ int TScanContext::tokenizeIdentifier() return keyword; return identifierOrType(); + case COOPMAT: + afterType = true; + if (parseContext.symbolTable.atBuiltInLevel() || + parseContext.extensionTurnedOn(E_GL_KHR_cooperative_matrix)) + return keyword; + return identifierOrType(); + case DEMOTE: if (parseContext.extensionTurnedOn(E_GL_EXT_demote_to_helper_invocation)) return keyword; @@ -1792,7 +1814,20 @@ int TScanContext::tokenizeIdentifier() parseContext.extensionTurnedOn(E_GL_EXT_spirv_intrinsics)) return keyword; return identifierOrType(); -#endif + + case HITOBJECTNV: + if (parseContext.symbolTable.atBuiltInLevel() || + (!parseContext.isEsProfile() && parseContext.version >= 460 + && parseContext.extensionTurnedOn(E_GL_NV_shader_invocation_reorder))) + return keyword; + return identifierOrType(); + + case HITOBJECTATTRNV: + if (parseContext.symbolTable.atBuiltInLevel() || + (!parseContext.isEsProfile() && parseContext.version >= 460 + && parseContext.extensionTurnedOn(E_GL_NV_shader_invocation_reorder))) + return keyword; + return identifierOrType(); default: parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc); diff --git a/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp b/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp index 7407b4a0c..406532463 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/ShaderLang.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include "SymbolTable.h" #include "ParseHelper.h" #include "Scan.h" @@ -57,7 +58,6 @@ #endif #include "../Include/ShHandle.h" -#include "../../OGLCompilersDLL/InitializeDll.h" #include "preprocessor/PpContext.h" @@ -81,6 +81,9 @@ namespace { // anonymous namespace for file-local functions and symbols // Shared global; access should be protected by a global mutex/critical section. int NumberOfClients = 0; +// global initialization lock +std::mutex init_lock; + using namespace glslang; // Create a language specific version of parseables. @@ -295,14 +298,6 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi EShLanguage language, EShSource source, TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables) { -#ifdef GLSLANG_WEB - profile = EEsProfile; - version = 310; -#elif defined(GLSLANG_ANGLE) - profile = ECoreProfile; - version = 450; -#endif - (*symbolTables[language]).adoptLevels(*commonTable[CommonIndex(profile, language)]); InitializeSymbolTable(builtInParseables.getStageString(language), version, profile, spvVersion, language, source, infoSink, *symbolTables[language]); @@ -319,14 +314,6 @@ void InitializeStageSymbolTable(TBuiltInParseables& builtInParseables, int versi // bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TSymbolTable** symbolTables, int version, EProfile profile, const SpvVersion& spvVersion, EShSource source) { -#ifdef GLSLANG_WEB - profile = EEsProfile; - version = 310; -#elif defined(GLSLANG_ANGLE) - profile = ECoreProfile; - version = 450; -#endif - std::unique_ptr builtInParseables(CreateBuiltInParseables(infoSink, source)); if (builtInParseables == nullptr) @@ -349,7 +336,6 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangFragment, source, infoSink, commonTable, symbolTables); -#ifndef GLSLANG_WEB // check for tessellation if ((profile != EEsProfile && version >= 150) || (profile == EEsProfile && version >= 310)) { @@ -371,7 +357,6 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangCompute, source, infoSink, commonTable, symbolTables); -#ifndef GLSLANG_ANGLE // check for ray tracing stages if (profile != EEsProfile && version >= 450) { InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangRayGen, source, @@ -391,16 +376,14 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS // check for mesh if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMeshNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangMesh, source, infoSink, commonTable, symbolTables); // check for task if ((profile != EEsProfile && version >= 450) || (profile == EEsProfile && version >= 320)) - InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTaskNV, source, + InitializeStageSymbolTable(*builtInParseables, version, profile, spvVersion, EShLangTask, source, infoSink, commonTable, symbolTables); -#endif // !GLSLANG_ANGLE -#endif // !GLSLANG_WEB return true; } @@ -437,18 +420,15 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp TInfoSink infoSink; // Make sure only one thread tries to do this at a time - glslang::GetGlobalLock(); + const std::lock_guard lock(init_lock); // See if it's already been done for this version/profile combination int versionIndex = MapVersionToIndex(version); int spvVersionIndex = MapSpvVersionToIndex(spvVersion); int profileIndex = MapProfileToIndex(profile); int sourceIndex = MapSourceToIndex(source); - if (CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][EPcGeneral]) { - glslang::ReleaseGlobalLock(); - + if (CommonSymbolTable[versionIndex][spvVersionIndex][profileIndex][sourceIndex][EPcGeneral]) return; - } // Switch to a new pool TPoolAllocator& previousAllocator = GetThreadPoolAllocator(); @@ -495,20 +475,16 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp delete builtInPoolAllocator; SetThreadPoolAllocator(&previousAllocator); - - glslang::ReleaseGlobalLock(); } // Function to Print all builtins void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable) { -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) infoSink.debug << "BuiltinSymbolTable {\n"; symbolTable.dump(infoSink, true); infoSink.debug << "}\n"; -#endif } // Return true if the shader was correctly specified for version/profile/stage. @@ -606,7 +582,6 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo break; } -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // Correct for stage type... switch (stage) { case EShLangGeometry: @@ -650,8 +625,8 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo version = 460; } break; - case EShLangMeshNV: - case EShLangTaskNV: + case EShLangMesh: + case EShLangTask: if ((profile == EEsProfile && version < 320) || (profile != EEsProfile && version < 450)) { correct = false; @@ -694,7 +669,6 @@ bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNo break; } } -#endif return correct; } @@ -813,6 +787,7 @@ bool ProcessDeferred( // set version/profile to defaultVersion/defaultProfile regardless of the #version // directive in the source code bool forceDefaultVersionAndProfile, + int overrideVersion, // overrides version specified by #verison or default version bool forwardCompatible, // give errors for use of deprecated features EShMessages messages, // warnings/errors/AST; things to print out TIntermediate& intermediate, // returned tree, etc. @@ -820,7 +795,8 @@ bool ProcessDeferred( bool requireNonempty, TShader::Includer& includer, const std::string sourceEntryPointName = "", - const TEnvironment* environment = nullptr) // optional way of fully setting all versions, overriding the above + const TEnvironment* environment = nullptr, // optional way of fully setting all versions, overriding the above + bool compileOnly = false) { // This must be undone (.pop()) by the caller, after it finishes consuming the created tree. GetThreadPoolAllocator().push(); @@ -883,7 +859,6 @@ bool ProcessDeferred( : userInput.scanVersion(version, profile, versionNotFirstToken); bool versionNotFound = version == 0; if (forceDefaultVersionAndProfile && source == EShSourceGlsl) { -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) if (! (messages & EShMsgSuppressWarnings) && ! versionNotFound && (version != defaultVersion || profile != defaultProfile)) { compiler->infoSink.info << "Warning, (version, profile) forced to be (" @@ -891,7 +866,7 @@ bool ProcessDeferred( << "), while in source code it is (" << version << ", " << ProfileName(profile) << ")\n"; } -#endif + if (versionNotFound) { versionNotFirstToken = false; versionNotFirst = false; @@ -900,19 +875,13 @@ bool ProcessDeferred( version = defaultVersion; profile = defaultProfile; } + if (source == EShSourceGlsl && overrideVersion != 0) { + version = overrideVersion; + } bool goodVersion = DeduceVersionProfile(compiler->infoSink, stage, versionNotFirst, defaultVersion, source, version, profile, spvVersion); -#ifdef GLSLANG_WEB - profile = EEsProfile; - version = 310; -#elif defined(GLSLANG_ANGLE) - profile = ECoreProfile; - version = 450; -#endif - bool versionWillBeError = (versionNotFound || (profile == EEsProfile && version >= 300 && versionNotFirst)); -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) bool warnVersionNotFirst = false; if (! versionWillBeError && versionNotFirstToken) { if (messages & EShMsgRelaxedErrors) @@ -920,7 +889,6 @@ bool ProcessDeferred( else versionWillBeError = true; } -#endif intermediate.setSource(source); intermediate.setVersion(version); @@ -974,6 +942,7 @@ bool ProcessDeferred( std::unique_ptr parseContext(CreateParseContext(*symbolTable, intermediate, version, profile, source, stage, compiler->infoSink, spvVersion, forwardCompatible, messages, false, sourceEntryPointName)); + parseContext->compileOnly = compileOnly; TPpContext ppContext(*parseContext, names[numPre] ? names[numPre] : "", includer); // only GLSL (bison triggered, really) needs an externally set scan context @@ -985,13 +954,11 @@ bool ProcessDeferred( parseContext->setLimits(*resources); if (! goodVersion) parseContext->addError(); -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) if (warnVersionNotFirst) { TSourceLoc loc; loc.init(); parseContext->warn(loc, "Illegal to have non-comment, non-whitespace tokens before #version", "#version", ""); } -#endif parseContext->initializeExtensionBehavior(); @@ -1023,8 +990,6 @@ bool ProcessDeferred( return success; } -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) - // Responsible for keeping track of the most recent source string and line in // the preprocessor and outputting newlines appropriately if the source string // or line changes. @@ -1102,8 +1067,8 @@ struct DoPreprocessing { EShOptimizationLevel, EShMessages) { // This is a list of tokens that do not require a space before or after. - static const std::string unNeededSpaceTokens = ";()[]"; - static const std::string noSpaceBeforeTokens = ","; + static const std::string noNeededSpaceBeforeTokens = ";)[].,"; + static const std::string noNeededSpaceAfterTokens = ".(["; glslang::TPpToken ppToken; parseContext.setScanner(&input); @@ -1176,6 +1141,7 @@ struct DoPreprocessing { }); int lastToken = EndOfInput; // lastToken records the last token processed. + std::string lastTokenName; do { int token = ppContext.tokenize(ppToken); if (token == EndOfInput) @@ -1194,12 +1160,23 @@ struct DoPreprocessing { // Output a space in between tokens, but not at the start of a line, // and also not around special tokens. This helps with readability // and consistency. - if (!isNewString && !isNewLine && lastToken != EndOfInput && - (unNeededSpaceTokens.find((char)token) == std::string::npos) && - (unNeededSpaceTokens.find((char)lastToken) == std::string::npos) && - (noSpaceBeforeTokens.find((char)token) == std::string::npos)) { - outputBuffer += ' '; + if (!isNewString && !isNewLine && lastToken != EndOfInput) { + // left parenthesis need a leading space, except it is in a function-call-like context. + // examples: `for (xxx)`, `a * (b + c)`, `vec(2.0)`, `foo(x, y, z)` + if (token == '(') { + if (lastToken != PpAtomIdentifier || + lastTokenName == "if" || + lastTokenName == "for" || + lastTokenName == "while" || + lastTokenName == "switch") + outputBuffer += ' '; + } else if ((noNeededSpaceBeforeTokens.find((char)token) == std::string::npos) && + (noNeededSpaceAfterTokens.find((char)lastToken) == std::string::npos)) { + outputBuffer += ' '; + } } + if (token == PpAtomIdentifier) + lastTokenName = ppToken.name; lastToken = token; if (token == PpAtomConstString) outputBuffer += "\""; @@ -1221,8 +1198,6 @@ struct DoPreprocessing { std::string* outputString; }; -#endif - // DoFullParse is a valid ProcessingConext template argument for fully // parsing the shader. It populates the "intermediate" with the AST. struct DoFullParse{ @@ -1246,16 +1221,13 @@ struct DoFullParse{ parseContext.infoSink.info << parseContext.getNumErrors() << " compilation errors. No code generated.\n\n"; } -#ifndef GLSLANG_ANGLE if (messages & EShMsgAST) intermediate.output(parseContext.infoSink, true); -#endif return success; } }; -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // Take a single compilation unit, and run the preprocessor on it. // Return: True if there were no issues found in preprocessing, // False if during preprocessing any unknown version, pragmas or @@ -1275,6 +1247,7 @@ bool PreprocessDeferred( int defaultVersion, // use 100 for ES environment, 110 for desktop EProfile defaultProfile, bool forceDefaultVersionAndProfile, + int overrideVersion, // use 0 if not overriding GLSL version bool forwardCompatible, // give errors for use of deprecated features EShMessages messages, // warnings/errors/AST; things to print out TShader::Includer& includer, @@ -1285,11 +1258,10 @@ bool PreprocessDeferred( DoPreprocessing parser(outputString); return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames, preamble, optLevel, resources, defaultVersion, - defaultProfile, forceDefaultVersionAndProfile, + defaultProfile, forceDefaultVersionAndProfile, overrideVersion, forwardCompatible, messages, intermediate, parser, false, includer, "", environment); } -#endif // // do a partial compile on the given strings for a single compilation unit @@ -1314,19 +1286,21 @@ bool CompileDeferred( int defaultVersion, // use 100 for ES environment, 110 for desktop EProfile defaultProfile, bool forceDefaultVersionAndProfile, + int overrideVersion, // use 0 if not overriding GLSL version bool forwardCompatible, // give errors for use of deprecated features EShMessages messages, // warnings/errors/AST; things to print out TIntermediate& intermediate,// returned tree, etc. TShader::Includer& includer, const std::string sourceEntryPointName = "", - TEnvironment* environment = nullptr) + TEnvironment* environment = nullptr, + bool compileOnly = false) { DoFullParse parser; return ProcessDeferred(compiler, shaderStrings, numStrings, inputLengths, stringNames, preamble, optLevel, resources, defaultVersion, - defaultProfile, forceDefaultVersionAndProfile, + defaultProfile, forceDefaultVersionAndProfile, overrideVersion, forwardCompatible, messages, intermediate, parser, - true, includer, sourceEntryPointName, environment); + true, includer, sourceEntryPointName, environment, compileOnly); } } // end anonymous namespace for local functions @@ -1336,12 +1310,7 @@ bool CompileDeferred( // int ShInitialize() { - glslang::InitGlobalLock(); - - if (! InitProcess()) - return 0; - - glslang::GetGlobalLock(); + const std::lock_guard lock(init_lock); ++NumberOfClients; if (PerProcessGPA == nullptr) @@ -1352,7 +1321,6 @@ int ShInitialize() glslang::HlslScanContext::fillInKeywordMap(); #endif - glslang::ReleaseGlobalLock(); return 1; } @@ -1361,31 +1329,22 @@ int ShInitialize() // objects. // -ShHandle ShConstructCompiler(const EShLanguage language, int debugOptions) +ShHandle ShConstructCompiler(const EShLanguage language, int /*debugOptions unused*/) { - if (!InitThread()) - return 0; - - TShHandleBase* base = static_cast(ConstructCompiler(language, debugOptions)); + TShHandleBase* base = static_cast(ConstructCompiler(language, 0)); return reinterpret_cast(base); } -ShHandle ShConstructLinker(const EShExecutable executable, int debugOptions) +ShHandle ShConstructLinker(const EShExecutable executable, int /*debugOptions unused*/) { - if (!InitThread()) - return 0; - - TShHandleBase* base = static_cast(ConstructLinker(executable, debugOptions)); + TShHandleBase* base = static_cast(ConstructLinker(executable, 0)); return reinterpret_cast(base); } ShHandle ShConstructUniformMap() { - if (!InitThread()) - return 0; - TShHandleBase* base = static_cast(ConstructUniformMap()); return reinterpret_cast(base); @@ -1393,7 +1352,7 @@ ShHandle ShConstructUniformMap() void ShDestruct(ShHandle handle) { - if (handle == 0) + if (handle == nullptr) return; TShHandleBase* base = static_cast(handle); @@ -1411,14 +1370,11 @@ void ShDestruct(ShHandle handle) // int ShFinalize() { - glslang::GetGlobalLock(); + const std::lock_guard lock(init_lock); --NumberOfClients; assert(NumberOfClients >= 0); - bool finalize = NumberOfClients == 0; - if (! finalize) { - glslang::ReleaseGlobalLock(); + if (NumberOfClients > 0) return 1; - } for (int version = 0; version < VersionCount; ++version) { for (int spvVersion = 0; spvVersion < SpvVersionCount; ++spvVersion) { @@ -1426,7 +1382,7 @@ int ShFinalize() for (int source = 0; source < SourceCount; ++source) { for (int stage = 0; stage < EShLangCount; ++stage) { delete SharedSymbolTables[version][spvVersion][p][source][stage]; - SharedSymbolTables[version][spvVersion][p][source][stage] = 0; + SharedSymbolTables[version][spvVersion][p][source][stage] = nullptr; } } } @@ -1439,7 +1395,7 @@ int ShFinalize() for (int source = 0; source < SourceCount; ++source) { for (int pc = 0; pc < EPcCount; ++pc) { delete CommonSymbolTable[version][spvVersion][p][source][pc]; - CommonSymbolTable[version][spvVersion][p][source][pc] = 0; + CommonSymbolTable[version][spvVersion][p][source][pc] = nullptr; } } } @@ -1456,7 +1412,6 @@ int ShFinalize() glslang::HlslScanContext::deleteKeywordMap(); #endif - glslang::ReleaseGlobalLock(); return 1; } @@ -1482,12 +1437,12 @@ int ShCompile( ) { // Map the generic handle to the C++ object - if (handle == 0) + if (handle == nullptr) return 0; TShHandleBase* base = reinterpret_cast(handle); TCompiler* compiler = base->getAsCompiler(); - if (compiler == 0) + if (compiler == nullptr) return 0; SetThreadPoolAllocator(compiler->getPool()); @@ -1498,7 +1453,7 @@ int ShCompile( TIntermediate intermediate(compiler->getLanguage()); TShader::ForbidIncluder includer; bool success = CompileDeferred(compiler, shaderStrings, numStrings, inputLengths, nullptr, - "", optLevel, resources, defaultVersion, ENoProfile, false, + "", optLevel, resources, defaultVersion, ENoProfile, false, 0, forwardCompatible, messages, intermediate, includer); // @@ -1527,13 +1482,13 @@ int ShLinkExt( const ShHandle compHandles[], const int numHandles) { - if (linkHandle == 0 || numHandles == 0) + if (linkHandle == nullptr || numHandles == 0) return 0; THandleList cObjects; for (int i = 0; i < numHandles; ++i) { - if (compHandles[i] == 0) + if (compHandles[i] == nullptr) return 0; TShHandleBase* base = reinterpret_cast(compHandles[i]); if (base->getAsLinker()) { @@ -1542,18 +1497,17 @@ int ShLinkExt( if (base->getAsCompiler()) cObjects.push_back(base->getAsCompiler()); - if (cObjects[i] == 0) + if (cObjects[i] == nullptr) return 0; } TShHandleBase* base = reinterpret_cast(linkHandle); TLinker* linker = static_cast(base->getAsLinker()); - SetThreadPoolAllocator(linker->getPool()); - - if (linker == 0) + if (linker == nullptr) return 0; - + + SetThreadPoolAllocator(linker->getPool()); linker->infoSink.info.erase(); for (int i = 0; i < numHandles; ++i) { @@ -1576,7 +1530,7 @@ int ShLinkExt( // void ShSetEncryptionMethod(ShHandle handle) { - if (handle == 0) + if (handle == nullptr) return; } @@ -1585,8 +1539,8 @@ void ShSetEncryptionMethod(ShHandle handle) // const char* ShGetInfoLog(const ShHandle handle) { - if (handle == 0) - return 0; + if (handle == nullptr) + return nullptr; TShHandleBase* base = static_cast(handle); TInfoSink* infoSink; @@ -1596,7 +1550,7 @@ const char* ShGetInfoLog(const ShHandle handle) else if (base->getAsLinker()) infoSink = &(base->getAsLinker()->getInfoSink()); else - return 0; + return nullptr; infoSink->info << infoSink->debug.c_str(); return infoSink->info.c_str(); @@ -1608,14 +1562,14 @@ const char* ShGetInfoLog(const ShHandle handle) // const void* ShGetExecutable(const ShHandle handle) { - if (handle == 0) - return 0; + if (handle == nullptr) + return nullptr; TShHandleBase* base = reinterpret_cast(handle); TLinker* linker = static_cast(base->getAsLinker()); - if (linker == 0) - return 0; + if (linker == nullptr) + return nullptr; return linker->getObjectCode(); } @@ -1630,13 +1584,13 @@ const void* ShGetExecutable(const ShHandle handle) // int ShSetVirtualAttributeBindings(const ShHandle handle, const ShBindingTable* table) { - if (handle == 0) + if (handle == nullptr) return 0; TShHandleBase* base = reinterpret_cast(handle); TLinker* linker = static_cast(base->getAsLinker()); - if (linker == 0) + if (linker == nullptr) return 0; linker->setAppAttributeBindings(table); @@ -1649,13 +1603,13 @@ int ShSetVirtualAttributeBindings(const ShHandle handle, const ShBindingTable* t // int ShSetFixedAttributeBindings(const ShHandle handle, const ShBindingTable* table) { - if (handle == 0) + if (handle == nullptr) return 0; TShHandleBase* base = reinterpret_cast(handle); TLinker* linker = static_cast(base->getAsLinker()); - if (linker == 0) + if (linker == nullptr) return 0; linker->setFixedAttributeBindings(table); @@ -1667,12 +1621,12 @@ int ShSetFixedAttributeBindings(const ShHandle handle, const ShBindingTable* tab // int ShExcludeAttributes(const ShHandle handle, int *attributes, int count) { - if (handle == 0) + if (handle == nullptr) return 0; TShHandleBase* base = reinterpret_cast(handle); TLinker* linker = static_cast(base->getAsLinker()); - if (linker == 0) + if (linker == nullptr) return 0; linker->setExcludedAttributes(attributes, count); @@ -1688,12 +1642,12 @@ int ShExcludeAttributes(const ShHandle handle, int *attributes, int count) // int ShGetUniformLocation(const ShHandle handle, const char* name) { - if (handle == 0) + if (handle == nullptr) return -1; TShHandleBase* base = reinterpret_cast(handle); TUniformMap* uniformMap= base->getAsUniformMap(); - if (uniformMap == 0) + if (uniformMap == nullptr) return -1; return uniformMap->getLocation(name); @@ -1759,7 +1713,7 @@ class TDeferredCompiler : public TCompiler { }; TShader::TShader(EShLanguage s) - : stage(s), lengths(nullptr), stringNames(nullptr), preamble("") + : stage(s), lengths(nullptr), stringNames(nullptr), preamble(""), overrideVersion(0) { pool = new TPoolAllocator; infoSink = new TInfoSink; @@ -1828,12 +1782,17 @@ void TShader::setUniqueId(unsigned long long id) intermediate->setUniqueId(id); } +void TShader::setOverrideVersion(int version) +{ + overrideVersion = version; +} + +void TShader::setDebugInfo(bool debugInfo) { intermediate->setDebugInfo(debugInfo); } void TShader::setInvertY(bool invert) { intermediate->setInvertY(invert); } void TShader::setDxPositionW(bool invert) { intermediate->setDxPositionW(invert); } +void TShader::setEnhancedMsgs() { intermediate->setEnhancedMsgs(); } void TShader::setNanMinMaxClamp(bool useNonNan) { intermediate->setNanMinMaxClamp(useNonNan); } -#ifndef GLSLANG_WEB - // Set binding base for given resource type void TShader::setShiftBinding(TResourceType res, unsigned int base) { intermediate->setShiftBinding(res, base); @@ -1875,7 +1834,6 @@ void TShader::setUniformLocationBase(int base) void TShader::setNoStorageFormat(bool useUnknownFormat) { intermediate->setNoStorageFormat(useUnknownFormat); } void TShader::setResourceSetBinding(const std::vector& base) { intermediate->setResourceSetBinding(base); } void TShader::setTextureSamplerTransformMode(EShTextureSamplerTransformMode mode) { intermediate->setTextureSamplerTransformMode(mode); } -#endif void TShader::addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing) { intermediate->addBlockStorageOverride(nameStr, backing); } @@ -1900,8 +1858,6 @@ void TShader::setFlattenUniformArrays(bool flatten) { intermediate->setFlatt bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion, EProfile defaultProfile, bool forceDefaultVersionAndProfile, bool forwardCompatible, EShMessages messages, Includer& includer) { - if (! InitThread()) - return false; SetThreadPoolAllocator(pool); if (! preamble) @@ -1909,12 +1865,11 @@ bool TShader::parse(const TBuiltInResource* builtInResources, int defaultVersion return CompileDeferred(compiler, strings, numStrings, lengths, stringNames, preamble, EShOptNone, builtInResources, defaultVersion, - defaultProfile, forceDefaultVersionAndProfile, + defaultProfile, forceDefaultVersionAndProfile, overrideVersion, forwardCompatible, messages, *intermediate, includer, sourceEntryPointName, - &environment); + &environment, compileOnly); } -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) // Fill in a string with the result of preprocessing ShaderStrings // Returns true if all extensions, pragmas and version strings were valid. // @@ -1927,8 +1882,6 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources, std::string* output_string, Includer& includer) { - if (! InitThread()) - return false; SetThreadPoolAllocator(pool); if (! preamble) @@ -1936,11 +1889,10 @@ bool TShader::preprocess(const TBuiltInResource* builtInResources, return PreprocessDeferred(compiler, strings, numStrings, lengths, stringNames, preamble, EShOptNone, builtInResources, defaultVersion, - defaultProfile, forceDefaultVersionAndProfile, + defaultProfile, forceDefaultVersionAndProfile, overrideVersion, forwardCompatible, message, includer, *intermediate, output_string, &environment); } -#endif const char* TShader::getInfoLog() { @@ -1952,16 +1904,12 @@ const char* TShader::getInfoDebugLog() return infoSink->debug.c_str(); } -TProgram::TProgram() : -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) - reflection(0), -#endif - linked(false) +TProgram::TProgram() : reflection(nullptr), linked(false) { pool = new TPoolAllocator; infoSink = new TInfoSink; for (int s = 0; s < EShLangCount; ++s) { - intermediate[s] = 0; + intermediate[s] = nullptr; newedIntermediate[s] = false; } } @@ -1969,9 +1917,7 @@ TProgram::TProgram() : TProgram::~TProgram() { delete infoSink; -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) delete reflection; -#endif for (int s = 0; s < EShLangCount; ++s) if (newedIntermediate[s]) @@ -2019,7 +1965,6 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) if (stages[stage].size() == 0) return true; -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) int numEsShaders = 0, numNonEsShaders = 0; for (auto it = stages[stage].begin(); it != stages[stage].end(); ++it) { if ((*it)->intermediate->getProfile() == EEsProfile) { @@ -2049,6 +1994,8 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) firstIntermediate->getVersion(), firstIntermediate->getProfile()); intermediate[stage]->setLimits(firstIntermediate->getLimits()); + if (firstIntermediate->getEnhancedMsgs()) + intermediate[stage]->setEnhancedMsgs(); // The new TIntermediate must use the same origin as the original TIntermediates. // Otherwise linking will fail due to different coordinate systems. @@ -2068,15 +2015,10 @@ bool TProgram::linkStage(EShLanguage stage, EShMessages messages) for (it = stages[stage].begin(); it != stages[stage].end(); ++it) intermediate[stage]->merge(*infoSink, *(*it)->intermediate); } -#else - intermediate[stage] = stages[stage].front()->intermediate; -#endif intermediate[stage]->finalCheck(*infoSink, (messages & EShMsgKeepUncalled) != 0); -#ifndef GLSLANG_ANGLE if (messages & EShMsgAST) intermediate[stage]->output(*infoSink, true); -#endif return intermediate[stage]->getNumErrors() == 0; } @@ -2154,8 +2096,6 @@ const char* TProgram::getInfoDebugLog() return infoSink->debug.c_str(); } -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) - // // Reflection implementation. // @@ -2236,6 +2176,4 @@ bool TProgram::mapIO(TIoMapResolver* pResolver, TIoMapper* pIoMapper) return ioMapper->doMap(pResolver, *infoSink); } -#endif // !GLSLANG_WEB && !GLSLANG_ANGLE - } // end namespace glslang diff --git a/src/libraries/glslang/glslang/MachineIndependent/SpirvIntrinsics.cpp b/src/libraries/glslang/glslang/MachineIndependent/SpirvIntrinsics.cpp index 6650f7d9e..1d08797ac 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/SpirvIntrinsics.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/SpirvIntrinsics.cpp @@ -33,8 +33,6 @@ // POSSIBILITY OF SUCH DAMAGE. // -#ifndef GLSLANG_WEB - // // GL_EXT_spirv_intrinsics // @@ -45,6 +43,15 @@ namespace glslang { +bool TSpirvTypeParameter::operator==(const TSpirvTypeParameter& rhs) const +{ + if (getAsConstant() != nullptr) + return getAsConstant()->getConstArray() == rhs.getAsConstant()->getConstArray(); + + assert(getAsType() != nullptr); + return *getAsType() == *rhs.getAsType(); +} + // // Handle SPIR-V requirements // @@ -67,7 +74,7 @@ TSpirvRequirement* TParseContext::makeSpirvRequirement(const TSourceLoc& loc, co spirvReq->capabilities.insert(capability->getAsConstantUnion()->getConstArray()[0].getIConst()); } } else - error(loc, "unknow SPIR-V requirement", name.c_str(), ""); + error(loc, "unknown SPIR-V requirement", name.c_str(), ""); return spirvReq; } @@ -168,7 +175,7 @@ void TQualifier::setSpirvDecorateId(int decoration, const TIntermAggregate* args TVector extraOperands; for (auto arg : args->getSequence()) { auto extraOperand = arg->getAsTyped(); - assert(extraOperand != nullptr && extraOperand->getQualifier().isConstant()); + assert(extraOperand != nullptr); extraOperands.push_back(extraOperand); } spirvDecorate->decorateIds[decoration] = extraOperands; @@ -202,30 +209,29 @@ TString TQualifier::getSpirvDecorateQualifierString() const const auto appendStr = [&](const char* s) { qualifierString.append(s); }; const auto appendDecorate = [&](const TIntermTyped* constant) { - auto& constArray = constant->getAsConstantUnion() != nullptr ? constant->getAsConstantUnion()->getConstArray() - : constant->getAsSymbolNode()->getConstArray(); - if (constant->getBasicType() == EbtFloat) { - float value = static_cast(constArray[0].getDConst()); - appendFloat(value); - } - else if (constant->getBasicType() == EbtInt) { - int value = constArray[0].getIConst(); - appendInt(value); - } - else if (constant->getBasicType() == EbtUint) { - unsigned value = constArray[0].getUConst(); - appendUint(value); - } - else if (constant->getBasicType() == EbtBool) { - bool value = constArray[0].getBConst(); - appendBool(value); + if (constant->getAsConstantUnion()) { + auto& constArray = constant->getAsConstantUnion()->getConstArray(); + if (constant->getBasicType() == EbtFloat) { + float value = static_cast(constArray[0].getDConst()); + appendFloat(value); + } else if (constant->getBasicType() == EbtInt) { + int value = constArray[0].getIConst(); + appendInt(value); + } else if (constant->getBasicType() == EbtUint) { + unsigned value = constArray[0].getUConst(); + appendUint(value); + } else if (constant->getBasicType() == EbtBool) { + bool value = constArray[0].getBConst(); + appendBool(value); + } else if (constant->getBasicType() == EbtString) { + const TString* value = constArray[0].getSConst(); + appendStr(value->c_str()); + } else + assert(0); + } else { + assert(constant->getAsSymbolNode()); + appendStr(constant->getAsSymbolNode()->getName().c_str()); } - else if (constant->getBasicType() == EbtString) { - const TString* value = constArray[0].getSConst(); - appendStr(value->c_str()); - } - else - assert(0); }; for (auto& decorate : spirvDecorate->decorates) { @@ -284,14 +290,20 @@ TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TSourceLoc& l constant->getBasicType() != EbtBool && constant->getBasicType() != EbtString) error(loc, "this type not allowed", constant->getType().getBasicString(), ""); - else { - assert(constant); + else spirvTypeParams->push_back(TSpirvTypeParameter(constant)); - } return spirvTypeParams; } +TSpirvTypeParameters* TParseContext::makeSpirvTypeParameters(const TSourceLoc& /* loc */, + const TPublicType& type) +{ + TSpirvTypeParameters* spirvTypeParams = new TSpirvTypeParameters; + spirvTypeParams->push_back(TSpirvTypeParameter(new TType(type))); + return spirvTypeParams; +} + TSpirvTypeParameters* TParseContext::mergeSpirvTypeParameters(TSpirvTypeParameters* spirvTypeParams1, TSpirvTypeParameters* spirvTypeParams2) { // Merge SPIR-V type parameters of the second one to the first one @@ -346,5 +358,3 @@ TSpirvInstruction* TParseContext::mergeSpirvInstruction(const TSourceLoc& loc, T } } // end namespace glslang - -#endif // GLSLANG_WEB diff --git a/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp b/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp index a3ffa0c46..dae5a8b91 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.cpp @@ -65,7 +65,6 @@ void TType::buildMangledName(TString& mangledName) const case EbtInt: mangledName += 'i'; 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; @@ -78,12 +77,10 @@ void TType::buildMangledName(TString& mangledName) const case EbtAccStruct: mangledName += "as"; break; case EbtRayQuery: mangledName += "rq"; break; case EbtSpirvType: mangledName += "spv-t"; break; -#endif + case EbtHitObjectNV: mangledName += "ho"; break; case EbtSampler: switch (sampler.type) { -#ifndef GLSLANG_WEB case EbtFloat16: mangledName += "f16"; break; -#endif case EbtInt: mangledName += "i"; break; case EbtUint: mangledName += "u"; break; case EbtInt64: mangledName += "i64"; break; @@ -110,12 +107,10 @@ void TType::buildMangledName(TString& mangledName) const case Esd2D: mangledName += "2"; break; case Esd3D: mangledName += "3"; break; case EsdCube: mangledName += "C"; break; -#ifndef GLSLANG_WEB case Esd1D: mangledName += "1"; break; case EsdRect: mangledName += "R2"; break; case EsdBuffer: mangledName += "B"; break; case EsdSubpass: mangledName += "P"; break; -#endif default: break; // some compilers want this } @@ -183,8 +178,6 @@ void TType::buildMangledName(TString& mangledName) const } } -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) - // // Dump functions. // @@ -263,8 +256,6 @@ void TSymbolTable::dump(TInfoSink& infoSink, bool complete) const } } -#endif - // // Functions have buried pointers to delete. // @@ -327,6 +318,16 @@ void TSymbolTableLevel::setFunctionExtensions(const char* name, int num, const c } } +// Make a single function require an extension(s). i.e., this will only set the extensions for the symbol that matches 'name' exactly. +// This is different from setFunctionExtensions, which uses std::map::lower_bound to effectively set all symbols that start with 'name'. +// Should only be used for a version/profile that actually needs the extension(s). +void TSymbolTableLevel::setSingleFunctionExtensions(const char* name, int num, const char* const extensions[]) +{ + if (auto candidate = level.find(name); candidate != level.end()) { + candidate->second->setExtensions(num, extensions); + } +} + // // Make all symbols in this table level read only. // @@ -381,9 +382,9 @@ TVariable* TVariable::clone() const TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf) { for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) { - TParameter param; + TParameter param{}; parameters.push_back(param); - parameters.back().copyParam(copyOf.parameters[i]); + (void)parameters.back().copyParam(copyOf.parameters[i]); } extensions = nullptr; @@ -397,9 +398,7 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf) implicitThis = copyOf.implicitThis; illegalImplicitThis = copyOf.illegalImplicitThis; defaultParamCount = copyOf.defaultParamCount; -#ifndef GLSLANG_WEB spirvInst = copyOf.spirvInst; -#endif } TFunction* TFunction::clone() const @@ -416,7 +415,7 @@ TAnonMember* TAnonMember::clone() const // copy of the original container. assert(0); - return 0; + return nullptr; } TSymbolTableLevel* TSymbolTableLevel::clone() const diff --git a/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h b/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h index 31312ecba..94c3929da 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h +++ b/src/libraries/glslang/glslang/MachineIndependent/SymbolTable.h @@ -84,7 +84,7 @@ typedef TVector TExtensionList; class TSymbol { public: POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) - explicit TSymbol(const TString *n) : name(n), uniqueId(0), extensions(0), writable(true) { } + explicit TSymbol(const TString *n) : name(n), uniqueId(0), extensions(nullptr), writable(true) { } virtual TSymbol* clone() const = 0; virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool @@ -97,18 +97,18 @@ class TSymbol { changeName(NewPoolTString(newName.c_str())); } virtual const TString& getMangledName() const { return getName(); } - virtual TFunction* getAsFunction() { return 0; } - virtual const TFunction* getAsFunction() const { return 0; } - virtual TVariable* getAsVariable() { return 0; } - virtual const TVariable* getAsVariable() const { return 0; } - virtual const TAnonMember* getAsAnonMember() const { return 0; } + virtual TFunction* getAsFunction() { return nullptr; } + virtual const TFunction* getAsFunction() const { return nullptr; } + virtual TVariable* getAsVariable() { return nullptr; } + virtual const TVariable* getAsVariable() const { return nullptr; } + virtual const TAnonMember* getAsAnonMember() const { return nullptr; } virtual const TType& getType() const = 0; virtual TType& getWritableType() = 0; virtual void setUniqueId(long long id) { uniqueId = id; } virtual long long getUniqueId() const { return uniqueId; } virtual void setExtensions(int numExts, const char* const exts[]) { - assert(extensions == 0); + assert(extensions == nullptr); assert(numExts > 0); extensions = NewPoolObject(extensions); for (int e = 0; e < numExts; ++e) @@ -117,10 +117,8 @@ class TSymbol { virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); } virtual const char** getExtensions() const { return extensions->data(); } -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0; void dumpExtensions(TInfoSink& infoSink) const; -#endif virtual bool isReadOnly() const { return ! writable; } virtual void makeReadOnly() { writable = false; } @@ -196,9 +194,7 @@ class TVariable : public TSymbol { } virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); } -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) virtual void dump(TInfoSink& infoSink, bool complete = false) const; -#endif protected: explicit TVariable(const TVariable&); @@ -224,14 +220,15 @@ struct TParameter { TString *name; TType* type; TIntermTyped* defaultValue; - void copyParam(const TParameter& param) + TParameter& copyParam(const TParameter& param) { if (param.name) name = NewPoolTString(param.name->c_str()); else - name = 0; + name = nullptr; type = param.type->clone(); defaultValue = param.defaultValue; + return *this; } TBuiltInVariable getDeclaredBuiltIn() const { return type->getQualifier().declaredBuiltIn; } }; @@ -242,14 +239,15 @@ struct TParameter { class TFunction : public TSymbol { public: explicit TFunction(TOperator o) : - TSymbol(0), + TSymbol(nullptr), op(o), defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0) { } TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) : TSymbol(name), mangledName(*name + '('), op(tOp), - defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0) + defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0), + linkType(ELinkNone) { returnType.shallowCopy(retType); declaredBuiltIn = retType.getQualifier().builtIn; @@ -318,19 +316,19 @@ class TFunction : public TSymbol { virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; } virtual const TParameter& operator[](int i) const { return parameters[i]; } + const TQualifier& getQualifier() const { return returnType.getQualifier(); } -#ifndef GLSLANG_WEB virtual void setSpirvInstruction(const TSpirvInstruction& inst) { relateToOperator(EOpSpirvInst); spirvInst = inst; } virtual const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; } -#endif -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) virtual void dump(TInfoSink& infoSink, bool complete = false) const override; -#endif + + void setExport() { linkType = ELinkExport; } + TLinkType getLinkType() const { return linkType; } protected: explicit TFunction(const TFunction&); @@ -352,9 +350,8 @@ class TFunction : public TSymbol { // but is not allowed to use them, or see hidden symbols instead. int defaultParamCount; -#ifndef GLSLANG_WEB TSpirvInstruction spirvInst; // SPIR-V instruction qualifiers -#endif + TLinkType linkType; }; // @@ -394,9 +391,7 @@ class TAnonMember : public TSymbol { virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); } virtual int getAnonId() const { return anonId; } -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) virtual void dump(TInfoSink& infoSink, bool complete = false) const override; -#endif protected: explicit TAnonMember(const TAnonMember&); @@ -410,7 +405,7 @@ class TAnonMember : public TSymbol { class TSymbolTableLevel { public: POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator()) - TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { } + TSymbolTableLevel() : defaultPrecision(nullptr), anonId(0), thisLevel(false) { } ~TSymbolTableLevel(); bool insert(const TString& name, TSymbol* symbol) { @@ -492,7 +487,7 @@ class TSymbolTableLevel { { tLevel::const_iterator it = level.find(name); if (it == level.end()) - return 0; + return nullptr; else return (*it).second; } @@ -560,7 +555,7 @@ class TSymbolTableLevel { { // can call multiple times at one scope, will only latch on first call, // as we're tracking the previous scope's values, not the current values - if (defaultPrecision != 0) + if (defaultPrecision != nullptr) return; defaultPrecision = new TPrecisionQualifier[EbtNumTypes]; @@ -572,7 +567,7 @@ class TSymbolTableLevel { { // can be called for table level pops that didn't set the // defaults - if (defaultPrecision == 0 || p == 0) + if (defaultPrecision == nullptr || p == nullptr) return; for (int t = 0; t < EbtNumTypes; ++t) @@ -581,9 +576,8 @@ class TSymbolTableLevel { void relateToOperator(const char* name, TOperator op); void setFunctionExtensions(const char* name, int num, const char* const extensions[]); -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) + void setSingleFunctionExtensions(const char* name, int num, const char* const extensions[]); void dump(TInfoSink& infoSink, bool complete = false) const; -#endif TSymbolTableLevel* clone() const; void readOnly(); @@ -621,7 +615,7 @@ class TSymbolTable { // don't deallocate levels passed in from elsewhere while (table.size() > adoptedLevels) - pop(0); + pop(nullptr); } void adoptLevels(TSymbolTable& symTable) @@ -782,7 +776,7 @@ class TSymbolTable { // Normal find of a symbol, that can optionally say whether the symbol was found // at a built-in level or the current top-scope level. - TSymbol* find(const TString& name, bool* builtIn = 0, bool* currentScope = 0, int* thisDepthP = 0) + TSymbol* find(const TString& name, bool* builtIn = nullptr, bool* currentScope = nullptr, int* thisDepthP = nullptr) { int level = currentLevel(); TSymbol* symbol; @@ -826,7 +820,7 @@ class TSymbolTable { ++thisDepth; symbol = table[level]->find(name); --level; - } while (symbol == 0 && level >= 0); + } while (symbol == nullptr && level >= 0); if (! table[level + 1]->isThisLevel()) thisDepth = 0; @@ -884,6 +878,12 @@ class TSymbolTable { table[level]->setFunctionExtensions(name, num, extensions); } + void setSingleFunctionExtensions(const char* name, int num, const char* const extensions[]) + { + for (unsigned int level = 0; level < table.size(); ++level) + table[level]->setSingleFunctionExtensions(name, num, extensions); + } + void setVariableExtensions(const char* name, int numExts, const char* const extensions[]) { TSymbol* symbol = find(TString(name)); @@ -911,9 +911,7 @@ class TSymbolTable { } long long getMaxSymbolId() { return uniqueId; } -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) void dump(TInfoSink& infoSink, bool complete = false) const; -#endif void copyTable(const TSymbolTable& copyOf); void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); } diff --git a/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp b/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp index 4a2b833f3..e28c6e595 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/Versions.cpp @@ -151,8 +151,6 @@ namespace glslang { -#ifndef GLSLANG_WEB - // // Initialize all extensions, almost always to 'disable', as once their features // are incorporated into a core version, their features are supported through allowing that @@ -166,7 +164,8 @@ void TParseVersions::initializeExtensionBehavior() } extensionData; const extensionData exts[] = { {E_GL_EXT_ray_tracing, EShTargetSpv_1_4}, - {E_GL_NV_ray_tracing_motion_blur, EShTargetSpv_1_4} + {E_GL_NV_ray_tracing_motion_blur, EShTargetSpv_1_4}, + {E_GL_EXT_mesh_shader, EShTargetSpv_1_4} }; for (size_t ii = 0; ii < sizeof(exts) / sizeof(exts[0]); ii++) { @@ -183,7 +182,6 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_OES_EGL_image_external_essl3] = EBhDisable; extensionBehavior[E_GL_EXT_YUV_target] = EBhDisable; extensionBehavior[E_GL_EXT_shader_texture_lod] = EBhDisable; - extensionBehavior[E_GL_EXT_texture_array] = EBhDisable; extensionBehavior[E_GL_EXT_shadow_samplers] = EBhDisable; extensionBehavior[E_GL_ARB_texture_rectangle] = EBhDisable; extensionBehavior[E_GL_3DL_array_objects] = EBhDisable; @@ -227,6 +225,7 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_ARB_texture_query_lod] = EBhDisable; extensionBehavior[E_GL_ARB_vertex_attrib_64bit] = EBhDisable; extensionBehavior[E_GL_ARB_draw_instanced] = EBhDisable; + extensionBehavior[E_GL_ARB_bindless_texture] = EBhDisable; extensionBehavior[E_GL_ARB_fragment_coord_conventions] = EBhDisable; @@ -260,6 +259,10 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_EXT_shader_8bit_storage] = EBhDisable; extensionBehavior[E_GL_EXT_subgroup_uniform_control_flow] = EBhDisable; + extensionBehavior[E_GL_EXT_fragment_shader_barycentric] = EBhDisable; + + extensionBehavior[E_GL_KHR_cooperative_matrix] = EBhDisable; + // #line and #include extensionBehavior[E_GL_GOOGLE_cpp_style_line_directive] = EBhDisable; extensionBehavior[E_GL_GOOGLE_include_directive] = EBhDisable; @@ -274,6 +277,7 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_AMD_shader_image_load_store_lod] = EBhDisable; extensionBehavior[E_GL_AMD_shader_fragment_mask] = EBhDisable; extensionBehavior[E_GL_AMD_gpu_shader_half_float_fetch] = EBhDisable; + extensionBehavior[E_GL_AMD_shader_early_and_late_fragment_tests] = EBhDisable; extensionBehavior[E_GL_INTEL_shader_integer_functions2] = EBhDisable; @@ -293,10 +297,17 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_NV_compute_shader_derivatives] = EBhDisable; extensionBehavior[E_GL_NV_shader_texture_footprint] = EBhDisable; extensionBehavior[E_GL_NV_mesh_shader] = EBhDisable; - extensionBehavior[E_GL_NV_cooperative_matrix] = EBhDisable; extensionBehavior[E_GL_NV_shader_sm_builtins] = EBhDisable; extensionBehavior[E_GL_NV_integer_cooperative_matrix] = EBhDisable; + extensionBehavior[E_GL_NV_shader_invocation_reorder] = EBhDisable; + extensionBehavior[E_GL_NV_displacement_micromap] = EBhDisable; + + // ARM + extensionBehavior[E_GL_ARM_shader_core_builtins] = EBhDisable; + + // QCOM + extensionBehavior[E_GL_QCOM_image_processing] = EBhDisable; // AEP extensionBehavior[E_GL_ANDROID_extension_pack_es31a] = EBhDisable; @@ -335,13 +346,21 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_EXT_ray_tracing] = EBhDisable; extensionBehavior[E_GL_EXT_ray_query] = EBhDisable; extensionBehavior[E_GL_EXT_ray_flags_primitive_culling] = EBhDisable; + extensionBehavior[E_GL_EXT_ray_cull_mask] = EBhDisable; extensionBehavior[E_GL_EXT_blend_func_extended] = EBhDisable; extensionBehavior[E_GL_EXT_shader_implicit_conversions] = EBhDisable; extensionBehavior[E_GL_EXT_fragment_shading_rate] = EBhDisable; - extensionBehavior[E_GL_EXT_shader_image_int64] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_image_int64] = EBhDisable; extensionBehavior[E_GL_EXT_terminate_invocation] = EBhDisable; extensionBehavior[E_GL_EXT_shared_memory_block] = EBhDisable; extensionBehavior[E_GL_EXT_spirv_intrinsics] = EBhDisable; + extensionBehavior[E_GL_EXT_mesh_shader] = EBhDisable; + extensionBehavior[E_GL_EXT_opacity_micromap] = EBhDisable; + extensionBehavior[E_GL_EXT_ray_tracing_position_fetch] = EBhDisable; + extensionBehavior[E_GL_EXT_shader_tile_image] = EBhDisable; + extensionBehavior[E_GL_EXT_texture_shadow_lod] = EBhDisable; + extensionBehavior[E_GL_EXT_draw_instanced] = EBhDisable; + extensionBehavior[E_GL_EXT_texture_array] = EBhDisable; // OVR extensions extensionBehavior[E_GL_OVR_multiview] = EBhDisable; @@ -364,9 +383,10 @@ void TParseVersions::initializeExtensionBehavior() extensionBehavior[E_GL_EXT_shader_subgroup_extended_types_float16] = EBhDisable; extensionBehavior[E_GL_EXT_shader_atomic_float] = EBhDisable; extensionBehavior[E_GL_EXT_shader_atomic_float2] = EBhDisable; -} -#endif // GLSLANG_WEB + // Record extensions not for spv. + spvUnsupportedExt.push_back(E_GL_ARB_bindless_texture); +} // 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). @@ -376,10 +396,6 @@ void TParseVersions::getPreamble(std::string& preamble) preamble = "#define GL_ES 1\n" "#define GL_FRAGMENT_PRECISION_HIGH 1\n" -#ifdef GLSLANG_WEB - ; -#else - "#define GL_EXT_texture_array 1\n" "#define GL_OES_texture_3D 1\n" "#define GL_OES_standard_derivatives 1\n" "#define GL_EXT_frag_depth 1\n" @@ -389,6 +405,7 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_shader_texture_lod 1\n" "#define GL_EXT_shadow_samplers 1\n" "#define GL_EXT_fragment_shading_rate 1\n" + "#define GL_EXT_texture_array 1\n" // AEP "#define GL_ANDROID_extension_pack_es31a 1\n" @@ -420,6 +437,8 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_OES_texture_buffer 1\n" "#define GL_OES_texture_cube_map_array 1\n" "#define GL_EXT_shader_non_constant_global_initializers 1\n" + + "#define GL_QCOM_image_processing 1\n" ; if (version >= 300) { @@ -432,8 +451,6 @@ void TParseVersions::getPreamble(std::string& preamble) } else { // !isEsProfile() preamble = - "#define GL_FRAGMENT_PRECISION_HIGH 1\n" - "#define GL_EXT_texture_array 1\n" "#define GL_ARB_texture_rectangle 1\n" "#define GL_ARB_shading_language_420pack 1\n" "#define GL_ARB_texture_gather 1\n" @@ -473,6 +490,7 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_ARB_vertex_attrib_64bit 1\n" "#define GL_ARB_draw_instanced 1\n" "#define GL_ARB_fragment_coord_conventions 1\n" + "#define GL_EXT_shader_non_constant_global_initializers 1\n" "#define GL_EXT_shader_image_load_formatted 1\n" "#define GL_EXT_post_depth_coverage 1\n" @@ -502,13 +520,18 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_KHR_shader_subgroup_clustered 1\n" "#define GL_KHR_shader_subgroup_quad 1\n" + "#define GL_KHR_cooperative_matrix 1\n" + "#define GL_EXT_shader_image_int64 1\n" "#define GL_EXT_shader_atomic_int64 1\n" "#define GL_EXT_shader_realtime_clock 1\n" "#define GL_EXT_ray_tracing 1\n" "#define GL_EXT_ray_query 1\n" "#define GL_EXT_ray_flags_primitive_culling 1\n" + "#define GL_EXT_ray_cull_mask 1\n" + "#define GL_EXT_ray_tracing_position_fetch 1\n" "#define GL_EXT_spirv_intrinsics 1\n" + "#define GL_EXT_mesh_shader 1\n" "#define GL_AMD_shader_ballot 1\n" "#define GL_AMD_shader_trinary_minmax 1\n" @@ -538,6 +561,9 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_NV_mesh_shader 1\n" "#define GL_NV_cooperative_matrix 1\n" "#define GL_NV_integer_cooperative_matrix 1\n" + "#define GL_NV_shader_invocation_reorder 1\n" + + "#define GL_QCOM_image_processing 1\n" "#define GL_EXT_shader_explicit_arithmetic_types 1\n" "#define GL_EXT_shader_explicit_arithmetic_types_int8 1\n" @@ -555,8 +581,15 @@ void TParseVersions::getPreamble(std::string& preamble) "#define GL_EXT_shader_atomic_float 1\n" "#define GL_EXT_shader_atomic_float2 1\n" + + "#define GL_EXT_fragment_shader_barycentric 1\n" + "#define GL_EXT_texture_array 1\n" ; + if (spvVersion.spv == 0) { + preamble += "#define GL_ARB_bindless_texture 1\n"; + } + if (version >= 150) { // define GL_core_profile and GL_compatibility_profile preamble += "#define GL_core_profile 1\n"; @@ -568,10 +601,11 @@ void TParseVersions::getPreamble(std::string& preamble) preamble += "#define GL_EXT_null_initializer 1\n"; preamble += "#define GL_EXT_subgroup_uniform_control_flow 1\n"; } -#endif // GLSLANG_WEB + if (version >= 130) { + preamble +="#define GL_FRAGMENT_PRECISION_HIGH 1\n"; + } } -#ifndef GLSLANG_WEB if ((!isEsProfile() && version >= 140) || (isEsProfile() && version >= 310)) { preamble += @@ -599,7 +633,6 @@ void TParseVersions::getPreamble(std::string& preamble) preamble += "#define GL_EXT_terminate_invocation 1\n" ; -#endif // #define VULKAN XXXX const int numberBufSize = 12; @@ -611,7 +644,6 @@ void TParseVersions::getPreamble(std::string& preamble) preamble += "\n"; } -#ifndef GLSLANG_WEB // #define GL_SPIRV XXXX if (spvVersion.openGl > 0) { preamble += "#define GL_SPIRV "; @@ -619,9 +651,7 @@ void TParseVersions::getPreamble(std::string& preamble) preamble += numberBuf; preamble += "\n"; } -#endif -#ifndef GLSLANG_WEB // GL_EXT_spirv_intrinsics if (!isEsProfile()) { switch (language) { @@ -637,12 +667,11 @@ void TParseVersions::getPreamble(std::string& preamble) case EShLangClosestHit: preamble += "#define GL_CLOSEST_HIT_SHADER_EXT 1 \n"; break; case EShLangMiss: preamble += "#define GL_MISS_SHADER_EXT 1 \n"; break; case EShLangCallable: preamble += "#define GL_CALLABLE_SHADER_EXT 1 \n"; break; - case EShLangTaskNV: preamble += "#define GL_TASK_SHADER_NV 1 \n"; break; - case EShLangMeshNV: preamble += "#define GL_MESH_SHADER_NV 1 \n"; break; + case EShLangTask: preamble += "#define GL_TASK_SHADER_NV 1 \n"; break; + case EShLangMesh: preamble += "#define GL_MESH_SHADER_NV 1 \n"; break; default: break; } } -#endif } // @@ -654,7 +683,6 @@ const char* StageName(EShLanguage stage) case EShLangVertex: return "vertex"; case EShLangFragment: return "fragment"; case EShLangCompute: return "compute"; -#ifndef GLSLANG_WEB case EShLangTessControl: return "tessellation control"; case EShLangTessEvaluation: return "tessellation evaluation"; case EShLangGeometry: return "geometry"; @@ -664,9 +692,8 @@ const char* StageName(EShLanguage stage) case EShLangClosestHit: return "closest-hit"; case EShLangMiss: return "miss"; case EShLangCallable: return "callable"; - case EShLangMeshNV: return "mesh"; - case EShLangTaskNV: return "task"; -#endif + case EShLangMesh: return "mesh"; + case EShLangTask: return "task"; default: return "unknown stage"; } } @@ -691,7 +718,6 @@ void TParseVersions::requireStage(const TSourceLoc& loc, EShLanguage stage, cons requireStage(loc, static_cast(1 << stage), featureDesc); } -#ifndef GLSLANG_WEB // // When to use requireProfile(): // @@ -729,7 +755,6 @@ void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int { 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: @@ -742,7 +767,6 @@ void TParseVersions::profileRequires(const TSourceLoc& loc, int profileMask, int default: break; // some compilers want this } } -#endif if (! okay) error(loc, "not supported for this version or the enabled extensions", featureDesc, ""); } @@ -1056,10 +1080,22 @@ void TParseVersions::checkExtensionStage(const TSourceLoc& loc, const char * con { // GL_NV_mesh_shader extension is only allowed in task/mesh shaders if (strcmp(extension, "GL_NV_mesh_shader") == 0) { - requireStage(loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask | EShLangFragmentMask), + requireStage(loc, (EShLanguageMask)(EShLangTaskMask | EShLangMeshMask | EShLangFragmentMask), "#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, ECoreProfile, 450, nullptr, "#extension GL_NV_mesh_shader"); + profileRequires(loc, EEsProfile, 320, nullptr, "#extension GL_NV_mesh_shader"); + if (extensionTurnedOn(E_GL_EXT_mesh_shader)) { + error(loc, "GL_EXT_mesh_shader is already turned on, and not allowed with", "#extension", extension); + } + } + else if (strcmp(extension, "GL_EXT_mesh_shader") == 0) { + requireStage(loc, (EShLanguageMask)(EShLangTaskMask | EShLangMeshMask | EShLangFragmentMask), + "#extension GL_EXT_mesh_shader"); + profileRequires(loc, ECoreProfile, 450, nullptr, "#extension GL_EXT_mesh_shader"); + profileRequires(loc, EEsProfile, 320, nullptr, "#extension GL_EXT_mesh_shader"); + if (extensionTurnedOn(E_GL_NV_mesh_shader)) { + error(loc, "GL_NV_mesh_shader is already turned on, and not allowed with", "#extension", extension); + } } } @@ -1079,6 +1115,13 @@ void TParseVersions::extensionRequires(const TSourceLoc &loc, const char * const minSpvVersion = iter->second; requireSpv(loc, extension, minSpvVersion); } + + if (spvVersion.spv != 0){ + for (auto ext : spvUnsupportedExt){ + if (strcmp(extension, ext.c_str()) == 0) + error(loc, "not allowed when using generating SPIR-V codes", extension, ""); + } + } } // Call for any operation needing full GLSL integer data-type support. @@ -1291,7 +1334,7 @@ void TParseVersions::int64Check(const TSourceLoc& loc, const char* op, bool buil } } -void TParseVersions::fcoopmatCheck(const TSourceLoc& loc, const char* op, bool builtIn) +void TParseVersions::fcoopmatCheckNV(const TSourceLoc& loc, const char* op, bool builtIn) { if (!builtIn) { const char* const extensions[] = {E_GL_NV_cooperative_matrix}; @@ -1299,14 +1342,22 @@ void TParseVersions::fcoopmatCheck(const TSourceLoc& loc, const char* op, bool b } } -void TParseVersions::intcoopmatCheck(const TSourceLoc& loc, const char* op, bool builtIn) +void TParseVersions::intcoopmatCheckNV(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 + +void TParseVersions::coopmatCheck(const TSourceLoc& loc, const char* op, bool builtIn) +{ + if (!builtIn) { + const char* const extensions[] = {E_GL_KHR_cooperative_matrix}; + requireExtensions(loc, sizeof(extensions)/sizeof(extensions[0]), extensions, op); + } +} + // Call for any operation removed because SPIR-V is in use. void TParseVersions::spvRemoved(const TSourceLoc& loc, const char* op) { @@ -1324,26 +1375,20 @@ void TParseVersions::vulkanRemoved(const TSourceLoc& loc, const char* op) // Call for any operation that requires Vulkan. void TParseVersions::requireVulkan(const TSourceLoc& loc, const char* op) { -#ifndef GLSLANG_WEB if (spvVersion.vulkan == 0) error(loc, "only allowed when using GLSL for Vulkan", op, ""); -#endif } // Call for any operation that requires SPIR-V. void TParseVersions::requireSpv(const TSourceLoc& loc, const char* op) { -#ifndef GLSLANG_WEB if (spvVersion.spv == 0) error(loc, "only allowed when generating SPIR-V", op, ""); -#endif } void TParseVersions::requireSpv(const TSourceLoc& loc, const char *op, unsigned int version) { -#ifndef GLSLANG_WEB if (spvVersion.spv < version) error(loc, "not supported for current targeted SPIR-V version", op, ""); -#endif } } // end namespace glslang diff --git a/src/libraries/glslang/glslang/MachineIndependent/Versions.h b/src/libraries/glslang/glslang/MachineIndependent/Versions.h old mode 100644 new mode 100755 index 35e1f9aa6..475cb8934 --- a/src/libraries/glslang/glslang/MachineIndependent/Versions.h +++ b/src/libraries/glslang/glslang/MachineIndependent/Versions.h @@ -120,7 +120,6 @@ const char* const E_GL_EXT_YUV_target = "GL_EXT_YUV_target"; const char* const E_GL_EXT_shader_texture_lod = "GL_EXT_shader_texture_lod"; const char* const E_GL_EXT_shadow_samplers = "GL_EXT_shadow_samplers"; -const char* const E_GL_EXT_texture_array = "GL_EXT_texture_array"; const char* const E_GL_ARB_texture_rectangle = "GL_ARB_texture_rectangle"; const char* const E_GL_3DL_array_objects = "GL_3DL_array_objects"; const char* const E_GL_ARB_shading_language_420pack = "GL_ARB_shading_language_420pack"; @@ -164,6 +163,7 @@ const char* const E_GL_ARB_texture_query_lod = "GL_ARB_texture_query_ const char* const E_GL_ARB_vertex_attrib_64bit = "GL_ARB_vertex_attrib_64bit"; const char* const E_GL_ARB_draw_instanced = "GL_ARB_draw_instanced"; const char* const E_GL_ARB_fragment_coord_conventions = "GL_ARB_fragment_coord_conventions"; +const char* const E_GL_ARB_bindless_texture = "GL_ARB_bindless_texture"; 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"; @@ -174,6 +174,7 @@ const char* const E_GL_KHR_shader_subgroup_shuffle_relative = "GL_KHR_shader_sub const char* const E_GL_KHR_shader_subgroup_clustered = "GL_KHR_shader_subgroup_clustered"; const char* const E_GL_KHR_shader_subgroup_quad = "GL_KHR_shader_subgroup_quad"; const char* const E_GL_KHR_memory_scope_semantics = "GL_KHR_memory_scope_semantics"; +const char* const E_GL_KHR_cooperative_matrix = "GL_KHR_cooperative_matrix"; const char* const E_GL_EXT_shader_atomic_int64 = "GL_EXT_shader_atomic_int64"; @@ -202,6 +203,7 @@ const char* const E_GL_EXT_debug_printf = "GL_EXT_debug_prin const char* const E_GL_EXT_ray_tracing = "GL_EXT_ray_tracing"; const char* const E_GL_EXT_ray_query = "GL_EXT_ray_query"; const char* const E_GL_EXT_ray_flags_primitive_culling = "GL_EXT_ray_flags_primitive_culling"; +const char* const E_GL_EXT_ray_cull_mask = "GL_EXT_ray_cull_mask"; const char* const E_GL_EXT_blend_func_extended = "GL_EXT_blend_func_extended"; const char* const E_GL_EXT_shader_implicit_conversions = "GL_EXT_shader_implicit_conversions"; const char* const E_GL_EXT_fragment_shading_rate = "GL_EXT_fragment_shading_rate"; @@ -210,12 +212,21 @@ const char* const E_GL_EXT_null_initializer = "GL_EXT_null_initi const char* const E_GL_EXT_shared_memory_block = "GL_EXT_shared_memory_block"; const char* const E_GL_EXT_subgroup_uniform_control_flow = "GL_EXT_subgroup_uniform_control_flow"; const char* const E_GL_EXT_spirv_intrinsics = "GL_EXT_spirv_intrinsics"; +const char* const E_GL_EXT_fragment_shader_barycentric = "GL_EXT_fragment_shader_barycentric"; +const char* const E_GL_EXT_mesh_shader = "GL_EXT_mesh_shader"; +const char* const E_GL_EXT_opacity_micromap = "GL_EXT_opacity_micromap"; +const char* const E_GL_EXT_draw_instanced = "GL_EXT_draw_instanced"; +const char* const E_GL_EXT_texture_array = "GL_EXT_texture_array"; // Arrays of extensions for the above viewportEXTs duplications const char* const post_depth_coverageEXTs[] = { E_GL_ARB_post_depth_coverage, E_GL_EXT_post_depth_coverage }; const int Num_post_depth_coverageEXTs = sizeof(post_depth_coverageEXTs) / sizeof(post_depth_coverageEXTs[0]); +// Array of extensions to cover both extensions providing ray tracing capabilities. +const char* const ray_tracing_EXTs[] = { E_GL_EXT_ray_query, E_GL_EXT_ray_tracing }; +const int Num_ray_tracing_EXTs = sizeof(ray_tracing_EXTs) / sizeof(ray_tracing_EXTs[0]); + // OVR extensions const char* const E_GL_OVR_multiview = "GL_OVR_multiview"; const char* const E_GL_OVR_multiview2 = "GL_OVR_multiview2"; @@ -237,6 +248,7 @@ 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_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_shader_early_and_late_fragment_tests = "GL_AMD_shader_early_and_late_fragment_tests"; const char* const E_GL_INTEL_shader_integer_functions2 = "GL_INTEL_shader_integer_functions2"; @@ -256,15 +268,23 @@ const char* const E_GL_NV_fragment_shader_barycentric = "GL_NV_fragmen const char* const E_GL_NV_compute_shader_derivatives = "GL_NV_compute_shader_derivatives"; const char* const E_GL_NV_shader_texture_footprint = "GL_NV_shader_texture_footprint"; const char* const E_GL_NV_mesh_shader = "GL_NV_mesh_shader"; +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"; +const char* const E_GL_NV_shader_invocation_reorder = "GL_NV_shader_invocation_reorder"; +const char* const E_GL_EXT_ray_tracing_position_fetch = "GL_EXT_ray_tracing_position_fetch"; +const char* const E_GL_NV_displacement_micromap = "GL_NV_displacement_micromap"; + +// ARM +const char* const E_GL_ARM_shader_core_builtins = "GL_ARM_shader_core_builtins"; // Arrays of extensions for the above viewportEXTs duplications 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 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"; + +const char* const E_GL_QCOM_image_processing = "GL_QCOM_image_processing"; // AEP const char* const E_GL_ANDROID_extension_pack_es31a = "GL_ANDROID_extension_pack_es31a"; @@ -282,7 +302,7 @@ const char* const E_GL_EXT_tessellation_shader = "GL_EXT_tessel const char* const E_GL_EXT_tessellation_point_size = "GL_EXT_tessellation_point_size"; const char* const E_GL_EXT_texture_buffer = "GL_EXT_texture_buffer"; const char* const E_GL_EXT_texture_cube_map_array = "GL_EXT_texture_cube_map_array"; -const char* const E_GL_EXT_shader_integer_mix = "GL_EXT_shader_integer_mix"; +const char* const E_GL_EXT_shader_integer_mix = "GL_EXT_shader_integer_mix"; // OES matching AEP const char* const E_GL_OES_geometry_shader = "GL_OES_geometry_shader"; @@ -314,6 +334,10 @@ const char* const E_GL_EXT_terminate_invocation = "GL_EXT_terminate_invocation"; const char* const E_GL_EXT_shader_atomic_float = "GL_EXT_shader_atomic_float"; const char* const E_GL_EXT_shader_atomic_float2 = "GL_EXT_shader_atomic_float2"; +const char* const E_GL_EXT_shader_tile_image = "GL_EXT_shader_tile_image"; + +const char* const E_GL_EXT_texture_shadow_lod = "GL_EXT_texture_shadow_lod"; + // Arrays of extensions for the above AEP duplications const char* const AEP_geometry_shader[] = { E_GL_EXT_geometry_shader, E_GL_OES_geometry_shader }; @@ -343,6 +367,9 @@ const int Num_AEP_texture_buffer = sizeof(AEP_texture_buffer)/sizeof(AEP_texture const char* const AEP_texture_cube_map_array[] = { E_GL_EXT_texture_cube_map_array, E_GL_OES_texture_cube_map_array }; const int Num_AEP_texture_cube_map_array = sizeof(AEP_texture_cube_map_array)/sizeof(AEP_texture_cube_map_array[0]); +const char* const AEP_mesh_shader[] = { E_GL_NV_mesh_shader, E_GL_EXT_mesh_shader }; +const int Num_AEP_mesh_shader = sizeof(AEP_mesh_shader)/sizeof(AEP_mesh_shader[0]); + } // end namespace glslang #endif // _VERSIONS_INCLUDED_ diff --git a/src/libraries/glslang/glslang/MachineIndependent/attribute.cpp b/src/libraries/glslang/glslang/MachineIndependent/attribute.cpp index df7fdc2a6..a167c494f 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/attribute.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/attribute.cpp @@ -34,8 +34,6 @@ // POSSIBILITY OF SUCH DAMAGE. // -#ifndef GLSLANG_WEB - #include "attribute.h" #include "../Include/intermediate.h" #include "ParseHelper.h" @@ -125,6 +123,8 @@ TAttributeType TParseContext::attributeFromName(const TString& name) const return EatPartialCount; else if (name == "subgroup_uniform_control_flow") return EatSubgroupUniformControlFlow; + else if (name == "export") + return EatExport; else return EatNone; } @@ -357,6 +357,7 @@ void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttri switch (it->name) { case EatSubgroupUniformControlFlow: + requireExtensions(loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute"); intermediate.setSubgroupUniformControlFlow(); break; default: @@ -367,5 +368,3 @@ void TParseContext::handleFunctionAttributes(const TSourceLoc& loc, const TAttri } } // end namespace glslang - -#endif // GLSLANG_WEB diff --git a/src/libraries/glslang/glslang/MachineIndependent/attribute.h b/src/libraries/glslang/glslang/MachineIndependent/attribute.h index c5b29176c..a0c4c43d4 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/attribute.h +++ b/src/libraries/glslang/glslang/MachineIndependent/attribute.h @@ -120,6 +120,7 @@ namespace glslang { EatNonWritable, EatNonReadable, EatSubgroupUniformControlFlow, + EatExport, }; class TIntermAggregate; diff --git a/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp b/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp index 5ba6a6d49..5038bebe5 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison implementation for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -46,10 +46,10 @@ USER NAME SPACE" below. */ /* Identify Bison output, and Bison version. */ -#define YYBISON 30704 +#define YYBISON 30802 /* Bison version string. */ -#define YYBISON_VERSION "3.7.4" +#define YYBISON_VERSION "3.8.2" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -67,7 +67,7 @@ /* First part of user prologue. */ -#line 69 "MachineIndependent/glslang.y" +#line 44 "MachineIndependent/glslang.y" /* Based on: @@ -287,448 +287,452 @@ enum yysymbol_kind_t YYSYMBOL_FCOOPMATNV = 163, /* FCOOPMATNV */ YYSYMBOL_ICOOPMATNV = 164, /* ICOOPMATNV */ YYSYMBOL_UCOOPMATNV = 165, /* UCOOPMATNV */ - YYSYMBOL_SAMPLERCUBEARRAY = 166, /* SAMPLERCUBEARRAY */ - YYSYMBOL_SAMPLERCUBEARRAYSHADOW = 167, /* SAMPLERCUBEARRAYSHADOW */ - YYSYMBOL_ISAMPLERCUBEARRAY = 168, /* ISAMPLERCUBEARRAY */ - YYSYMBOL_USAMPLERCUBEARRAY = 169, /* USAMPLERCUBEARRAY */ - YYSYMBOL_SAMPLER1D = 170, /* SAMPLER1D */ - YYSYMBOL_SAMPLER1DARRAY = 171, /* SAMPLER1DARRAY */ - YYSYMBOL_SAMPLER1DARRAYSHADOW = 172, /* SAMPLER1DARRAYSHADOW */ - YYSYMBOL_ISAMPLER1D = 173, /* ISAMPLER1D */ - YYSYMBOL_SAMPLER1DSHADOW = 174, /* SAMPLER1DSHADOW */ - YYSYMBOL_SAMPLER2DRECT = 175, /* SAMPLER2DRECT */ - YYSYMBOL_SAMPLER2DRECTSHADOW = 176, /* SAMPLER2DRECTSHADOW */ - YYSYMBOL_ISAMPLER2DRECT = 177, /* ISAMPLER2DRECT */ - YYSYMBOL_USAMPLER2DRECT = 178, /* USAMPLER2DRECT */ - YYSYMBOL_SAMPLERBUFFER = 179, /* SAMPLERBUFFER */ - YYSYMBOL_ISAMPLERBUFFER = 180, /* ISAMPLERBUFFER */ - YYSYMBOL_USAMPLERBUFFER = 181, /* USAMPLERBUFFER */ - YYSYMBOL_SAMPLER2DMS = 182, /* SAMPLER2DMS */ - YYSYMBOL_ISAMPLER2DMS = 183, /* ISAMPLER2DMS */ - YYSYMBOL_USAMPLER2DMS = 184, /* USAMPLER2DMS */ - YYSYMBOL_SAMPLER2DMSARRAY = 185, /* SAMPLER2DMSARRAY */ - YYSYMBOL_ISAMPLER2DMSARRAY = 186, /* ISAMPLER2DMSARRAY */ - YYSYMBOL_USAMPLER2DMSARRAY = 187, /* USAMPLER2DMSARRAY */ - YYSYMBOL_SAMPLEREXTERNALOES = 188, /* SAMPLEREXTERNALOES */ - YYSYMBOL_SAMPLEREXTERNAL2DY2YEXT = 189, /* SAMPLEREXTERNAL2DY2YEXT */ - YYSYMBOL_ISAMPLER1DARRAY = 190, /* ISAMPLER1DARRAY */ - YYSYMBOL_USAMPLER1D = 191, /* USAMPLER1D */ - YYSYMBOL_USAMPLER1DARRAY = 192, /* USAMPLER1DARRAY */ - YYSYMBOL_F16SAMPLER1D = 193, /* F16SAMPLER1D */ - YYSYMBOL_F16SAMPLER2D = 194, /* F16SAMPLER2D */ - YYSYMBOL_F16SAMPLER3D = 195, /* F16SAMPLER3D */ - YYSYMBOL_F16SAMPLER2DRECT = 196, /* F16SAMPLER2DRECT */ - YYSYMBOL_F16SAMPLERCUBE = 197, /* F16SAMPLERCUBE */ - YYSYMBOL_F16SAMPLER1DARRAY = 198, /* F16SAMPLER1DARRAY */ - YYSYMBOL_F16SAMPLER2DARRAY = 199, /* F16SAMPLER2DARRAY */ - YYSYMBOL_F16SAMPLERCUBEARRAY = 200, /* F16SAMPLERCUBEARRAY */ - YYSYMBOL_F16SAMPLERBUFFER = 201, /* F16SAMPLERBUFFER */ - YYSYMBOL_F16SAMPLER2DMS = 202, /* F16SAMPLER2DMS */ - YYSYMBOL_F16SAMPLER2DMSARRAY = 203, /* F16SAMPLER2DMSARRAY */ - YYSYMBOL_F16SAMPLER1DSHADOW = 204, /* F16SAMPLER1DSHADOW */ - YYSYMBOL_F16SAMPLER2DSHADOW = 205, /* F16SAMPLER2DSHADOW */ - YYSYMBOL_F16SAMPLER1DARRAYSHADOW = 206, /* F16SAMPLER1DARRAYSHADOW */ - YYSYMBOL_F16SAMPLER2DARRAYSHADOW = 207, /* F16SAMPLER2DARRAYSHADOW */ - YYSYMBOL_F16SAMPLER2DRECTSHADOW = 208, /* F16SAMPLER2DRECTSHADOW */ - YYSYMBOL_F16SAMPLERCUBESHADOW = 209, /* F16SAMPLERCUBESHADOW */ - YYSYMBOL_F16SAMPLERCUBEARRAYSHADOW = 210, /* F16SAMPLERCUBEARRAYSHADOW */ - YYSYMBOL_IMAGE1D = 211, /* IMAGE1D */ - YYSYMBOL_IIMAGE1D = 212, /* IIMAGE1D */ - YYSYMBOL_UIMAGE1D = 213, /* UIMAGE1D */ - YYSYMBOL_IMAGE2D = 214, /* IMAGE2D */ - YYSYMBOL_IIMAGE2D = 215, /* IIMAGE2D */ - YYSYMBOL_UIMAGE2D = 216, /* UIMAGE2D */ - YYSYMBOL_IMAGE3D = 217, /* IMAGE3D */ - YYSYMBOL_IIMAGE3D = 218, /* IIMAGE3D */ - YYSYMBOL_UIMAGE3D = 219, /* UIMAGE3D */ - YYSYMBOL_IMAGE2DRECT = 220, /* IMAGE2DRECT */ - YYSYMBOL_IIMAGE2DRECT = 221, /* IIMAGE2DRECT */ - YYSYMBOL_UIMAGE2DRECT = 222, /* UIMAGE2DRECT */ - YYSYMBOL_IMAGECUBE = 223, /* IMAGECUBE */ - YYSYMBOL_IIMAGECUBE = 224, /* IIMAGECUBE */ - YYSYMBOL_UIMAGECUBE = 225, /* UIMAGECUBE */ - YYSYMBOL_IMAGEBUFFER = 226, /* IMAGEBUFFER */ - YYSYMBOL_IIMAGEBUFFER = 227, /* IIMAGEBUFFER */ - YYSYMBOL_UIMAGEBUFFER = 228, /* UIMAGEBUFFER */ - YYSYMBOL_IMAGE1DARRAY = 229, /* IMAGE1DARRAY */ - YYSYMBOL_IIMAGE1DARRAY = 230, /* IIMAGE1DARRAY */ - YYSYMBOL_UIMAGE1DARRAY = 231, /* UIMAGE1DARRAY */ - YYSYMBOL_IMAGE2DARRAY = 232, /* IMAGE2DARRAY */ - YYSYMBOL_IIMAGE2DARRAY = 233, /* IIMAGE2DARRAY */ - YYSYMBOL_UIMAGE2DARRAY = 234, /* UIMAGE2DARRAY */ - YYSYMBOL_IMAGECUBEARRAY = 235, /* IMAGECUBEARRAY */ - YYSYMBOL_IIMAGECUBEARRAY = 236, /* IIMAGECUBEARRAY */ - YYSYMBOL_UIMAGECUBEARRAY = 237, /* UIMAGECUBEARRAY */ - YYSYMBOL_IMAGE2DMS = 238, /* IMAGE2DMS */ - YYSYMBOL_IIMAGE2DMS = 239, /* IIMAGE2DMS */ - YYSYMBOL_UIMAGE2DMS = 240, /* UIMAGE2DMS */ - YYSYMBOL_IMAGE2DMSARRAY = 241, /* IMAGE2DMSARRAY */ - YYSYMBOL_IIMAGE2DMSARRAY = 242, /* IIMAGE2DMSARRAY */ - YYSYMBOL_UIMAGE2DMSARRAY = 243, /* UIMAGE2DMSARRAY */ - YYSYMBOL_F16IMAGE1D = 244, /* F16IMAGE1D */ - YYSYMBOL_F16IMAGE2D = 245, /* F16IMAGE2D */ - YYSYMBOL_F16IMAGE3D = 246, /* F16IMAGE3D */ - YYSYMBOL_F16IMAGE2DRECT = 247, /* F16IMAGE2DRECT */ - YYSYMBOL_F16IMAGECUBE = 248, /* F16IMAGECUBE */ - YYSYMBOL_F16IMAGE1DARRAY = 249, /* F16IMAGE1DARRAY */ - YYSYMBOL_F16IMAGE2DARRAY = 250, /* F16IMAGE2DARRAY */ - YYSYMBOL_F16IMAGECUBEARRAY = 251, /* F16IMAGECUBEARRAY */ - YYSYMBOL_F16IMAGEBUFFER = 252, /* F16IMAGEBUFFER */ - YYSYMBOL_F16IMAGE2DMS = 253, /* F16IMAGE2DMS */ - YYSYMBOL_F16IMAGE2DMSARRAY = 254, /* F16IMAGE2DMSARRAY */ - YYSYMBOL_I64IMAGE1D = 255, /* I64IMAGE1D */ - YYSYMBOL_U64IMAGE1D = 256, /* U64IMAGE1D */ - YYSYMBOL_I64IMAGE2D = 257, /* I64IMAGE2D */ - YYSYMBOL_U64IMAGE2D = 258, /* U64IMAGE2D */ - YYSYMBOL_I64IMAGE3D = 259, /* I64IMAGE3D */ - YYSYMBOL_U64IMAGE3D = 260, /* U64IMAGE3D */ - YYSYMBOL_I64IMAGE2DRECT = 261, /* I64IMAGE2DRECT */ - YYSYMBOL_U64IMAGE2DRECT = 262, /* U64IMAGE2DRECT */ - YYSYMBOL_I64IMAGECUBE = 263, /* I64IMAGECUBE */ - YYSYMBOL_U64IMAGECUBE = 264, /* U64IMAGECUBE */ - YYSYMBOL_I64IMAGEBUFFER = 265, /* I64IMAGEBUFFER */ - YYSYMBOL_U64IMAGEBUFFER = 266, /* U64IMAGEBUFFER */ - YYSYMBOL_I64IMAGE1DARRAY = 267, /* I64IMAGE1DARRAY */ - YYSYMBOL_U64IMAGE1DARRAY = 268, /* U64IMAGE1DARRAY */ - YYSYMBOL_I64IMAGE2DARRAY = 269, /* I64IMAGE2DARRAY */ - YYSYMBOL_U64IMAGE2DARRAY = 270, /* U64IMAGE2DARRAY */ - YYSYMBOL_I64IMAGECUBEARRAY = 271, /* I64IMAGECUBEARRAY */ - YYSYMBOL_U64IMAGECUBEARRAY = 272, /* U64IMAGECUBEARRAY */ - YYSYMBOL_I64IMAGE2DMS = 273, /* I64IMAGE2DMS */ - YYSYMBOL_U64IMAGE2DMS = 274, /* U64IMAGE2DMS */ - YYSYMBOL_I64IMAGE2DMSARRAY = 275, /* I64IMAGE2DMSARRAY */ - YYSYMBOL_U64IMAGE2DMSARRAY = 276, /* U64IMAGE2DMSARRAY */ - YYSYMBOL_TEXTURECUBEARRAY = 277, /* TEXTURECUBEARRAY */ - YYSYMBOL_ITEXTURECUBEARRAY = 278, /* ITEXTURECUBEARRAY */ - YYSYMBOL_UTEXTURECUBEARRAY = 279, /* UTEXTURECUBEARRAY */ - YYSYMBOL_TEXTURE1D = 280, /* TEXTURE1D */ - YYSYMBOL_ITEXTURE1D = 281, /* ITEXTURE1D */ - YYSYMBOL_UTEXTURE1D = 282, /* UTEXTURE1D */ - YYSYMBOL_TEXTURE1DARRAY = 283, /* TEXTURE1DARRAY */ - YYSYMBOL_ITEXTURE1DARRAY = 284, /* ITEXTURE1DARRAY */ - YYSYMBOL_UTEXTURE1DARRAY = 285, /* UTEXTURE1DARRAY */ - YYSYMBOL_TEXTURE2DRECT = 286, /* TEXTURE2DRECT */ - YYSYMBOL_ITEXTURE2DRECT = 287, /* ITEXTURE2DRECT */ - YYSYMBOL_UTEXTURE2DRECT = 288, /* UTEXTURE2DRECT */ - YYSYMBOL_TEXTUREBUFFER = 289, /* TEXTUREBUFFER */ - YYSYMBOL_ITEXTUREBUFFER = 290, /* ITEXTUREBUFFER */ - YYSYMBOL_UTEXTUREBUFFER = 291, /* UTEXTUREBUFFER */ - YYSYMBOL_TEXTURE2DMS = 292, /* TEXTURE2DMS */ - YYSYMBOL_ITEXTURE2DMS = 293, /* ITEXTURE2DMS */ - YYSYMBOL_UTEXTURE2DMS = 294, /* UTEXTURE2DMS */ - YYSYMBOL_TEXTURE2DMSARRAY = 295, /* TEXTURE2DMSARRAY */ - YYSYMBOL_ITEXTURE2DMSARRAY = 296, /* ITEXTURE2DMSARRAY */ - YYSYMBOL_UTEXTURE2DMSARRAY = 297, /* UTEXTURE2DMSARRAY */ - YYSYMBOL_F16TEXTURE1D = 298, /* F16TEXTURE1D */ - YYSYMBOL_F16TEXTURE2D = 299, /* F16TEXTURE2D */ - YYSYMBOL_F16TEXTURE3D = 300, /* F16TEXTURE3D */ - YYSYMBOL_F16TEXTURE2DRECT = 301, /* F16TEXTURE2DRECT */ - YYSYMBOL_F16TEXTURECUBE = 302, /* F16TEXTURECUBE */ - YYSYMBOL_F16TEXTURE1DARRAY = 303, /* F16TEXTURE1DARRAY */ - YYSYMBOL_F16TEXTURE2DARRAY = 304, /* F16TEXTURE2DARRAY */ - YYSYMBOL_F16TEXTURECUBEARRAY = 305, /* F16TEXTURECUBEARRAY */ - YYSYMBOL_F16TEXTUREBUFFER = 306, /* F16TEXTUREBUFFER */ - YYSYMBOL_F16TEXTURE2DMS = 307, /* F16TEXTURE2DMS */ - YYSYMBOL_F16TEXTURE2DMSARRAY = 308, /* F16TEXTURE2DMSARRAY */ - YYSYMBOL_SUBPASSINPUT = 309, /* SUBPASSINPUT */ - YYSYMBOL_SUBPASSINPUTMS = 310, /* SUBPASSINPUTMS */ - YYSYMBOL_ISUBPASSINPUT = 311, /* ISUBPASSINPUT */ - YYSYMBOL_ISUBPASSINPUTMS = 312, /* ISUBPASSINPUTMS */ - YYSYMBOL_USUBPASSINPUT = 313, /* USUBPASSINPUT */ - YYSYMBOL_USUBPASSINPUTMS = 314, /* USUBPASSINPUTMS */ - YYSYMBOL_F16SUBPASSINPUT = 315, /* F16SUBPASSINPUT */ - YYSYMBOL_F16SUBPASSINPUTMS = 316, /* F16SUBPASSINPUTMS */ - YYSYMBOL_SPIRV_INSTRUCTION = 317, /* SPIRV_INSTRUCTION */ - YYSYMBOL_SPIRV_EXECUTION_MODE = 318, /* SPIRV_EXECUTION_MODE */ - YYSYMBOL_SPIRV_EXECUTION_MODE_ID = 319, /* SPIRV_EXECUTION_MODE_ID */ - YYSYMBOL_SPIRV_DECORATE = 320, /* SPIRV_DECORATE */ - YYSYMBOL_SPIRV_DECORATE_ID = 321, /* SPIRV_DECORATE_ID */ - YYSYMBOL_SPIRV_DECORATE_STRING = 322, /* SPIRV_DECORATE_STRING */ - YYSYMBOL_SPIRV_TYPE = 323, /* SPIRV_TYPE */ - YYSYMBOL_SPIRV_STORAGE_CLASS = 324, /* SPIRV_STORAGE_CLASS */ - YYSYMBOL_SPIRV_BY_REFERENCE = 325, /* SPIRV_BY_REFERENCE */ - YYSYMBOL_SPIRV_LITERAL = 326, /* SPIRV_LITERAL */ - YYSYMBOL_LEFT_OP = 327, /* LEFT_OP */ - YYSYMBOL_RIGHT_OP = 328, /* RIGHT_OP */ - YYSYMBOL_INC_OP = 329, /* INC_OP */ - YYSYMBOL_DEC_OP = 330, /* DEC_OP */ - YYSYMBOL_LE_OP = 331, /* LE_OP */ - YYSYMBOL_GE_OP = 332, /* GE_OP */ - YYSYMBOL_EQ_OP = 333, /* EQ_OP */ - YYSYMBOL_NE_OP = 334, /* NE_OP */ - YYSYMBOL_AND_OP = 335, /* AND_OP */ - YYSYMBOL_OR_OP = 336, /* OR_OP */ - YYSYMBOL_XOR_OP = 337, /* XOR_OP */ - YYSYMBOL_MUL_ASSIGN = 338, /* MUL_ASSIGN */ - YYSYMBOL_DIV_ASSIGN = 339, /* DIV_ASSIGN */ - YYSYMBOL_ADD_ASSIGN = 340, /* ADD_ASSIGN */ - YYSYMBOL_MOD_ASSIGN = 341, /* MOD_ASSIGN */ - YYSYMBOL_LEFT_ASSIGN = 342, /* LEFT_ASSIGN */ - YYSYMBOL_RIGHT_ASSIGN = 343, /* RIGHT_ASSIGN */ - YYSYMBOL_AND_ASSIGN = 344, /* AND_ASSIGN */ - YYSYMBOL_XOR_ASSIGN = 345, /* XOR_ASSIGN */ - YYSYMBOL_OR_ASSIGN = 346, /* OR_ASSIGN */ - YYSYMBOL_SUB_ASSIGN = 347, /* SUB_ASSIGN */ - YYSYMBOL_STRING_LITERAL = 348, /* STRING_LITERAL */ - YYSYMBOL_LEFT_PAREN = 349, /* LEFT_PAREN */ - YYSYMBOL_RIGHT_PAREN = 350, /* RIGHT_PAREN */ - YYSYMBOL_LEFT_BRACKET = 351, /* LEFT_BRACKET */ - YYSYMBOL_RIGHT_BRACKET = 352, /* RIGHT_BRACKET */ - YYSYMBOL_LEFT_BRACE = 353, /* LEFT_BRACE */ - YYSYMBOL_RIGHT_BRACE = 354, /* RIGHT_BRACE */ - YYSYMBOL_DOT = 355, /* DOT */ - YYSYMBOL_COMMA = 356, /* COMMA */ - YYSYMBOL_COLON = 357, /* COLON */ - YYSYMBOL_EQUAL = 358, /* EQUAL */ - YYSYMBOL_SEMICOLON = 359, /* SEMICOLON */ - YYSYMBOL_BANG = 360, /* BANG */ - YYSYMBOL_DASH = 361, /* DASH */ - YYSYMBOL_TILDE = 362, /* TILDE */ - YYSYMBOL_PLUS = 363, /* PLUS */ - YYSYMBOL_STAR = 364, /* STAR */ - YYSYMBOL_SLASH = 365, /* SLASH */ - YYSYMBOL_PERCENT = 366, /* PERCENT */ - YYSYMBOL_LEFT_ANGLE = 367, /* LEFT_ANGLE */ - YYSYMBOL_RIGHT_ANGLE = 368, /* RIGHT_ANGLE */ - YYSYMBOL_VERTICAL_BAR = 369, /* VERTICAL_BAR */ - YYSYMBOL_CARET = 370, /* CARET */ - YYSYMBOL_AMPERSAND = 371, /* AMPERSAND */ - YYSYMBOL_QUESTION = 372, /* QUESTION */ - YYSYMBOL_INVARIANT = 373, /* INVARIANT */ - YYSYMBOL_HIGH_PRECISION = 374, /* HIGH_PRECISION */ - YYSYMBOL_MEDIUM_PRECISION = 375, /* MEDIUM_PRECISION */ - YYSYMBOL_LOW_PRECISION = 376, /* LOW_PRECISION */ - YYSYMBOL_PRECISION = 377, /* PRECISION */ - YYSYMBOL_PACKED = 378, /* PACKED */ - YYSYMBOL_RESOURCE = 379, /* RESOURCE */ - YYSYMBOL_SUPERP = 380, /* SUPERP */ - YYSYMBOL_FLOATCONSTANT = 381, /* FLOATCONSTANT */ - YYSYMBOL_INTCONSTANT = 382, /* INTCONSTANT */ - YYSYMBOL_UINTCONSTANT = 383, /* UINTCONSTANT */ - YYSYMBOL_BOOLCONSTANT = 384, /* BOOLCONSTANT */ - YYSYMBOL_IDENTIFIER = 385, /* IDENTIFIER */ - YYSYMBOL_TYPE_NAME = 386, /* TYPE_NAME */ - YYSYMBOL_CENTROID = 387, /* CENTROID */ - YYSYMBOL_IN = 388, /* IN */ - YYSYMBOL_OUT = 389, /* OUT */ - YYSYMBOL_INOUT = 390, /* INOUT */ - YYSYMBOL_STRUCT = 391, /* STRUCT */ - YYSYMBOL_VOID = 392, /* VOID */ - YYSYMBOL_WHILE = 393, /* WHILE */ - YYSYMBOL_BREAK = 394, /* BREAK */ - YYSYMBOL_CONTINUE = 395, /* CONTINUE */ - YYSYMBOL_DO = 396, /* DO */ - YYSYMBOL_ELSE = 397, /* ELSE */ - YYSYMBOL_FOR = 398, /* FOR */ - YYSYMBOL_IF = 399, /* IF */ - YYSYMBOL_DISCARD = 400, /* DISCARD */ - YYSYMBOL_RETURN = 401, /* RETURN */ - YYSYMBOL_SWITCH = 402, /* SWITCH */ - YYSYMBOL_CASE = 403, /* CASE */ - YYSYMBOL_DEFAULT = 404, /* DEFAULT */ - YYSYMBOL_TERMINATE_INVOCATION = 405, /* TERMINATE_INVOCATION */ - YYSYMBOL_TERMINATE_RAY = 406, /* TERMINATE_RAY */ - YYSYMBOL_IGNORE_INTERSECTION = 407, /* IGNORE_INTERSECTION */ - YYSYMBOL_UNIFORM = 408, /* UNIFORM */ - YYSYMBOL_SHARED = 409, /* SHARED */ - YYSYMBOL_BUFFER = 410, /* BUFFER */ - YYSYMBOL_FLAT = 411, /* FLAT */ - YYSYMBOL_SMOOTH = 412, /* SMOOTH */ - YYSYMBOL_LAYOUT = 413, /* LAYOUT */ - YYSYMBOL_DOUBLECONSTANT = 414, /* DOUBLECONSTANT */ - YYSYMBOL_INT16CONSTANT = 415, /* INT16CONSTANT */ - YYSYMBOL_UINT16CONSTANT = 416, /* UINT16CONSTANT */ - YYSYMBOL_FLOAT16CONSTANT = 417, /* FLOAT16CONSTANT */ - YYSYMBOL_INT32CONSTANT = 418, /* INT32CONSTANT */ - YYSYMBOL_UINT32CONSTANT = 419, /* UINT32CONSTANT */ - YYSYMBOL_INT64CONSTANT = 420, /* INT64CONSTANT */ - YYSYMBOL_UINT64CONSTANT = 421, /* UINT64CONSTANT */ - YYSYMBOL_SUBROUTINE = 422, /* SUBROUTINE */ - YYSYMBOL_DEMOTE = 423, /* DEMOTE */ - YYSYMBOL_PAYLOADNV = 424, /* PAYLOADNV */ - YYSYMBOL_PAYLOADINNV = 425, /* PAYLOADINNV */ - YYSYMBOL_HITATTRNV = 426, /* HITATTRNV */ - YYSYMBOL_CALLDATANV = 427, /* CALLDATANV */ - YYSYMBOL_CALLDATAINNV = 428, /* CALLDATAINNV */ - YYSYMBOL_PAYLOADEXT = 429, /* PAYLOADEXT */ - YYSYMBOL_PAYLOADINEXT = 430, /* PAYLOADINEXT */ - YYSYMBOL_HITATTREXT = 431, /* HITATTREXT */ - YYSYMBOL_CALLDATAEXT = 432, /* CALLDATAEXT */ - YYSYMBOL_CALLDATAINEXT = 433, /* CALLDATAINEXT */ - YYSYMBOL_PATCH = 434, /* PATCH */ - YYSYMBOL_SAMPLE = 435, /* SAMPLE */ - YYSYMBOL_NONUNIFORM = 436, /* NONUNIFORM */ - YYSYMBOL_COHERENT = 437, /* COHERENT */ - YYSYMBOL_VOLATILE = 438, /* VOLATILE */ - YYSYMBOL_RESTRICT = 439, /* RESTRICT */ - YYSYMBOL_READONLY = 440, /* READONLY */ - YYSYMBOL_WRITEONLY = 441, /* WRITEONLY */ - YYSYMBOL_DEVICECOHERENT = 442, /* DEVICECOHERENT */ - YYSYMBOL_QUEUEFAMILYCOHERENT = 443, /* QUEUEFAMILYCOHERENT */ - YYSYMBOL_WORKGROUPCOHERENT = 444, /* WORKGROUPCOHERENT */ - YYSYMBOL_SUBGROUPCOHERENT = 445, /* SUBGROUPCOHERENT */ - YYSYMBOL_NONPRIVATE = 446, /* NONPRIVATE */ - YYSYMBOL_SHADERCALLCOHERENT = 447, /* SHADERCALLCOHERENT */ - YYSYMBOL_NOPERSPECTIVE = 448, /* NOPERSPECTIVE */ - YYSYMBOL_EXPLICITINTERPAMD = 449, /* EXPLICITINTERPAMD */ - YYSYMBOL_PERVERTEXNV = 450, /* PERVERTEXNV */ - YYSYMBOL_PERPRIMITIVENV = 451, /* PERPRIMITIVENV */ - YYSYMBOL_PERVIEWNV = 452, /* PERVIEWNV */ - YYSYMBOL_PERTASKNV = 453, /* PERTASKNV */ - YYSYMBOL_PRECISE = 454, /* PRECISE */ - YYSYMBOL_YYACCEPT = 455, /* $accept */ - YYSYMBOL_variable_identifier = 456, /* variable_identifier */ - YYSYMBOL_primary_expression = 457, /* primary_expression */ - YYSYMBOL_postfix_expression = 458, /* postfix_expression */ - YYSYMBOL_integer_expression = 459, /* integer_expression */ - YYSYMBOL_function_call = 460, /* function_call */ - YYSYMBOL_function_call_or_method = 461, /* function_call_or_method */ - YYSYMBOL_function_call_generic = 462, /* function_call_generic */ - YYSYMBOL_function_call_header_no_parameters = 463, /* function_call_header_no_parameters */ - YYSYMBOL_function_call_header_with_parameters = 464, /* function_call_header_with_parameters */ - YYSYMBOL_function_call_header = 465, /* function_call_header */ - YYSYMBOL_function_identifier = 466, /* function_identifier */ - YYSYMBOL_unary_expression = 467, /* unary_expression */ - YYSYMBOL_unary_operator = 468, /* unary_operator */ - YYSYMBOL_multiplicative_expression = 469, /* multiplicative_expression */ - YYSYMBOL_additive_expression = 470, /* additive_expression */ - YYSYMBOL_shift_expression = 471, /* shift_expression */ - YYSYMBOL_relational_expression = 472, /* relational_expression */ - YYSYMBOL_equality_expression = 473, /* equality_expression */ - YYSYMBOL_and_expression = 474, /* and_expression */ - YYSYMBOL_exclusive_or_expression = 475, /* exclusive_or_expression */ - YYSYMBOL_inclusive_or_expression = 476, /* inclusive_or_expression */ - YYSYMBOL_logical_and_expression = 477, /* logical_and_expression */ - YYSYMBOL_logical_xor_expression = 478, /* logical_xor_expression */ - YYSYMBOL_logical_or_expression = 479, /* logical_or_expression */ - YYSYMBOL_conditional_expression = 480, /* conditional_expression */ - YYSYMBOL_481_1 = 481, /* $@1 */ - YYSYMBOL_assignment_expression = 482, /* assignment_expression */ - YYSYMBOL_assignment_operator = 483, /* assignment_operator */ - YYSYMBOL_expression = 484, /* expression */ - YYSYMBOL_constant_expression = 485, /* constant_expression */ - YYSYMBOL_declaration = 486, /* declaration */ - YYSYMBOL_block_structure = 487, /* block_structure */ - YYSYMBOL_488_2 = 488, /* $@2 */ - YYSYMBOL_identifier_list = 489, /* identifier_list */ - YYSYMBOL_function_prototype = 490, /* function_prototype */ - YYSYMBOL_function_declarator = 491, /* function_declarator */ - YYSYMBOL_function_header_with_parameters = 492, /* function_header_with_parameters */ - YYSYMBOL_function_header = 493, /* function_header */ - YYSYMBOL_parameter_declarator = 494, /* parameter_declarator */ - YYSYMBOL_parameter_declaration = 495, /* parameter_declaration */ - YYSYMBOL_parameter_type_specifier = 496, /* parameter_type_specifier */ - YYSYMBOL_init_declarator_list = 497, /* init_declarator_list */ - YYSYMBOL_single_declaration = 498, /* single_declaration */ - YYSYMBOL_fully_specified_type = 499, /* fully_specified_type */ - YYSYMBOL_invariant_qualifier = 500, /* invariant_qualifier */ - YYSYMBOL_interpolation_qualifier = 501, /* interpolation_qualifier */ - YYSYMBOL_layout_qualifier = 502, /* layout_qualifier */ - YYSYMBOL_layout_qualifier_id_list = 503, /* layout_qualifier_id_list */ - YYSYMBOL_layout_qualifier_id = 504, /* layout_qualifier_id */ - YYSYMBOL_precise_qualifier = 505, /* precise_qualifier */ - YYSYMBOL_type_qualifier = 506, /* type_qualifier */ - YYSYMBOL_single_type_qualifier = 507, /* single_type_qualifier */ - YYSYMBOL_storage_qualifier = 508, /* storage_qualifier */ - YYSYMBOL_non_uniform_qualifier = 509, /* non_uniform_qualifier */ - YYSYMBOL_type_name_list = 510, /* type_name_list */ - YYSYMBOL_type_specifier = 511, /* type_specifier */ - YYSYMBOL_array_specifier = 512, /* array_specifier */ - YYSYMBOL_type_parameter_specifier_opt = 513, /* type_parameter_specifier_opt */ - YYSYMBOL_type_parameter_specifier = 514, /* type_parameter_specifier */ - YYSYMBOL_type_parameter_specifier_list = 515, /* type_parameter_specifier_list */ - YYSYMBOL_type_specifier_nonarray = 516, /* type_specifier_nonarray */ - YYSYMBOL_precision_qualifier = 517, /* precision_qualifier */ - YYSYMBOL_struct_specifier = 518, /* struct_specifier */ - YYSYMBOL_519_3 = 519, /* $@3 */ - YYSYMBOL_520_4 = 520, /* $@4 */ - YYSYMBOL_struct_declaration_list = 521, /* struct_declaration_list */ - YYSYMBOL_struct_declaration = 522, /* struct_declaration */ - YYSYMBOL_struct_declarator_list = 523, /* struct_declarator_list */ - YYSYMBOL_struct_declarator = 524, /* struct_declarator */ - YYSYMBOL_initializer = 525, /* initializer */ - YYSYMBOL_initializer_list = 526, /* initializer_list */ - YYSYMBOL_declaration_statement = 527, /* declaration_statement */ - YYSYMBOL_statement = 528, /* statement */ - YYSYMBOL_simple_statement = 529, /* simple_statement */ - YYSYMBOL_demote_statement = 530, /* demote_statement */ - YYSYMBOL_compound_statement = 531, /* compound_statement */ - YYSYMBOL_532_5 = 532, /* $@5 */ - YYSYMBOL_533_6 = 533, /* $@6 */ - YYSYMBOL_statement_no_new_scope = 534, /* statement_no_new_scope */ - YYSYMBOL_statement_scoped = 535, /* statement_scoped */ - YYSYMBOL_536_7 = 536, /* $@7 */ - YYSYMBOL_537_8 = 537, /* $@8 */ - YYSYMBOL_compound_statement_no_new_scope = 538, /* compound_statement_no_new_scope */ - YYSYMBOL_statement_list = 539, /* statement_list */ - YYSYMBOL_expression_statement = 540, /* expression_statement */ - YYSYMBOL_selection_statement = 541, /* selection_statement */ - YYSYMBOL_selection_statement_nonattributed = 542, /* selection_statement_nonattributed */ - YYSYMBOL_selection_rest_statement = 543, /* selection_rest_statement */ - YYSYMBOL_condition = 544, /* condition */ - YYSYMBOL_switch_statement = 545, /* switch_statement */ - YYSYMBOL_switch_statement_nonattributed = 546, /* switch_statement_nonattributed */ - YYSYMBOL_547_9 = 547, /* $@9 */ - YYSYMBOL_switch_statement_list = 548, /* switch_statement_list */ - YYSYMBOL_case_label = 549, /* case_label */ - YYSYMBOL_iteration_statement = 550, /* iteration_statement */ - YYSYMBOL_iteration_statement_nonattributed = 551, /* iteration_statement_nonattributed */ - YYSYMBOL_552_10 = 552, /* $@10 */ - YYSYMBOL_553_11 = 553, /* $@11 */ - YYSYMBOL_554_12 = 554, /* $@12 */ - YYSYMBOL_for_init_statement = 555, /* for_init_statement */ - YYSYMBOL_conditionopt = 556, /* conditionopt */ - YYSYMBOL_for_rest_statement = 557, /* for_rest_statement */ - YYSYMBOL_jump_statement = 558, /* jump_statement */ - YYSYMBOL_translation_unit = 559, /* translation_unit */ - YYSYMBOL_external_declaration = 560, /* external_declaration */ - YYSYMBOL_function_definition = 561, /* function_definition */ - YYSYMBOL_562_13 = 562, /* $@13 */ - YYSYMBOL_attribute = 563, /* attribute */ - YYSYMBOL_attribute_list = 564, /* attribute_list */ - YYSYMBOL_single_attribute = 565, /* single_attribute */ - YYSYMBOL_spirv_requirements_list = 566, /* spirv_requirements_list */ - YYSYMBOL_spirv_requirements_parameter = 567, /* spirv_requirements_parameter */ - YYSYMBOL_spirv_extension_list = 568, /* spirv_extension_list */ - YYSYMBOL_spirv_capability_list = 569, /* spirv_capability_list */ - YYSYMBOL_spirv_execution_mode_qualifier = 570, /* spirv_execution_mode_qualifier */ - YYSYMBOL_spirv_execution_mode_parameter_list = 571, /* spirv_execution_mode_parameter_list */ - YYSYMBOL_spirv_execution_mode_parameter = 572, /* spirv_execution_mode_parameter */ - YYSYMBOL_spirv_execution_mode_id_parameter_list = 573, /* spirv_execution_mode_id_parameter_list */ - YYSYMBOL_spirv_storage_class_qualifier = 574, /* spirv_storage_class_qualifier */ - YYSYMBOL_spirv_decorate_qualifier = 575, /* spirv_decorate_qualifier */ - YYSYMBOL_spirv_decorate_parameter_list = 576, /* spirv_decorate_parameter_list */ - YYSYMBOL_spirv_decorate_parameter = 577, /* spirv_decorate_parameter */ - YYSYMBOL_spirv_decorate_id_parameter_list = 578, /* spirv_decorate_id_parameter_list */ - YYSYMBOL_spirv_decorate_string_parameter_list = 579, /* spirv_decorate_string_parameter_list */ - YYSYMBOL_spirv_type_specifier = 580, /* spirv_type_specifier */ - YYSYMBOL_spirv_type_parameter_list = 581, /* spirv_type_parameter_list */ - YYSYMBOL_spirv_type_parameter = 582, /* spirv_type_parameter */ - YYSYMBOL_spirv_instruction_qualifier = 583, /* spirv_instruction_qualifier */ - YYSYMBOL_spirv_instruction_qualifier_list = 584, /* spirv_instruction_qualifier_list */ - YYSYMBOL_spirv_instruction_qualifier_id = 585 /* spirv_instruction_qualifier_id */ + YYSYMBOL_COOPMAT = 166, /* COOPMAT */ + YYSYMBOL_HITOBJECTNV = 167, /* HITOBJECTNV */ + YYSYMBOL_HITOBJECTATTRNV = 168, /* HITOBJECTATTRNV */ + YYSYMBOL_SAMPLERCUBEARRAY = 169, /* SAMPLERCUBEARRAY */ + YYSYMBOL_SAMPLERCUBEARRAYSHADOW = 170, /* SAMPLERCUBEARRAYSHADOW */ + YYSYMBOL_ISAMPLERCUBEARRAY = 171, /* ISAMPLERCUBEARRAY */ + YYSYMBOL_USAMPLERCUBEARRAY = 172, /* USAMPLERCUBEARRAY */ + YYSYMBOL_SAMPLER1D = 173, /* SAMPLER1D */ + YYSYMBOL_SAMPLER1DARRAY = 174, /* SAMPLER1DARRAY */ + YYSYMBOL_SAMPLER1DARRAYSHADOW = 175, /* SAMPLER1DARRAYSHADOW */ + YYSYMBOL_ISAMPLER1D = 176, /* ISAMPLER1D */ + YYSYMBOL_SAMPLER1DSHADOW = 177, /* SAMPLER1DSHADOW */ + YYSYMBOL_SAMPLER2DRECT = 178, /* SAMPLER2DRECT */ + YYSYMBOL_SAMPLER2DRECTSHADOW = 179, /* SAMPLER2DRECTSHADOW */ + YYSYMBOL_ISAMPLER2DRECT = 180, /* ISAMPLER2DRECT */ + YYSYMBOL_USAMPLER2DRECT = 181, /* USAMPLER2DRECT */ + YYSYMBOL_SAMPLERBUFFER = 182, /* SAMPLERBUFFER */ + YYSYMBOL_ISAMPLERBUFFER = 183, /* ISAMPLERBUFFER */ + YYSYMBOL_USAMPLERBUFFER = 184, /* USAMPLERBUFFER */ + YYSYMBOL_SAMPLER2DMS = 185, /* SAMPLER2DMS */ + YYSYMBOL_ISAMPLER2DMS = 186, /* ISAMPLER2DMS */ + YYSYMBOL_USAMPLER2DMS = 187, /* USAMPLER2DMS */ + YYSYMBOL_SAMPLER2DMSARRAY = 188, /* SAMPLER2DMSARRAY */ + YYSYMBOL_ISAMPLER2DMSARRAY = 189, /* ISAMPLER2DMSARRAY */ + YYSYMBOL_USAMPLER2DMSARRAY = 190, /* USAMPLER2DMSARRAY */ + YYSYMBOL_SAMPLEREXTERNALOES = 191, /* SAMPLEREXTERNALOES */ + YYSYMBOL_SAMPLEREXTERNAL2DY2YEXT = 192, /* SAMPLEREXTERNAL2DY2YEXT */ + YYSYMBOL_ISAMPLER1DARRAY = 193, /* ISAMPLER1DARRAY */ + YYSYMBOL_USAMPLER1D = 194, /* USAMPLER1D */ + YYSYMBOL_USAMPLER1DARRAY = 195, /* USAMPLER1DARRAY */ + YYSYMBOL_F16SAMPLER1D = 196, /* F16SAMPLER1D */ + YYSYMBOL_F16SAMPLER2D = 197, /* F16SAMPLER2D */ + YYSYMBOL_F16SAMPLER3D = 198, /* F16SAMPLER3D */ + YYSYMBOL_F16SAMPLER2DRECT = 199, /* F16SAMPLER2DRECT */ + YYSYMBOL_F16SAMPLERCUBE = 200, /* F16SAMPLERCUBE */ + YYSYMBOL_F16SAMPLER1DARRAY = 201, /* F16SAMPLER1DARRAY */ + YYSYMBOL_F16SAMPLER2DARRAY = 202, /* F16SAMPLER2DARRAY */ + YYSYMBOL_F16SAMPLERCUBEARRAY = 203, /* F16SAMPLERCUBEARRAY */ + YYSYMBOL_F16SAMPLERBUFFER = 204, /* F16SAMPLERBUFFER */ + YYSYMBOL_F16SAMPLER2DMS = 205, /* F16SAMPLER2DMS */ + YYSYMBOL_F16SAMPLER2DMSARRAY = 206, /* F16SAMPLER2DMSARRAY */ + YYSYMBOL_F16SAMPLER1DSHADOW = 207, /* F16SAMPLER1DSHADOW */ + YYSYMBOL_F16SAMPLER2DSHADOW = 208, /* F16SAMPLER2DSHADOW */ + YYSYMBOL_F16SAMPLER1DARRAYSHADOW = 209, /* F16SAMPLER1DARRAYSHADOW */ + YYSYMBOL_F16SAMPLER2DARRAYSHADOW = 210, /* F16SAMPLER2DARRAYSHADOW */ + YYSYMBOL_F16SAMPLER2DRECTSHADOW = 211, /* F16SAMPLER2DRECTSHADOW */ + YYSYMBOL_F16SAMPLERCUBESHADOW = 212, /* F16SAMPLERCUBESHADOW */ + YYSYMBOL_F16SAMPLERCUBEARRAYSHADOW = 213, /* F16SAMPLERCUBEARRAYSHADOW */ + YYSYMBOL_IMAGE1D = 214, /* IMAGE1D */ + YYSYMBOL_IIMAGE1D = 215, /* IIMAGE1D */ + YYSYMBOL_UIMAGE1D = 216, /* UIMAGE1D */ + YYSYMBOL_IMAGE2D = 217, /* IMAGE2D */ + YYSYMBOL_IIMAGE2D = 218, /* IIMAGE2D */ + YYSYMBOL_UIMAGE2D = 219, /* UIMAGE2D */ + YYSYMBOL_IMAGE3D = 220, /* IMAGE3D */ + YYSYMBOL_IIMAGE3D = 221, /* IIMAGE3D */ + YYSYMBOL_UIMAGE3D = 222, /* UIMAGE3D */ + YYSYMBOL_IMAGE2DRECT = 223, /* IMAGE2DRECT */ + YYSYMBOL_IIMAGE2DRECT = 224, /* IIMAGE2DRECT */ + YYSYMBOL_UIMAGE2DRECT = 225, /* UIMAGE2DRECT */ + YYSYMBOL_IMAGECUBE = 226, /* IMAGECUBE */ + YYSYMBOL_IIMAGECUBE = 227, /* IIMAGECUBE */ + YYSYMBOL_UIMAGECUBE = 228, /* UIMAGECUBE */ + YYSYMBOL_IMAGEBUFFER = 229, /* IMAGEBUFFER */ + YYSYMBOL_IIMAGEBUFFER = 230, /* IIMAGEBUFFER */ + YYSYMBOL_UIMAGEBUFFER = 231, /* UIMAGEBUFFER */ + YYSYMBOL_IMAGE1DARRAY = 232, /* IMAGE1DARRAY */ + YYSYMBOL_IIMAGE1DARRAY = 233, /* IIMAGE1DARRAY */ + YYSYMBOL_UIMAGE1DARRAY = 234, /* UIMAGE1DARRAY */ + YYSYMBOL_IMAGE2DARRAY = 235, /* IMAGE2DARRAY */ + YYSYMBOL_IIMAGE2DARRAY = 236, /* IIMAGE2DARRAY */ + YYSYMBOL_UIMAGE2DARRAY = 237, /* UIMAGE2DARRAY */ + YYSYMBOL_IMAGECUBEARRAY = 238, /* IMAGECUBEARRAY */ + YYSYMBOL_IIMAGECUBEARRAY = 239, /* IIMAGECUBEARRAY */ + YYSYMBOL_UIMAGECUBEARRAY = 240, /* UIMAGECUBEARRAY */ + YYSYMBOL_IMAGE2DMS = 241, /* IMAGE2DMS */ + YYSYMBOL_IIMAGE2DMS = 242, /* IIMAGE2DMS */ + YYSYMBOL_UIMAGE2DMS = 243, /* UIMAGE2DMS */ + YYSYMBOL_IMAGE2DMSARRAY = 244, /* IMAGE2DMSARRAY */ + YYSYMBOL_IIMAGE2DMSARRAY = 245, /* IIMAGE2DMSARRAY */ + YYSYMBOL_UIMAGE2DMSARRAY = 246, /* UIMAGE2DMSARRAY */ + YYSYMBOL_F16IMAGE1D = 247, /* F16IMAGE1D */ + YYSYMBOL_F16IMAGE2D = 248, /* F16IMAGE2D */ + YYSYMBOL_F16IMAGE3D = 249, /* F16IMAGE3D */ + YYSYMBOL_F16IMAGE2DRECT = 250, /* F16IMAGE2DRECT */ + YYSYMBOL_F16IMAGECUBE = 251, /* F16IMAGECUBE */ + YYSYMBOL_F16IMAGE1DARRAY = 252, /* F16IMAGE1DARRAY */ + YYSYMBOL_F16IMAGE2DARRAY = 253, /* F16IMAGE2DARRAY */ + YYSYMBOL_F16IMAGECUBEARRAY = 254, /* F16IMAGECUBEARRAY */ + YYSYMBOL_F16IMAGEBUFFER = 255, /* F16IMAGEBUFFER */ + YYSYMBOL_F16IMAGE2DMS = 256, /* F16IMAGE2DMS */ + YYSYMBOL_F16IMAGE2DMSARRAY = 257, /* F16IMAGE2DMSARRAY */ + YYSYMBOL_I64IMAGE1D = 258, /* I64IMAGE1D */ + YYSYMBOL_U64IMAGE1D = 259, /* U64IMAGE1D */ + YYSYMBOL_I64IMAGE2D = 260, /* I64IMAGE2D */ + YYSYMBOL_U64IMAGE2D = 261, /* U64IMAGE2D */ + YYSYMBOL_I64IMAGE3D = 262, /* I64IMAGE3D */ + YYSYMBOL_U64IMAGE3D = 263, /* U64IMAGE3D */ + YYSYMBOL_I64IMAGE2DRECT = 264, /* I64IMAGE2DRECT */ + YYSYMBOL_U64IMAGE2DRECT = 265, /* U64IMAGE2DRECT */ + YYSYMBOL_I64IMAGECUBE = 266, /* I64IMAGECUBE */ + YYSYMBOL_U64IMAGECUBE = 267, /* U64IMAGECUBE */ + YYSYMBOL_I64IMAGEBUFFER = 268, /* I64IMAGEBUFFER */ + YYSYMBOL_U64IMAGEBUFFER = 269, /* U64IMAGEBUFFER */ + YYSYMBOL_I64IMAGE1DARRAY = 270, /* I64IMAGE1DARRAY */ + YYSYMBOL_U64IMAGE1DARRAY = 271, /* U64IMAGE1DARRAY */ + YYSYMBOL_I64IMAGE2DARRAY = 272, /* I64IMAGE2DARRAY */ + YYSYMBOL_U64IMAGE2DARRAY = 273, /* U64IMAGE2DARRAY */ + YYSYMBOL_I64IMAGECUBEARRAY = 274, /* I64IMAGECUBEARRAY */ + YYSYMBOL_U64IMAGECUBEARRAY = 275, /* U64IMAGECUBEARRAY */ + YYSYMBOL_I64IMAGE2DMS = 276, /* I64IMAGE2DMS */ + YYSYMBOL_U64IMAGE2DMS = 277, /* U64IMAGE2DMS */ + YYSYMBOL_I64IMAGE2DMSARRAY = 278, /* I64IMAGE2DMSARRAY */ + YYSYMBOL_U64IMAGE2DMSARRAY = 279, /* U64IMAGE2DMSARRAY */ + YYSYMBOL_TEXTURECUBEARRAY = 280, /* TEXTURECUBEARRAY */ + YYSYMBOL_ITEXTURECUBEARRAY = 281, /* ITEXTURECUBEARRAY */ + YYSYMBOL_UTEXTURECUBEARRAY = 282, /* UTEXTURECUBEARRAY */ + YYSYMBOL_TEXTURE1D = 283, /* TEXTURE1D */ + YYSYMBOL_ITEXTURE1D = 284, /* ITEXTURE1D */ + YYSYMBOL_UTEXTURE1D = 285, /* UTEXTURE1D */ + YYSYMBOL_TEXTURE1DARRAY = 286, /* TEXTURE1DARRAY */ + YYSYMBOL_ITEXTURE1DARRAY = 287, /* ITEXTURE1DARRAY */ + YYSYMBOL_UTEXTURE1DARRAY = 288, /* UTEXTURE1DARRAY */ + YYSYMBOL_TEXTURE2DRECT = 289, /* TEXTURE2DRECT */ + YYSYMBOL_ITEXTURE2DRECT = 290, /* ITEXTURE2DRECT */ + YYSYMBOL_UTEXTURE2DRECT = 291, /* UTEXTURE2DRECT */ + YYSYMBOL_TEXTUREBUFFER = 292, /* TEXTUREBUFFER */ + YYSYMBOL_ITEXTUREBUFFER = 293, /* ITEXTUREBUFFER */ + YYSYMBOL_UTEXTUREBUFFER = 294, /* UTEXTUREBUFFER */ + YYSYMBOL_TEXTURE2DMS = 295, /* TEXTURE2DMS */ + YYSYMBOL_ITEXTURE2DMS = 296, /* ITEXTURE2DMS */ + YYSYMBOL_UTEXTURE2DMS = 297, /* UTEXTURE2DMS */ + YYSYMBOL_TEXTURE2DMSARRAY = 298, /* TEXTURE2DMSARRAY */ + YYSYMBOL_ITEXTURE2DMSARRAY = 299, /* ITEXTURE2DMSARRAY */ + YYSYMBOL_UTEXTURE2DMSARRAY = 300, /* UTEXTURE2DMSARRAY */ + YYSYMBOL_F16TEXTURE1D = 301, /* F16TEXTURE1D */ + YYSYMBOL_F16TEXTURE2D = 302, /* F16TEXTURE2D */ + YYSYMBOL_F16TEXTURE3D = 303, /* F16TEXTURE3D */ + YYSYMBOL_F16TEXTURE2DRECT = 304, /* F16TEXTURE2DRECT */ + YYSYMBOL_F16TEXTURECUBE = 305, /* F16TEXTURECUBE */ + YYSYMBOL_F16TEXTURE1DARRAY = 306, /* F16TEXTURE1DARRAY */ + YYSYMBOL_F16TEXTURE2DARRAY = 307, /* F16TEXTURE2DARRAY */ + YYSYMBOL_F16TEXTURECUBEARRAY = 308, /* F16TEXTURECUBEARRAY */ + YYSYMBOL_F16TEXTUREBUFFER = 309, /* F16TEXTUREBUFFER */ + YYSYMBOL_F16TEXTURE2DMS = 310, /* F16TEXTURE2DMS */ + YYSYMBOL_F16TEXTURE2DMSARRAY = 311, /* F16TEXTURE2DMSARRAY */ + YYSYMBOL_SUBPASSINPUT = 312, /* SUBPASSINPUT */ + YYSYMBOL_SUBPASSINPUTMS = 313, /* SUBPASSINPUTMS */ + YYSYMBOL_ISUBPASSINPUT = 314, /* ISUBPASSINPUT */ + YYSYMBOL_ISUBPASSINPUTMS = 315, /* ISUBPASSINPUTMS */ + YYSYMBOL_USUBPASSINPUT = 316, /* USUBPASSINPUT */ + YYSYMBOL_USUBPASSINPUTMS = 317, /* USUBPASSINPUTMS */ + YYSYMBOL_F16SUBPASSINPUT = 318, /* F16SUBPASSINPUT */ + YYSYMBOL_F16SUBPASSINPUTMS = 319, /* F16SUBPASSINPUTMS */ + YYSYMBOL_SPIRV_INSTRUCTION = 320, /* SPIRV_INSTRUCTION */ + YYSYMBOL_SPIRV_EXECUTION_MODE = 321, /* SPIRV_EXECUTION_MODE */ + YYSYMBOL_SPIRV_EXECUTION_MODE_ID = 322, /* SPIRV_EXECUTION_MODE_ID */ + YYSYMBOL_SPIRV_DECORATE = 323, /* SPIRV_DECORATE */ + YYSYMBOL_SPIRV_DECORATE_ID = 324, /* SPIRV_DECORATE_ID */ + YYSYMBOL_SPIRV_DECORATE_STRING = 325, /* SPIRV_DECORATE_STRING */ + YYSYMBOL_SPIRV_TYPE = 326, /* SPIRV_TYPE */ + YYSYMBOL_SPIRV_STORAGE_CLASS = 327, /* SPIRV_STORAGE_CLASS */ + YYSYMBOL_SPIRV_BY_REFERENCE = 328, /* SPIRV_BY_REFERENCE */ + YYSYMBOL_SPIRV_LITERAL = 329, /* SPIRV_LITERAL */ + YYSYMBOL_ATTACHMENTEXT = 330, /* ATTACHMENTEXT */ + YYSYMBOL_IATTACHMENTEXT = 331, /* IATTACHMENTEXT */ + YYSYMBOL_UATTACHMENTEXT = 332, /* UATTACHMENTEXT */ + YYSYMBOL_LEFT_OP = 333, /* LEFT_OP */ + YYSYMBOL_RIGHT_OP = 334, /* RIGHT_OP */ + YYSYMBOL_INC_OP = 335, /* INC_OP */ + YYSYMBOL_DEC_OP = 336, /* DEC_OP */ + YYSYMBOL_LE_OP = 337, /* LE_OP */ + YYSYMBOL_GE_OP = 338, /* GE_OP */ + YYSYMBOL_EQ_OP = 339, /* EQ_OP */ + YYSYMBOL_NE_OP = 340, /* NE_OP */ + YYSYMBOL_AND_OP = 341, /* AND_OP */ + YYSYMBOL_OR_OP = 342, /* OR_OP */ + YYSYMBOL_XOR_OP = 343, /* XOR_OP */ + YYSYMBOL_MUL_ASSIGN = 344, /* MUL_ASSIGN */ + YYSYMBOL_DIV_ASSIGN = 345, /* DIV_ASSIGN */ + YYSYMBOL_ADD_ASSIGN = 346, /* ADD_ASSIGN */ + YYSYMBOL_MOD_ASSIGN = 347, /* MOD_ASSIGN */ + YYSYMBOL_LEFT_ASSIGN = 348, /* LEFT_ASSIGN */ + YYSYMBOL_RIGHT_ASSIGN = 349, /* RIGHT_ASSIGN */ + YYSYMBOL_AND_ASSIGN = 350, /* AND_ASSIGN */ + YYSYMBOL_XOR_ASSIGN = 351, /* XOR_ASSIGN */ + YYSYMBOL_OR_ASSIGN = 352, /* OR_ASSIGN */ + YYSYMBOL_SUB_ASSIGN = 353, /* SUB_ASSIGN */ + YYSYMBOL_STRING_LITERAL = 354, /* STRING_LITERAL */ + YYSYMBOL_LEFT_PAREN = 355, /* LEFT_PAREN */ + YYSYMBOL_RIGHT_PAREN = 356, /* RIGHT_PAREN */ + YYSYMBOL_LEFT_BRACKET = 357, /* LEFT_BRACKET */ + YYSYMBOL_RIGHT_BRACKET = 358, /* RIGHT_BRACKET */ + YYSYMBOL_LEFT_BRACE = 359, /* LEFT_BRACE */ + YYSYMBOL_RIGHT_BRACE = 360, /* RIGHT_BRACE */ + YYSYMBOL_DOT = 361, /* DOT */ + YYSYMBOL_COMMA = 362, /* COMMA */ + YYSYMBOL_COLON = 363, /* COLON */ + YYSYMBOL_EQUAL = 364, /* EQUAL */ + YYSYMBOL_SEMICOLON = 365, /* SEMICOLON */ + YYSYMBOL_BANG = 366, /* BANG */ + YYSYMBOL_DASH = 367, /* DASH */ + YYSYMBOL_TILDE = 368, /* TILDE */ + YYSYMBOL_PLUS = 369, /* PLUS */ + YYSYMBOL_STAR = 370, /* STAR */ + YYSYMBOL_SLASH = 371, /* SLASH */ + YYSYMBOL_PERCENT = 372, /* PERCENT */ + YYSYMBOL_LEFT_ANGLE = 373, /* LEFT_ANGLE */ + YYSYMBOL_RIGHT_ANGLE = 374, /* RIGHT_ANGLE */ + YYSYMBOL_VERTICAL_BAR = 375, /* VERTICAL_BAR */ + YYSYMBOL_CARET = 376, /* CARET */ + YYSYMBOL_AMPERSAND = 377, /* AMPERSAND */ + YYSYMBOL_QUESTION = 378, /* QUESTION */ + YYSYMBOL_INVARIANT = 379, /* INVARIANT */ + YYSYMBOL_HIGH_PRECISION = 380, /* HIGH_PRECISION */ + YYSYMBOL_MEDIUM_PRECISION = 381, /* MEDIUM_PRECISION */ + YYSYMBOL_LOW_PRECISION = 382, /* LOW_PRECISION */ + YYSYMBOL_PRECISION = 383, /* PRECISION */ + YYSYMBOL_PACKED = 384, /* PACKED */ + YYSYMBOL_RESOURCE = 385, /* RESOURCE */ + YYSYMBOL_SUPERP = 386, /* SUPERP */ + YYSYMBOL_FLOATCONSTANT = 387, /* FLOATCONSTANT */ + YYSYMBOL_INTCONSTANT = 388, /* INTCONSTANT */ + YYSYMBOL_UINTCONSTANT = 389, /* UINTCONSTANT */ + YYSYMBOL_BOOLCONSTANT = 390, /* BOOLCONSTANT */ + YYSYMBOL_IDENTIFIER = 391, /* IDENTIFIER */ + YYSYMBOL_TYPE_NAME = 392, /* TYPE_NAME */ + YYSYMBOL_CENTROID = 393, /* CENTROID */ + YYSYMBOL_IN = 394, /* IN */ + YYSYMBOL_OUT = 395, /* OUT */ + YYSYMBOL_INOUT = 396, /* INOUT */ + YYSYMBOL_STRUCT = 397, /* STRUCT */ + YYSYMBOL_VOID = 398, /* VOID */ + YYSYMBOL_WHILE = 399, /* WHILE */ + YYSYMBOL_BREAK = 400, /* BREAK */ + YYSYMBOL_CONTINUE = 401, /* CONTINUE */ + YYSYMBOL_DO = 402, /* DO */ + YYSYMBOL_ELSE = 403, /* ELSE */ + YYSYMBOL_FOR = 404, /* FOR */ + YYSYMBOL_IF = 405, /* IF */ + YYSYMBOL_DISCARD = 406, /* DISCARD */ + YYSYMBOL_RETURN = 407, /* RETURN */ + YYSYMBOL_SWITCH = 408, /* SWITCH */ + YYSYMBOL_CASE = 409, /* CASE */ + YYSYMBOL_DEFAULT = 410, /* DEFAULT */ + YYSYMBOL_TERMINATE_INVOCATION = 411, /* TERMINATE_INVOCATION */ + YYSYMBOL_TERMINATE_RAY = 412, /* TERMINATE_RAY */ + YYSYMBOL_IGNORE_INTERSECTION = 413, /* IGNORE_INTERSECTION */ + YYSYMBOL_UNIFORM = 414, /* UNIFORM */ + YYSYMBOL_SHARED = 415, /* SHARED */ + YYSYMBOL_BUFFER = 416, /* BUFFER */ + YYSYMBOL_TILEIMAGEEXT = 417, /* TILEIMAGEEXT */ + YYSYMBOL_FLAT = 418, /* FLAT */ + YYSYMBOL_SMOOTH = 419, /* SMOOTH */ + YYSYMBOL_LAYOUT = 420, /* LAYOUT */ + YYSYMBOL_DOUBLECONSTANT = 421, /* DOUBLECONSTANT */ + YYSYMBOL_INT16CONSTANT = 422, /* INT16CONSTANT */ + YYSYMBOL_UINT16CONSTANT = 423, /* UINT16CONSTANT */ + YYSYMBOL_FLOAT16CONSTANT = 424, /* FLOAT16CONSTANT */ + YYSYMBOL_INT32CONSTANT = 425, /* INT32CONSTANT */ + YYSYMBOL_UINT32CONSTANT = 426, /* UINT32CONSTANT */ + YYSYMBOL_INT64CONSTANT = 427, /* INT64CONSTANT */ + YYSYMBOL_UINT64CONSTANT = 428, /* UINT64CONSTANT */ + YYSYMBOL_SUBROUTINE = 429, /* SUBROUTINE */ + YYSYMBOL_DEMOTE = 430, /* DEMOTE */ + YYSYMBOL_PAYLOADNV = 431, /* PAYLOADNV */ + YYSYMBOL_PAYLOADINNV = 432, /* PAYLOADINNV */ + YYSYMBOL_HITATTRNV = 433, /* HITATTRNV */ + YYSYMBOL_CALLDATANV = 434, /* CALLDATANV */ + YYSYMBOL_CALLDATAINNV = 435, /* CALLDATAINNV */ + YYSYMBOL_PAYLOADEXT = 436, /* PAYLOADEXT */ + YYSYMBOL_PAYLOADINEXT = 437, /* PAYLOADINEXT */ + YYSYMBOL_HITATTREXT = 438, /* HITATTREXT */ + YYSYMBOL_CALLDATAEXT = 439, /* CALLDATAEXT */ + YYSYMBOL_CALLDATAINEXT = 440, /* CALLDATAINEXT */ + YYSYMBOL_PATCH = 441, /* PATCH */ + YYSYMBOL_SAMPLE = 442, /* SAMPLE */ + YYSYMBOL_NONUNIFORM = 443, /* NONUNIFORM */ + YYSYMBOL_COHERENT = 444, /* COHERENT */ + YYSYMBOL_VOLATILE = 445, /* VOLATILE */ + YYSYMBOL_RESTRICT = 446, /* RESTRICT */ + YYSYMBOL_READONLY = 447, /* READONLY */ + YYSYMBOL_WRITEONLY = 448, /* WRITEONLY */ + YYSYMBOL_DEVICECOHERENT = 449, /* DEVICECOHERENT */ + YYSYMBOL_QUEUEFAMILYCOHERENT = 450, /* QUEUEFAMILYCOHERENT */ + YYSYMBOL_WORKGROUPCOHERENT = 451, /* WORKGROUPCOHERENT */ + YYSYMBOL_SUBGROUPCOHERENT = 452, /* SUBGROUPCOHERENT */ + YYSYMBOL_NONPRIVATE = 453, /* NONPRIVATE */ + YYSYMBOL_SHADERCALLCOHERENT = 454, /* SHADERCALLCOHERENT */ + YYSYMBOL_NOPERSPECTIVE = 455, /* NOPERSPECTIVE */ + YYSYMBOL_EXPLICITINTERPAMD = 456, /* EXPLICITINTERPAMD */ + YYSYMBOL_PERVERTEXEXT = 457, /* PERVERTEXEXT */ + YYSYMBOL_PERVERTEXNV = 458, /* PERVERTEXNV */ + YYSYMBOL_PERPRIMITIVENV = 459, /* PERPRIMITIVENV */ + YYSYMBOL_PERVIEWNV = 460, /* PERVIEWNV */ + YYSYMBOL_PERTASKNV = 461, /* PERTASKNV */ + YYSYMBOL_PERPRIMITIVEEXT = 462, /* PERPRIMITIVEEXT */ + YYSYMBOL_TASKPAYLOADWORKGROUPEXT = 463, /* TASKPAYLOADWORKGROUPEXT */ + YYSYMBOL_PRECISE = 464, /* PRECISE */ + YYSYMBOL_YYACCEPT = 465, /* $accept */ + YYSYMBOL_variable_identifier = 466, /* variable_identifier */ + YYSYMBOL_primary_expression = 467, /* primary_expression */ + YYSYMBOL_postfix_expression = 468, /* postfix_expression */ + YYSYMBOL_integer_expression = 469, /* integer_expression */ + YYSYMBOL_function_call = 470, /* function_call */ + YYSYMBOL_function_call_or_method = 471, /* function_call_or_method */ + YYSYMBOL_function_call_generic = 472, /* function_call_generic */ + YYSYMBOL_function_call_header_no_parameters = 473, /* function_call_header_no_parameters */ + YYSYMBOL_function_call_header_with_parameters = 474, /* function_call_header_with_parameters */ + YYSYMBOL_function_call_header = 475, /* function_call_header */ + YYSYMBOL_function_identifier = 476, /* function_identifier */ + YYSYMBOL_unary_expression = 477, /* unary_expression */ + YYSYMBOL_unary_operator = 478, /* unary_operator */ + YYSYMBOL_multiplicative_expression = 479, /* multiplicative_expression */ + YYSYMBOL_additive_expression = 480, /* additive_expression */ + YYSYMBOL_shift_expression = 481, /* shift_expression */ + YYSYMBOL_relational_expression = 482, /* relational_expression */ + YYSYMBOL_equality_expression = 483, /* equality_expression */ + YYSYMBOL_and_expression = 484, /* and_expression */ + YYSYMBOL_exclusive_or_expression = 485, /* exclusive_or_expression */ + YYSYMBOL_inclusive_or_expression = 486, /* inclusive_or_expression */ + YYSYMBOL_logical_and_expression = 487, /* logical_and_expression */ + YYSYMBOL_logical_xor_expression = 488, /* logical_xor_expression */ + YYSYMBOL_logical_or_expression = 489, /* logical_or_expression */ + YYSYMBOL_conditional_expression = 490, /* conditional_expression */ + YYSYMBOL_491_1 = 491, /* $@1 */ + YYSYMBOL_assignment_expression = 492, /* assignment_expression */ + YYSYMBOL_assignment_operator = 493, /* assignment_operator */ + YYSYMBOL_expression = 494, /* expression */ + YYSYMBOL_constant_expression = 495, /* constant_expression */ + YYSYMBOL_declaration = 496, /* declaration */ + YYSYMBOL_block_structure = 497, /* block_structure */ + YYSYMBOL_498_2 = 498, /* $@2 */ + YYSYMBOL_identifier_list = 499, /* identifier_list */ + YYSYMBOL_function_prototype = 500, /* function_prototype */ + YYSYMBOL_function_declarator = 501, /* function_declarator */ + YYSYMBOL_function_header_with_parameters = 502, /* function_header_with_parameters */ + YYSYMBOL_function_header = 503, /* function_header */ + YYSYMBOL_parameter_declarator = 504, /* parameter_declarator */ + YYSYMBOL_parameter_declaration = 505, /* parameter_declaration */ + YYSYMBOL_parameter_type_specifier = 506, /* parameter_type_specifier */ + YYSYMBOL_init_declarator_list = 507, /* init_declarator_list */ + YYSYMBOL_single_declaration = 508, /* single_declaration */ + YYSYMBOL_fully_specified_type = 509, /* fully_specified_type */ + YYSYMBOL_invariant_qualifier = 510, /* invariant_qualifier */ + YYSYMBOL_interpolation_qualifier = 511, /* interpolation_qualifier */ + YYSYMBOL_layout_qualifier = 512, /* layout_qualifier */ + YYSYMBOL_layout_qualifier_id_list = 513, /* layout_qualifier_id_list */ + YYSYMBOL_layout_qualifier_id = 514, /* layout_qualifier_id */ + YYSYMBOL_precise_qualifier = 515, /* precise_qualifier */ + YYSYMBOL_type_qualifier = 516, /* type_qualifier */ + YYSYMBOL_single_type_qualifier = 517, /* single_type_qualifier */ + YYSYMBOL_storage_qualifier = 518, /* storage_qualifier */ + YYSYMBOL_non_uniform_qualifier = 519, /* non_uniform_qualifier */ + YYSYMBOL_type_name_list = 520, /* type_name_list */ + YYSYMBOL_type_specifier = 521, /* type_specifier */ + YYSYMBOL_array_specifier = 522, /* array_specifier */ + YYSYMBOL_type_parameter_specifier_opt = 523, /* type_parameter_specifier_opt */ + YYSYMBOL_type_parameter_specifier = 524, /* type_parameter_specifier */ + YYSYMBOL_type_parameter_specifier_list = 525, /* type_parameter_specifier_list */ + YYSYMBOL_type_specifier_nonarray = 526, /* type_specifier_nonarray */ + YYSYMBOL_precision_qualifier = 527, /* precision_qualifier */ + YYSYMBOL_struct_specifier = 528, /* struct_specifier */ + YYSYMBOL_529_3 = 529, /* $@3 */ + YYSYMBOL_530_4 = 530, /* $@4 */ + YYSYMBOL_struct_declaration_list = 531, /* struct_declaration_list */ + YYSYMBOL_struct_declaration = 532, /* struct_declaration */ + YYSYMBOL_struct_declarator_list = 533, /* struct_declarator_list */ + YYSYMBOL_struct_declarator = 534, /* struct_declarator */ + YYSYMBOL_initializer = 535, /* initializer */ + YYSYMBOL_initializer_list = 536, /* initializer_list */ + YYSYMBOL_declaration_statement = 537, /* declaration_statement */ + YYSYMBOL_statement = 538, /* statement */ + YYSYMBOL_simple_statement = 539, /* simple_statement */ + YYSYMBOL_demote_statement = 540, /* demote_statement */ + YYSYMBOL_compound_statement = 541, /* compound_statement */ + YYSYMBOL_542_5 = 542, /* $@5 */ + YYSYMBOL_543_6 = 543, /* $@6 */ + YYSYMBOL_statement_no_new_scope = 544, /* statement_no_new_scope */ + YYSYMBOL_statement_scoped = 545, /* statement_scoped */ + YYSYMBOL_546_7 = 546, /* $@7 */ + YYSYMBOL_547_8 = 547, /* $@8 */ + YYSYMBOL_compound_statement_no_new_scope = 548, /* compound_statement_no_new_scope */ + YYSYMBOL_statement_list = 549, /* statement_list */ + YYSYMBOL_expression_statement = 550, /* expression_statement */ + YYSYMBOL_selection_statement = 551, /* selection_statement */ + YYSYMBOL_selection_statement_nonattributed = 552, /* selection_statement_nonattributed */ + YYSYMBOL_selection_rest_statement = 553, /* selection_rest_statement */ + YYSYMBOL_condition = 554, /* condition */ + YYSYMBOL_switch_statement = 555, /* switch_statement */ + YYSYMBOL_switch_statement_nonattributed = 556, /* switch_statement_nonattributed */ + YYSYMBOL_557_9 = 557, /* $@9 */ + YYSYMBOL_switch_statement_list = 558, /* switch_statement_list */ + YYSYMBOL_case_label = 559, /* case_label */ + YYSYMBOL_iteration_statement = 560, /* iteration_statement */ + YYSYMBOL_iteration_statement_nonattributed = 561, /* iteration_statement_nonattributed */ + YYSYMBOL_562_10 = 562, /* $@10 */ + YYSYMBOL_563_11 = 563, /* $@11 */ + YYSYMBOL_564_12 = 564, /* $@12 */ + YYSYMBOL_for_init_statement = 565, /* for_init_statement */ + YYSYMBOL_conditionopt = 566, /* conditionopt */ + YYSYMBOL_for_rest_statement = 567, /* for_rest_statement */ + YYSYMBOL_jump_statement = 568, /* jump_statement */ + YYSYMBOL_translation_unit = 569, /* translation_unit */ + YYSYMBOL_external_declaration = 570, /* external_declaration */ + YYSYMBOL_function_definition = 571, /* function_definition */ + YYSYMBOL_572_13 = 572, /* $@13 */ + YYSYMBOL_attribute = 573, /* attribute */ + YYSYMBOL_attribute_list = 574, /* attribute_list */ + YYSYMBOL_single_attribute = 575, /* single_attribute */ + YYSYMBOL_spirv_requirements_list = 576, /* spirv_requirements_list */ + YYSYMBOL_spirv_requirements_parameter = 577, /* spirv_requirements_parameter */ + YYSYMBOL_spirv_extension_list = 578, /* spirv_extension_list */ + YYSYMBOL_spirv_capability_list = 579, /* spirv_capability_list */ + YYSYMBOL_spirv_execution_mode_qualifier = 580, /* spirv_execution_mode_qualifier */ + YYSYMBOL_spirv_execution_mode_parameter_list = 581, /* spirv_execution_mode_parameter_list */ + YYSYMBOL_spirv_execution_mode_parameter = 582, /* spirv_execution_mode_parameter */ + YYSYMBOL_spirv_execution_mode_id_parameter_list = 583, /* spirv_execution_mode_id_parameter_list */ + YYSYMBOL_spirv_storage_class_qualifier = 584, /* spirv_storage_class_qualifier */ + YYSYMBOL_spirv_decorate_qualifier = 585, /* spirv_decorate_qualifier */ + YYSYMBOL_spirv_decorate_parameter_list = 586, /* spirv_decorate_parameter_list */ + YYSYMBOL_spirv_decorate_parameter = 587, /* spirv_decorate_parameter */ + YYSYMBOL_spirv_decorate_id_parameter_list = 588, /* spirv_decorate_id_parameter_list */ + YYSYMBOL_spirv_decorate_id_parameter = 589, /* spirv_decorate_id_parameter */ + YYSYMBOL_spirv_decorate_string_parameter_list = 590, /* spirv_decorate_string_parameter_list */ + YYSYMBOL_spirv_type_specifier = 591, /* spirv_type_specifier */ + YYSYMBOL_spirv_type_parameter_list = 592, /* spirv_type_parameter_list */ + YYSYMBOL_spirv_type_parameter = 593, /* spirv_type_parameter */ + YYSYMBOL_spirv_instruction_qualifier = 594, /* spirv_instruction_qualifier */ + YYSYMBOL_spirv_instruction_qualifier_list = 595, /* spirv_instruction_qualifier_list */ + YYSYMBOL_spirv_instruction_qualifier_id = 596 /* spirv_instruction_qualifier_id */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; /* Second part of user prologue. */ -#line 136 "MachineIndependent/glslang.y" +#line 111 "MachineIndependent/glslang.y" -/* windows only pragma */ -#ifdef _MSC_VER - #pragma warning(disable : 4065) - #pragma warning(disable : 4127) - #pragma warning(disable : 4244) -#endif - #define parseContext (*pParseContext) #define yyerror(context, msg) context->parserError(msg) extern int yylex(YYSTYPE*, TParseContext&); -#line 732 "MachineIndependent/glslang_tab.cpp" +#line 736 "MachineIndependent/glslang_tab.cpp" #ifdef short @@ -768,6 +772,18 @@ typedef int_least16_t yytype_int16; typedef short yytype_int16; #endif +/* Work around bug in HP-UX 11.23, which defines these macros + incorrectly for preprocessor constants. This workaround can likely + be removed in 2023, as HPE has promised support for HP-UX 11.23 + (aka HP-UX 11i v2) only through the end of 2022; see Table 2 of + . */ +#ifdef __hpux +# undef UINT_LEAST8_MAX +# undef UINT_LEAST16_MAX +# define UINT_LEAST8_MAX 255 +# define UINT_LEAST16_MAX 65535 +#endif + #if defined __UINT_LEAST8_MAX__ && __UINT_LEAST8_MAX__ <= __INT_MAX__ typedef __UINT_LEAST8_TYPE__ yytype_uint8; #elif (!defined __UINT_LEAST8_MAX__ && defined YY_STDINT_H \ @@ -865,17 +881,23 @@ typedef int yy_state_fast_t; /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ -# define YYUSE(E) ((void) (E)) +# define YY_USE(E) ((void) (E)) #else -# define YYUSE(E) /* empty */ +# define YY_USE(E) /* empty */ #endif -#if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ /* Suppress an incorrect diagnostic about yylval being uninitialized. */ -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ +#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__ +# if __GNUC__ * 100 + __GNUC_MINOR__ < 407 +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") +# else +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ _Pragma ("GCC diagnostic push") \ _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"") \ _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# endif # define YY_IGNORE_MAYBE_UNINITIALIZED_END \ _Pragma ("GCC diagnostic pop") #else @@ -1032,21 +1054,21 @@ union yyalloc #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 442 +#define YYFINAL 452 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 12452 +#define YYLAST 12701 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 455 +#define YYNTOKENS 465 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 131 +#define YYNNTS 132 /* YYNRULES -- Number of rules. */ -#define YYNRULES 683 +#define YYNRULES 700 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 929 +#define YYNSTATES 946 /* YYMAXUTOK -- Last valid token kind. */ -#define YYMAXUTOK 709 +#define YYMAXUTOK 719 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM @@ -1130,82 +1152,85 @@ static const yytype_int16 yytranslate[] = 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454 + 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, + 455, 456, 457, 458, 459, 460, 461, 462, 463, 464 }; #if YYDEBUG - /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 392, 392, 398, 401, 406, 409, 412, 416, 420, - 423, 427, 431, 435, 439, 443, 447, 453, 461, 464, - 467, 470, 473, 478, 486, 493, 500, 506, 510, 517, - 520, 526, 533, 543, 551, 556, 584, 593, 599, 603, - 607, 627, 628, 629, 630, 636, 637, 642, 647, 656, - 657, 662, 670, 671, 677, 686, 687, 692, 697, 702, - 710, 711, 720, 732, 733, 742, 743, 752, 753, 762, - 763, 771, 772, 780, 781, 789, 790, 790, 808, 809, - 825, 829, 833, 837, 842, 846, 850, 854, 858, 862, - 866, 873, 876, 887, 894, 900, 907, 913, 918, 925, - 929, 933, 937, 942, 947, 956, 956, 967, 971, 978, - 982, 988, 994, 1004, 1007, 1014, 1022, 1042, 1065, 1080, - 1105, 1116, 1126, 1136, 1146, 1155, 1158, 1162, 1166, 1171, - 1179, 1186, 1191, 1196, 1201, 1210, 1220, 1247, 1256, 1263, - 1271, 1278, 1285, 1293, 1303, 1310, 1321, 1327, 1330, 1337, - 1341, 1345, 1354, 1364, 1367, 1378, 1381, 1384, 1388, 1392, - 1397, 1401, 1404, 1409, 1413, 1418, 1427, 1431, 1436, 1442, - 1448, 1455, 1460, 1468, 1474, 1486, 1500, 1506, 1511, 1519, - 1527, 1535, 1543, 1551, 1559, 1567, 1575, 1582, 1589, 1593, - 1598, 1603, 1608, 1613, 1618, 1623, 1627, 1631, 1635, 1639, - 1645, 1656, 1663, 1666, 1675, 1680, 1690, 1695, 1703, 1707, - 1717, 1720, 1726, 1732, 1739, 1749, 1753, 1757, 1761, 1766, - 1770, 1775, 1780, 1785, 1790, 1795, 1800, 1805, 1810, 1815, - 1821, 1827, 1833, 1838, 1843, 1848, 1853, 1858, 1863, 1868, - 1873, 1878, 1883, 1888, 1894, 1901, 1906, 1911, 1916, 1921, - 1926, 1931, 1936, 1941, 1946, 1951, 1956, 1964, 1972, 1980, - 1986, 1992, 1998, 2004, 2010, 2016, 2022, 2028, 2034, 2040, - 2046, 2052, 2058, 2064, 2070, 2076, 2082, 2088, 2094, 2100, - 2106, 2112, 2118, 2124, 2130, 2136, 2142, 2148, 2154, 2160, - 2166, 2172, 2178, 2186, 2194, 2202, 2210, 2218, 2226, 2234, - 2242, 2250, 2258, 2266, 2274, 2280, 2286, 2292, 2298, 2304, - 2310, 2316, 2322, 2328, 2334, 2340, 2346, 2352, 2358, 2364, - 2370, 2376, 2382, 2388, 2394, 2400, 2406, 2412, 2418, 2424, - 2430, 2436, 2442, 2448, 2454, 2460, 2466, 2472, 2478, 2484, - 2490, 2494, 2498, 2502, 2507, 2513, 2518, 2523, 2528, 2533, - 2538, 2543, 2549, 2554, 2559, 2564, 2569, 2574, 2580, 2586, - 2592, 2598, 2604, 2610, 2616, 2622, 2628, 2634, 2640, 2646, - 2652, 2658, 2663, 2668, 2673, 2678, 2683, 2688, 2694, 2699, - 2704, 2709, 2714, 2719, 2724, 2729, 2735, 2740, 2745, 2750, - 2755, 2760, 2765, 2770, 2775, 2780, 2785, 2790, 2795, 2800, - 2805, 2811, 2816, 2821, 2827, 2833, 2838, 2843, 2848, 2854, - 2859, 2864, 2869, 2875, 2880, 2885, 2890, 2896, 2901, 2906, - 2911, 2917, 2923, 2929, 2935, 2940, 2946, 2952, 2958, 2963, - 2968, 2973, 2978, 2983, 2989, 2994, 2999, 3004, 3010, 3015, - 3020, 3025, 3031, 3036, 3041, 3046, 3052, 3057, 3062, 3067, - 3073, 3078, 3083, 3088, 3094, 3099, 3104, 3109, 3115, 3120, - 3125, 3130, 3136, 3141, 3146, 3151, 3157, 3162, 3167, 3172, - 3178, 3183, 3188, 3193, 3199, 3204, 3209, 3214, 3220, 3225, - 3230, 3235, 3241, 3246, 3251, 3256, 3262, 3267, 3272, 3277, - 3283, 3288, 3293, 3298, 3303, 3308, 3313, 3318, 3323, 3328, - 3333, 3338, 3343, 3348, 3353, 3358, 3363, 3368, 3373, 3378, - 3383, 3388, 3393, 3398, 3403, 3409, 3415, 3421, 3427, 3434, - 3441, 3447, 3453, 3459, 3465, 3471, 3477, 3483, 3488, 3493, - 3509, 3514, 3519, 3527, 3527, 3538, 3538, 3548, 3551, 3564, - 3586, 3613, 3617, 3623, 3628, 3639, 3643, 3649, 3655, 3666, - 3669, 3676, 3680, 3681, 3687, 3688, 3689, 3690, 3691, 3692, - 3693, 3695, 3701, 3710, 3711, 3715, 3711, 3727, 3728, 3732, - 3732, 3739, 3739, 3753, 3756, 3764, 3772, 3783, 3784, 3788, - 3792, 3800, 3807, 3811, 3819, 3823, 3836, 3840, 3848, 3848, - 3868, 3871, 3877, 3889, 3901, 3905, 3913, 3913, 3928, 3928, - 3946, 3946, 3967, 3970, 3976, 3979, 3985, 3989, 3996, 4001, - 4006, 4013, 4016, 4020, 4025, 4029, 4039, 4043, 4052, 4055, - 4059, 4068, 4068, 4110, 4115, 4118, 4123, 4126, 4133, 4136, - 4141, 4144, 4149, 4152, 4157, 4160, 4165, 4169, 4174, 4178, - 4183, 4187, 4194, 4197, 4202, 4205, 4208, 4211, 4214, 4219, - 4228, 4239, 4244, 4252, 4256, 4261, 4265, 4270, 4274, 4279, - 4283, 4290, 4293, 4298, 4301, 4304, 4307, 4312, 4320, 4330, - 4334, 4339, 4343, 4348, 4352, 4359, 4362, 4367, 4372, 4375, - 4381, 4384, 4389, 4392 + 0, 355, 355, 361, 364, 369, 372, 375, 379, 382, + 385, 389, 393, 397, 401, 405, 409, 415, 422, 425, + 428, 431, 434, 439, 447, 454, 461, 467, 471, 478, + 481, 487, 505, 527, 535, 540, 567, 575, 581, 585, + 589, 609, 610, 611, 612, 618, 619, 624, 629, 638, + 639, 644, 652, 653, 659, 668, 669, 674, 679, 684, + 692, 693, 702, 714, 715, 724, 725, 734, 735, 744, + 745, 753, 754, 762, 763, 771, 772, 772, 790, 791, + 807, 811, 815, 819, 824, 828, 832, 836, 840, 844, + 848, 855, 858, 869, 876, 881, 888, 893, 898, 905, + 909, 913, 917, 922, 927, 936, 936, 947, 951, 958, + 963, 969, 975, 985, 988, 995, 1008, 1031, 1054, 1069, + 1094, 1105, 1115, 1125, 1135, 1144, 1147, 1151, 1155, 1160, + 1168, 1173, 1178, 1183, 1188, 1197, 1207, 1234, 1243, 1250, + 1257, 1264, 1271, 1279, 1287, 1297, 1307, 1314, 1324, 1330, + 1333, 1340, 1344, 1348, 1356, 1365, 1368, 1379, 1382, 1385, + 1389, 1393, 1397, 1401, 1404, 1409, 1413, 1418, 1426, 1430, + 1435, 1441, 1447, 1454, 1459, 1464, 1472, 1477, 1489, 1503, + 1509, 1514, 1522, 1530, 1538, 1546, 1554, 1562, 1570, 1578, + 1586, 1593, 1600, 1604, 1609, 1614, 1619, 1624, 1629, 1634, + 1638, 1642, 1646, 1650, 1656, 1662, 1672, 1679, 1682, 1690, + 1697, 1708, 1713, 1721, 1725, 1735, 1738, 1744, 1750, 1755, + 1763, 1773, 1777, 1781, 1785, 1790, 1794, 1799, 1804, 1809, + 1814, 1819, 1824, 1829, 1834, 1839, 1845, 1851, 1857, 1862, + 1867, 1872, 1877, 1882, 1887, 1892, 1897, 1902, 1907, 1912, + 1917, 1924, 1929, 1934, 1939, 1944, 1949, 1954, 1959, 1964, + 1969, 1974, 1979, 1987, 1995, 2003, 2009, 2015, 2021, 2027, + 2033, 2039, 2045, 2051, 2057, 2063, 2069, 2075, 2081, 2087, + 2093, 2099, 2105, 2111, 2117, 2123, 2129, 2135, 2141, 2147, + 2153, 2159, 2165, 2171, 2177, 2183, 2189, 2195, 2201, 2209, + 2217, 2225, 2233, 2241, 2249, 2257, 2265, 2273, 2281, 2289, + 2297, 2303, 2309, 2315, 2321, 2327, 2333, 2339, 2345, 2351, + 2357, 2363, 2369, 2375, 2381, 2387, 2393, 2399, 2405, 2411, + 2417, 2423, 2429, 2435, 2441, 2447, 2453, 2459, 2465, 2471, + 2477, 2483, 2489, 2495, 2501, 2507, 2513, 2517, 2521, 2525, + 2530, 2535, 2540, 2545, 2550, 2555, 2560, 2565, 2570, 2575, + 2580, 2585, 2590, 2595, 2601, 2607, 2613, 2619, 2625, 2631, + 2637, 2643, 2649, 2655, 2661, 2667, 2673, 2678, 2683, 2688, + 2693, 2698, 2703, 2708, 2713, 2718, 2723, 2728, 2733, 2738, + 2743, 2748, 2753, 2758, 2763, 2768, 2773, 2778, 2783, 2788, + 2793, 2798, 2803, 2808, 2813, 2818, 2823, 2828, 2833, 2838, + 2844, 2850, 2855, 2860, 2865, 2871, 2876, 2881, 2886, 2892, + 2897, 2902, 2907, 2913, 2918, 2923, 2928, 2934, 2940, 2946, + 2952, 2957, 2963, 2969, 2975, 2980, 2985, 2990, 2995, 3000, + 3006, 3011, 3016, 3021, 3027, 3032, 3037, 3042, 3048, 3053, + 3058, 3063, 3069, 3074, 3079, 3084, 3090, 3095, 3100, 3105, + 3111, 3116, 3121, 3126, 3132, 3137, 3142, 3147, 3153, 3158, + 3163, 3168, 3174, 3179, 3184, 3189, 3195, 3200, 3205, 3210, + 3216, 3221, 3226, 3231, 3237, 3242, 3247, 3252, 3258, 3263, + 3268, 3273, 3279, 3284, 3289, 3294, 3300, 3305, 3310, 3315, + 3320, 3325, 3330, 3335, 3340, 3345, 3350, 3355, 3360, 3365, + 3370, 3375, 3380, 3385, 3390, 3395, 3400, 3405, 3410, 3415, + 3420, 3426, 3432, 3438, 3444, 3450, 3456, 3462, 3469, 3476, + 3482, 3488, 3494, 3500, 3507, 3514, 3521, 3528, 3532, 3536, + 3541, 3557, 3562, 3567, 3575, 3575, 3592, 3592, 3602, 3605, + 3618, 3640, 3667, 3671, 3677, 3682, 3693, 3696, 3702, 3708, + 3717, 3720, 3726, 3730, 3731, 3737, 3738, 3739, 3740, 3741, + 3742, 3743, 3744, 3748, 3756, 3757, 3761, 3757, 3773, 3774, + 3778, 3778, 3785, 3785, 3799, 3802, 3810, 3818, 3829, 3830, + 3834, 3837, 3844, 3851, 3855, 3863, 3867, 3880, 3883, 3890, + 3890, 3910, 3913, 3919, 3931, 3943, 3946, 3953, 3953, 3968, + 3968, 3986, 3986, 4007, 4010, 4016, 4019, 4025, 4029, 4036, + 4041, 4046, 4053, 4056, 4060, 4064, 4068, 4077, 4081, 4090, + 4093, 4096, 4104, 4104, 4146, 4151, 4154, 4159, 4162, 4167, + 4170, 4175, 4178, 4183, 4186, 4191, 4194, 4199, 4203, 4208, + 4212, 4217, 4221, 4228, 4231, 4236, 4239, 4242, 4245, 4248, + 4253, 4262, 4273, 4278, 4286, 4290, 4295, 4299, 4304, 4308, + 4313, 4317, 4324, 4327, 4332, 4335, 4338, 4341, 4346, 4349, + 4354, 4360, 4363, 4366, 4369, 4374, 4378, 4383, 4387, 4392, + 4396, 4403, 4406, 4411, 4414, 4419, 4422, 4428, 4431, 4436, + 4439 }; #endif @@ -1250,16 +1275,17 @@ static const char *const yytname[] = "F32MAT4X2", "F32MAT4X3", "F32MAT4X4", "F64MAT2X2", "F64MAT2X3", "F64MAT2X4", "F64MAT3X2", "F64MAT3X3", "F64MAT3X4", "F64MAT4X2", "F64MAT4X3", "F64MAT4X4", "ATOMIC_UINT", "ACCSTRUCTNV", "ACCSTRUCTEXT", - "RAYQUERYEXT", "FCOOPMATNV", "ICOOPMATNV", "UCOOPMATNV", - "SAMPLERCUBEARRAY", "SAMPLERCUBEARRAYSHADOW", "ISAMPLERCUBEARRAY", - "USAMPLERCUBEARRAY", "SAMPLER1D", "SAMPLER1DARRAY", - "SAMPLER1DARRAYSHADOW", "ISAMPLER1D", "SAMPLER1DSHADOW", "SAMPLER2DRECT", - "SAMPLER2DRECTSHADOW", "ISAMPLER2DRECT", "USAMPLER2DRECT", - "SAMPLERBUFFER", "ISAMPLERBUFFER", "USAMPLERBUFFER", "SAMPLER2DMS", - "ISAMPLER2DMS", "USAMPLER2DMS", "SAMPLER2DMSARRAY", "ISAMPLER2DMSARRAY", - "USAMPLER2DMSARRAY", "SAMPLEREXTERNALOES", "SAMPLEREXTERNAL2DY2YEXT", - "ISAMPLER1DARRAY", "USAMPLER1D", "USAMPLER1DARRAY", "F16SAMPLER1D", - "F16SAMPLER2D", "F16SAMPLER3D", "F16SAMPLER2DRECT", "F16SAMPLERCUBE", + "RAYQUERYEXT", "FCOOPMATNV", "ICOOPMATNV", "UCOOPMATNV", "COOPMAT", + "HITOBJECTNV", "HITOBJECTATTRNV", "SAMPLERCUBEARRAY", + "SAMPLERCUBEARRAYSHADOW", "ISAMPLERCUBEARRAY", "USAMPLERCUBEARRAY", + "SAMPLER1D", "SAMPLER1DARRAY", "SAMPLER1DARRAYSHADOW", "ISAMPLER1D", + "SAMPLER1DSHADOW", "SAMPLER2DRECT", "SAMPLER2DRECTSHADOW", + "ISAMPLER2DRECT", "USAMPLER2DRECT", "SAMPLERBUFFER", "ISAMPLERBUFFER", + "USAMPLERBUFFER", "SAMPLER2DMS", "ISAMPLER2DMS", "USAMPLER2DMS", + "SAMPLER2DMSARRAY", "ISAMPLER2DMSARRAY", "USAMPLER2DMSARRAY", + "SAMPLEREXTERNALOES", "SAMPLEREXTERNAL2DY2YEXT", "ISAMPLER1DARRAY", + "USAMPLER1D", "USAMPLER1DARRAY", "F16SAMPLER1D", "F16SAMPLER2D", + "F16SAMPLER3D", "F16SAMPLER2DRECT", "F16SAMPLERCUBE", "F16SAMPLER1DARRAY", "F16SAMPLER2DARRAY", "F16SAMPLERCUBEARRAY", "F16SAMPLERBUFFER", "F16SAMPLER2DMS", "F16SAMPLER2DMSARRAY", "F16SAMPLER1DSHADOW", "F16SAMPLER2DSHADOW", "F16SAMPLER1DARRAYSHADOW", @@ -1295,32 +1321,34 @@ static const char *const yytname[] = "F16SUBPASSINPUTMS", "SPIRV_INSTRUCTION", "SPIRV_EXECUTION_MODE", "SPIRV_EXECUTION_MODE_ID", "SPIRV_DECORATE", "SPIRV_DECORATE_ID", "SPIRV_DECORATE_STRING", "SPIRV_TYPE", "SPIRV_STORAGE_CLASS", - "SPIRV_BY_REFERENCE", "SPIRV_LITERAL", "LEFT_OP", "RIGHT_OP", "INC_OP", - "DEC_OP", "LE_OP", "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", - "XOR_OP", "MUL_ASSIGN", "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", - "LEFT_ASSIGN", "RIGHT_ASSIGN", "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", - "SUB_ASSIGN", "STRING_LITERAL", "LEFT_PAREN", "RIGHT_PAREN", - "LEFT_BRACKET", "RIGHT_BRACKET", "LEFT_BRACE", "RIGHT_BRACE", "DOT", - "COMMA", "COLON", "EQUAL", "SEMICOLON", "BANG", "DASH", "TILDE", "PLUS", - "STAR", "SLASH", "PERCENT", "LEFT_ANGLE", "RIGHT_ANGLE", "VERTICAL_BAR", - "CARET", "AMPERSAND", "QUESTION", "INVARIANT", "HIGH_PRECISION", - "MEDIUM_PRECISION", "LOW_PRECISION", "PRECISION", "PACKED", "RESOURCE", - "SUPERP", "FLOATCONSTANT", "INTCONSTANT", "UINTCONSTANT", "BOOLCONSTANT", + "SPIRV_BY_REFERENCE", "SPIRV_LITERAL", "ATTACHMENTEXT", "IATTACHMENTEXT", + "UATTACHMENTEXT", "LEFT_OP", "RIGHT_OP", "INC_OP", "DEC_OP", "LE_OP", + "GE_OP", "EQ_OP", "NE_OP", "AND_OP", "OR_OP", "XOR_OP", "MUL_ASSIGN", + "DIV_ASSIGN", "ADD_ASSIGN", "MOD_ASSIGN", "LEFT_ASSIGN", "RIGHT_ASSIGN", + "AND_ASSIGN", "XOR_ASSIGN", "OR_ASSIGN", "SUB_ASSIGN", "STRING_LITERAL", + "LEFT_PAREN", "RIGHT_PAREN", "LEFT_BRACKET", "RIGHT_BRACKET", + "LEFT_BRACE", "RIGHT_BRACE", "DOT", "COMMA", "COLON", "EQUAL", + "SEMICOLON", "BANG", "DASH", "TILDE", "PLUS", "STAR", "SLASH", "PERCENT", + "LEFT_ANGLE", "RIGHT_ANGLE", "VERTICAL_BAR", "CARET", "AMPERSAND", + "QUESTION", "INVARIANT", "HIGH_PRECISION", "MEDIUM_PRECISION", + "LOW_PRECISION", "PRECISION", "PACKED", "RESOURCE", "SUPERP", + "FLOATCONSTANT", "INTCONSTANT", "UINTCONSTANT", "BOOLCONSTANT", "IDENTIFIER", "TYPE_NAME", "CENTROID", "IN", "OUT", "INOUT", "STRUCT", "VOID", "WHILE", "BREAK", "CONTINUE", "DO", "ELSE", "FOR", "IF", "DISCARD", "RETURN", "SWITCH", "CASE", "DEFAULT", "TERMINATE_INVOCATION", "TERMINATE_RAY", "IGNORE_INTERSECTION", "UNIFORM", "SHARED", "BUFFER", - "FLAT", "SMOOTH", "LAYOUT", "DOUBLECONSTANT", "INT16CONSTANT", - "UINT16CONSTANT", "FLOAT16CONSTANT", "INT32CONSTANT", "UINT32CONSTANT", - "INT64CONSTANT", "UINT64CONSTANT", "SUBROUTINE", "DEMOTE", "PAYLOADNV", - "PAYLOADINNV", "HITATTRNV", "CALLDATANV", "CALLDATAINNV", "PAYLOADEXT", - "PAYLOADINEXT", "HITATTREXT", "CALLDATAEXT", "CALLDATAINEXT", "PATCH", - "SAMPLE", "NONUNIFORM", "COHERENT", "VOLATILE", "RESTRICT", "READONLY", - "WRITEONLY", "DEVICECOHERENT", "QUEUEFAMILYCOHERENT", - "WORKGROUPCOHERENT", "SUBGROUPCOHERENT", "NONPRIVATE", - "SHADERCALLCOHERENT", "NOPERSPECTIVE", "EXPLICITINTERPAMD", - "PERVERTEXNV", "PERPRIMITIVENV", "PERVIEWNV", "PERTASKNV", "PRECISE", - "$accept", "variable_identifier", "primary_expression", + "TILEIMAGEEXT", "FLAT", "SMOOTH", "LAYOUT", "DOUBLECONSTANT", + "INT16CONSTANT", "UINT16CONSTANT", "FLOAT16CONSTANT", "INT32CONSTANT", + "UINT32CONSTANT", "INT64CONSTANT", "UINT64CONSTANT", "SUBROUTINE", + "DEMOTE", "PAYLOADNV", "PAYLOADINNV", "HITATTRNV", "CALLDATANV", + "CALLDATAINNV", "PAYLOADEXT", "PAYLOADINEXT", "HITATTREXT", + "CALLDATAEXT", "CALLDATAINEXT", "PATCH", "SAMPLE", "NONUNIFORM", + "COHERENT", "VOLATILE", "RESTRICT", "READONLY", "WRITEONLY", + "DEVICECOHERENT", "QUEUEFAMILYCOHERENT", "WORKGROUPCOHERENT", + "SUBGROUPCOHERENT", "NONPRIVATE", "SHADERCALLCOHERENT", "NOPERSPECTIVE", + "EXPLICITINTERPAMD", "PERVERTEXEXT", "PERVERTEXNV", "PERPRIMITIVENV", + "PERVIEWNV", "PERTASKNV", "PERPRIMITIVEEXT", "TASKPAYLOADWORKGROUPEXT", + "PRECISE", "$accept", "variable_identifier", "primary_expression", "postfix_expression", "integer_expression", "function_call", "function_call_or_method", "function_call_generic", "function_call_header_no_parameters", @@ -1365,7 +1393,7 @@ static const char *const yytname[] = "spirv_execution_mode_id_parameter_list", "spirv_storage_class_qualifier", "spirv_decorate_qualifier", "spirv_decorate_parameter_list", "spirv_decorate_parameter", - "spirv_decorate_id_parameter_list", + "spirv_decorate_id_parameter_list", "spirv_decorate_id_parameter", "spirv_decorate_string_parameter_list", "spirv_type_specifier", "spirv_type_parameter_list", "spirv_type_parameter", "spirv_instruction_qualifier", "spirv_instruction_qualifier_list", @@ -1379,406 +1407,358 @@ yysymbol_name (yysymbol_kind_t yysymbol) } #endif -#ifdef YYPRINT -/* YYTOKNUM[NUM] -- (External) token number corresponding to the - (internal) symbol number NUM (which must be that of a token). */ -static const yytype_int16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, - 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, - 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, - 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, - 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, - 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, - 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, - 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, - 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, - 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, - 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, - 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, - 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, - 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, - 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, - 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, - 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, - 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, - 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, - 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, - 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, - 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, - 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, - 705, 706, 707, 708, 709 -}; -#endif - -#define YYPACT_NINF (-859) +#define YYPACT_NINF (-872) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) -#define YYTABLE_NINF (-570) +#define YYTABLE_NINF (-695) #define yytable_value_is_error(Yyn) \ 0 - /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ static const yytype_int16 yypact[] = { - 4548, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -312, -274, -244, -212, -208, - -201, -181, -169, -859, -859, -194, -859, -859, -859, -859, - -859, -285, -859, -859, -859, -859, -859, -317, -859, -859, - -859, -859, -859, -859, -132, -73, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -329, -70, - -158, -145, 7712, -221, -859, -164, -859, -859, -859, -859, - 5452, -859, -859, -859, -859, -68, -859, -859, 932, -859, - -859, 7712, -55, -859, -859, -859, 5904, -80, -154, -150, - -142, -135, -130, -80, -129, -79, 12060, -859, -45, -354, - -76, -859, -308, -859, -43, -40, 7712, -859, -859, -859, - 7712, -72, -71, -859, -265, -859, -257, -859, -859, 10761, - -39, -859, -859, -859, -35, -69, 7712, -859, -42, -38, - -37, -859, -302, -859, -235, -32, -33, -28, -27, -217, - -26, -23, -22, -21, -20, -16, -216, -29, -15, -31, - -303, -859, -13, 7712, -859, -14, -859, -214, -859, -859, - -205, 9029, -859, -279, 1384, -859, -859, -859, -859, -859, - -39, -299, -859, 9462, -275, -859, -34, -859, -137, 10761, - 10761, -859, 10761, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -248, -859, -859, -859, -3, -203, 11194, -1, - -859, 10761, -859, -859, -310, 3, -40, 1, -859, -309, - -80, -859, -30, -859, -319, 5, -128, 10761, -124, -859, - -157, -122, 10761, -120, 10, -118, -80, -859, 11627, -859, - -116, 10761, 7, -79, -859, 7712, -25, 6356, -859, 7712, - 10761, -859, -354, -859, -19, -859, -859, -78, -263, -94, - -298, -52, -18, -8, -12, 29, 28, -301, 15, 9895, - -859, 16, -859, -859, 19, 12, 17, -859, 20, 23, - 18, 10328, 24, 10761, 21, 22, 25, 27, 30, -215, - -859, -859, -117, -859, -70, 26, 34, -859, -859, -859, - -859, -859, 1836, -859, -859, -859, -859, -859, -859, -859, - -859, -859, 5000, 3, 9462, -264, 8163, -859, -859, 9462, - 7712, -859, -11, -859, -859, -859, -195, -859, -859, 10761, - -6, -859, -859, 10761, 37, -859, -859, -859, 10761, -859, - -859, -859, -322, -859, -859, -192, 35, -859, -859, -859, - -859, -859, -859, -179, -859, -178, -859, -859, -177, 32, - -859, -859, -859, -859, -175, -859, -174, -859, -167, 36, - -859, -166, 38, -165, 35, -859, -163, -859, 45, 46, - -859, -859, -25, -39, -115, -859, -859, -859, 6808, -859, - -859, -859, 10761, 10761, 10761, 10761, 10761, 10761, 10761, 10761, - 10761, 10761, 10761, 10761, 10761, 10761, 10761, 10761, 10761, 10761, - 10761, -859, -859, -859, 51, -859, 2288, -859, -859, -859, - 2288, -859, 10761, -859, -859, -88, 10761, -63, -859, -859, - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, 10761, 10761, -859, -859, -859, -859, - -859, -859, -859, 9462, -859, -859, -108, -859, 7260, -859, - -859, 52, 53, -859, -859, -859, -859, -859, -138, -136, - -859, -304, -859, -319, -859, -319, -859, 10761, 10761, -859, - -157, -859, -157, -859, 10761, 10761, -859, 65, 10, -859, - 11627, -859, 10761, -859, -859, -86, 3, -25, -859, -859, - -859, -859, -859, -78, -78, -263, -263, -94, -94, -94, - -94, -298, -298, -52, -18, -8, -12, 29, 28, 10761, - -859, 2288, 4096, 31, 3644, -156, -859, -155, -859, -859, - -859, -859, -859, 8596, -859, -859, -859, 66, -859, 39, - -859, -153, -859, -151, -859, -148, -859, -146, -859, -144, - -143, -859, -859, -859, -61, 64, 53, 40, 72, 74, - -859, -859, 4096, 75, -859, -859, -859, -859, -859, -859, - -859, -859, -859, -859, -859, 10761, -859, 71, 2740, 10761, - -859, 73, 81, 41, 80, 3192, -859, 83, -859, 9462, - -859, -859, -859, -141, 10761, 2740, 75, -859, -859, 2288, - -859, 78, 53, -859, -859, 2288, 86, -859, -859 + 4648, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -305, -301, + -289, -276, -246, -238, -227, -182, -872, -872, -872, -872, + -872, -168, -872, -872, -872, -872, -872, -55, -872, -872, + -872, -872, -872, -319, -872, -872, -872, -872, -872, -872, + -872, -135, -120, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -327, -114, + -81, -124, 7882, -313, -872, -101, -872, -872, -872, -872, + 5572, -872, -872, -872, -872, -94, -872, -872, 952, -872, + -872, 7882, -73, -872, -872, -872, 6034, -78, -252, -250, + -216, -197, -136, -78, -127, -49, 12303, -872, -13, -346, + -39, -872, -309, -872, -10, -9, 7882, -872, -872, -872, + 7882, -38, -37, -872, -267, -872, -236, -872, -872, 10983, + -2, -872, -872, -872, 3, -35, 7882, -872, -8, -6, + -1, -872, -256, -872, -255, -4, 4, 7, 8, -237, + 10, 11, 13, 14, 15, 18, -232, 9, 19, 27, + -188, -872, -3, 7882, -872, 20, -872, -229, -872, -872, + -219, 9223, -872, -272, 1414, -872, -872, -872, -872, -872, + -2, -277, -872, 9663, -265, -872, -23, -872, -112, 10983, + 10983, -872, 10983, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -253, -872, -872, -872, 29, -204, 11423, 28, + -872, 10983, -872, 31, -321, 17, -9, 32, -872, -325, + -78, -872, 5, -872, -330, 33, -125, 10983, -123, -872, + -130, -119, -146, -118, 34, -103, -78, -872, 11863, -872, + -74, 10983, 36, -49, -872, 7882, 24, 6496, -872, 7882, + 10983, -872, -346, -872, 30, -872, -872, -33, -133, -105, + -303, -11, -14, 21, 23, 48, 52, -316, 41, -872, + 10103, -872, 42, -872, -872, 46, 38, 40, -872, 64, + 67, 60, 10543, 74, 10983, 68, 65, 69, 70, 73, + -167, -872, -872, -47, -872, -114, 77, 31, -872, -872, + -872, -872, -872, 1876, -872, -872, -872, -872, -872, -872, + -872, -872, -872, 5110, 17, 9663, -261, 8343, -872, -872, + 9663, 7882, -872, 50, -872, -872, -872, -203, -872, -872, + 10983, 51, -872, -872, 10983, 87, -872, -872, -872, 10983, + -872, -872, -872, -312, -872, -872, -200, 80, -872, -872, + -872, -872, -872, -872, -199, -872, -196, -872, -872, -195, + 71, -872, -872, -872, -872, -169, -872, -164, -872, -872, + -872, -872, -872, -161, -872, 83, -872, -160, 84, -153, + 80, -872, -278, -152, -872, 91, 94, -872, -872, 24, + -2, -43, -872, -872, -872, 6958, -872, -872, -872, 10983, + 10983, 10983, 10983, 10983, 10983, 10983, 10983, 10983, 10983, 10983, + 10983, 10983, 10983, 10983, 10983, 10983, 10983, 10983, -872, -872, + -872, 93, -872, 2338, -872, -872, -872, 2338, -872, 10983, + -872, -872, -42, 10983, -32, -872, -872, -872, -872, -872, + -872, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, 10983, 10983, -872, -872, -872, -872, -872, -872, -872, + 9663, -872, -872, -76, -872, 7420, -872, -872, 96, 95, + -872, -872, -872, -872, -872, -132, -131, -872, -311, -872, + -330, -872, -330, -872, 10983, 10983, -872, -130, -872, -130, + -872, -146, -146, -872, 101, 34, -872, 11863, -872, 10983, + -872, -872, -41, 17, 24, -872, -872, -872, -872, -872, + -33, -33, -133, -133, -105, -105, -105, -105, -303, -303, + -11, -14, 21, 23, 48, 52, 10983, -872, 2338, 4186, + 59, 3724, -151, -872, -150, -872, -872, -872, -872, -872, + 8783, -872, -872, -872, 105, -872, 72, -872, -149, -872, + -148, -872, -141, -872, -140, -872, -139, -138, -872, -872, + -872, -28, 102, 95, 75, 107, 106, -872, -872, 4186, + 108, -872, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, 10983, -872, 100, 2800, 10983, -872, 104, 109, + 76, 112, 3262, -872, 113, -872, 9663, -872, -872, -872, + -137, 10983, 2800, 108, -872, -872, 2338, -872, 110, 95, + -872, -872, 2338, 114, -872, -872 }; - /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE does not specify something else to do. Zero - means the default is an error. */ +/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ static const yytype_int16 yydefact[] = { - 0, 166, 219, 217, 218, 216, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 220, 221, 222, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 345, 346, 347, 348, 349, 350, 351, 371, 372, 373, - 374, 375, 376, 377, 386, 399, 400, 387, 388, 390, - 389, 391, 392, 393, 394, 395, 396, 397, 398, 174, - 175, 245, 246, 244, 247, 254, 255, 252, 253, 250, - 251, 248, 249, 277, 278, 279, 289, 290, 291, 274, - 275, 276, 286, 287, 288, 271, 272, 273, 283, 284, - 285, 268, 269, 270, 280, 281, 282, 256, 257, 258, - 292, 293, 294, 259, 260, 261, 304, 305, 306, 262, - 263, 264, 316, 317, 318, 265, 266, 267, 328, 329, - 330, 295, 296, 297, 298, 299, 300, 301, 302, 303, - 307, 308, 309, 310, 311, 312, 313, 314, 315, 319, - 320, 321, 322, 323, 324, 325, 326, 327, 331, 332, - 333, 334, 335, 336, 337, 338, 339, 343, 340, 341, - 342, 524, 525, 526, 355, 356, 379, 382, 344, 353, - 354, 370, 352, 401, 402, 405, 406, 407, 409, 410, - 411, 413, 414, 415, 417, 418, 514, 515, 378, 380, - 381, 357, 358, 359, 403, 360, 364, 365, 368, 408, - 412, 416, 361, 362, 366, 367, 404, 363, 369, 448, - 450, 451, 452, 454, 455, 456, 458, 459, 460, 462, - 463, 464, 466, 467, 468, 470, 471, 472, 474, 475, - 476, 478, 479, 480, 482, 483, 484, 486, 487, 488, - 490, 491, 449, 453, 457, 461, 465, 473, 477, 481, - 469, 485, 489, 492, 493, 494, 495, 496, 497, 498, - 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, - 509, 510, 511, 512, 513, 383, 384, 385, 419, 428, - 430, 424, 429, 431, 432, 434, 435, 436, 438, 439, - 440, 442, 443, 444, 446, 447, 420, 421, 422, 433, - 423, 425, 426, 427, 437, 441, 445, 516, 517, 520, - 521, 522, 523, 518, 519, 0, 0, 0, 0, 0, - 0, 0, 0, 164, 165, 0, 620, 137, 530, 531, - 532, 0, 529, 170, 168, 169, 167, 0, 215, 171, - 172, 173, 139, 138, 0, 199, 180, 182, 178, 184, - 186, 181, 183, 179, 185, 187, 176, 177, 201, 188, - 195, 196, 197, 198, 189, 190, 191, 192, 193, 194, - 140, 141, 142, 143, 144, 145, 152, 619, 0, 621, - 0, 114, 113, 0, 125, 130, 159, 158, 156, 160, - 0, 153, 155, 161, 135, 211, 157, 528, 0, 616, - 618, 0, 0, 162, 163, 527, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 535, 0, 0, + 0, 168, 225, 223, 224, 222, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 226, 227, 228, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 351, 352, 353, 354, 355, 356, 357, 377, 378, 379, + 380, 381, 382, 383, 392, 405, 406, 393, 394, 396, + 395, 397, 398, 399, 400, 401, 402, 403, 404, 177, + 178, 251, 252, 250, 253, 260, 261, 258, 259, 256, + 257, 254, 255, 283, 284, 285, 295, 296, 297, 280, + 281, 282, 292, 293, 294, 277, 278, 279, 289, 290, + 291, 274, 275, 276, 286, 287, 288, 262, 263, 264, + 298, 299, 300, 265, 266, 267, 310, 311, 312, 268, + 269, 270, 322, 323, 324, 271, 272, 273, 334, 335, + 336, 301, 302, 303, 304, 305, 306, 307, 308, 309, + 313, 314, 315, 316, 317, 318, 319, 320, 321, 325, + 326, 327, 328, 329, 330, 331, 332, 333, 337, 338, + 339, 340, 341, 342, 343, 344, 345, 349, 346, 347, + 348, 533, 534, 535, 536, 538, 182, 361, 362, 385, + 388, 350, 359, 360, 376, 358, 407, 408, 411, 412, + 413, 415, 416, 417, 419, 420, 421, 423, 424, 520, + 521, 384, 386, 387, 363, 364, 365, 409, 366, 370, + 371, 374, 414, 418, 422, 367, 368, 372, 373, 410, + 369, 375, 454, 456, 457, 458, 460, 461, 462, 464, + 465, 466, 468, 469, 470, 472, 473, 474, 476, 477, + 478, 480, 481, 482, 484, 485, 486, 488, 489, 490, + 492, 493, 494, 496, 497, 455, 459, 463, 467, 471, + 479, 483, 487, 475, 491, 495, 498, 499, 500, 501, + 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, + 512, 513, 514, 515, 516, 517, 518, 519, 389, 390, + 391, 425, 434, 436, 430, 435, 437, 438, 440, 441, + 442, 444, 445, 446, 448, 449, 450, 452, 453, 426, + 427, 428, 439, 429, 431, 432, 433, 443, 447, 451, + 525, 526, 529, 530, 531, 532, 527, 528, 0, 0, + 0, 0, 0, 0, 0, 0, 166, 167, 522, 523, + 524, 0, 631, 137, 541, 542, 543, 0, 540, 172, + 170, 171, 169, 0, 221, 173, 175, 176, 174, 139, + 138, 0, 203, 184, 186, 181, 188, 190, 185, 187, + 183, 189, 191, 179, 180, 206, 192, 199, 200, 201, + 202, 193, 194, 195, 196, 197, 198, 140, 141, 143, + 142, 144, 146, 147, 145, 205, 154, 630, 0, 632, + 0, 114, 113, 0, 125, 130, 161, 160, 158, 162, + 0, 155, 157, 163, 135, 216, 159, 539, 0, 627, + 629, 0, 0, 164, 165, 537, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 546, 0, 0, 0, 99, 0, 94, 0, 109, 0, 121, 115, 123, - 0, 124, 0, 97, 131, 102, 0, 154, 136, 0, - 204, 210, 1, 617, 0, 0, 0, 96, 0, 0, - 0, 628, 0, 680, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 626, - 0, 624, 0, 0, 533, 149, 151, 0, 147, 202, - 0, 0, 100, 0, 0, 622, 110, 116, 120, 122, + 0, 124, 0, 97, 131, 102, 0, 156, 136, 0, + 209, 215, 1, 628, 0, 0, 0, 96, 0, 0, + 0, 639, 0, 697, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 637, + 0, 635, 0, 0, 544, 151, 153, 0, 149, 207, + 0, 0, 100, 0, 0, 633, 110, 116, 120, 122, 118, 126, 117, 0, 132, 105, 0, 103, 0, 0, 0, 9, 0, 43, 42, 44, 41, 5, 6, 7, 8, 2, 16, 14, 15, 17, 10, 11, 12, 13, 3, 18, 37, 20, 25, 26, 0, 0, 30, 0, - 213, 0, 36, 34, 0, 205, 111, 0, 95, 0, - 0, 678, 0, 636, 0, 0, 0, 0, 0, 653, - 0, 0, 0, 0, 0, 0, 0, 673, 0, 651, - 0, 0, 0, 0, 98, 0, 0, 0, 537, 0, - 0, 146, 0, 200, 0, 206, 45, 49, 52, 55, - 60, 63, 65, 67, 69, 71, 73, 75, 0, 0, - 101, 564, 573, 577, 0, 0, 0, 598, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, - 78, 91, 0, 551, 0, 161, 135, 554, 575, 553, - 561, 552, 0, 555, 556, 579, 557, 586, 558, 559, - 594, 560, 0, 119, 0, 127, 0, 545, 134, 0, - 0, 107, 0, 104, 38, 39, 0, 22, 23, 0, - 0, 28, 27, 0, 215, 31, 33, 40, 0, 212, - 112, 682, 0, 683, 629, 0, 0, 681, 648, 644, - 645, 646, 647, 0, 642, 0, 93, 649, 0, 0, - 663, 664, 665, 666, 0, 661, 0, 667, 0, 0, - 669, 0, 0, 0, 2, 677, 0, 675, 0, 0, - 623, 625, 0, 543, 0, 541, 536, 538, 0, 150, - 148, 203, 0, 0, 0, 0, 0, 0, 0, 0, + 219, 0, 36, 218, 0, 210, 111, 0, 95, 0, + 0, 695, 0, 647, 0, 0, 0, 0, 0, 664, + 0, 0, 0, 0, 0, 0, 0, 689, 0, 662, + 0, 0, 0, 0, 98, 0, 0, 0, 548, 0, + 0, 148, 0, 204, 0, 211, 45, 49, 52, 55, + 60, 63, 65, 67, 69, 71, 73, 75, 0, 34, + 0, 101, 575, 584, 588, 0, 0, 0, 609, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 45, 78, 91, 0, 562, 0, 163, 135, 565, 586, + 564, 572, 563, 0, 566, 567, 590, 568, 597, 569, + 570, 605, 571, 0, 119, 0, 127, 0, 556, 134, + 0, 0, 107, 0, 104, 38, 39, 0, 22, 23, + 0, 0, 28, 27, 0, 221, 31, 33, 40, 0, + 217, 112, 699, 0, 700, 640, 0, 0, 698, 659, + 655, 656, 657, 658, 0, 653, 0, 93, 660, 0, + 0, 674, 675, 676, 677, 0, 672, 0, 681, 682, + 683, 684, 680, 0, 678, 0, 685, 0, 0, 0, + 2, 693, 216, 0, 691, 0, 0, 634, 636, 0, + 554, 0, 552, 547, 549, 0, 152, 150, 208, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 76, 207, 208, 0, 563, 0, 596, 609, 608, - 0, 600, 0, 612, 610, 0, 0, 0, 593, 613, - 614, 615, 562, 81, 82, 84, 83, 86, 87, 88, - 89, 90, 85, 80, 0, 0, 578, 574, 576, 580, - 587, 595, 129, 0, 548, 549, 0, 133, 0, 108, - 4, 0, 24, 21, 32, 214, 632, 634, 0, 0, - 679, 0, 638, 0, 637, 0, 640, 0, 0, 655, - 0, 654, 0, 657, 0, 0, 659, 0, 0, 674, - 0, 671, 0, 652, 627, 0, 544, 0, 539, 534, - 46, 47, 48, 51, 50, 53, 54, 58, 59, 56, - 57, 61, 62, 64, 66, 68, 70, 72, 74, 0, - 209, 565, 0, 0, 0, 0, 611, 0, 592, 79, - 92, 128, 546, 0, 106, 19, 630, 0, 631, 0, - 643, 0, 650, 0, 662, 0, 668, 0, 670, 0, - 0, 676, 540, 542, 0, 0, 584, 0, 0, 0, - 603, 602, 605, 571, 588, 547, 550, 633, 635, 639, - 641, 656, 658, 660, 672, 0, 566, 0, 0, 0, - 604, 0, 0, 583, 0, 0, 581, 0, 77, 0, - 568, 597, 567, 0, 606, 0, 571, 570, 572, 590, - 585, 0, 607, 601, 582, 591, 0, 599, 589 + 0, 0, 0, 0, 0, 0, 0, 0, 76, 212, + 213, 0, 574, 0, 607, 620, 619, 0, 611, 0, + 623, 621, 0, 0, 0, 604, 624, 625, 626, 573, + 81, 82, 84, 83, 86, 87, 88, 89, 90, 85, + 80, 0, 0, 589, 585, 587, 591, 598, 606, 129, + 0, 559, 560, 0, 133, 0, 108, 4, 0, 24, + 21, 32, 220, 643, 645, 0, 0, 696, 0, 649, + 0, 648, 0, 651, 0, 0, 666, 0, 665, 0, + 668, 0, 0, 670, 0, 0, 690, 0, 687, 0, + 663, 638, 0, 555, 0, 550, 545, 46, 47, 48, + 51, 50, 53, 54, 58, 59, 56, 57, 61, 62, + 64, 66, 68, 70, 72, 74, 0, 214, 576, 0, + 0, 0, 0, 622, 0, 603, 79, 92, 128, 557, + 0, 106, 19, 641, 0, 642, 0, 654, 0, 661, + 0, 673, 0, 679, 0, 686, 0, 0, 692, 551, + 553, 0, 0, 595, 0, 0, 0, 614, 613, 616, + 582, 599, 558, 561, 644, 646, 650, 652, 667, 669, + 671, 688, 0, 577, 0, 0, 0, 615, 0, 0, + 594, 0, 0, 592, 0, 77, 0, 579, 608, 578, + 0, 617, 0, 582, 581, 583, 601, 596, 0, 618, + 612, 593, 602, 0, 610, 600 }; - /* YYPGOTO[NTERM-NUM]. */ +/* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -859, -859, -859, -859, -859, -859, -859, -859, -859, -859, - -859, -859, -209, -859, -418, -417, -602, -421, -291, -284, - -286, -283, -281, -287, -859, -473, -859, -490, -859, -497, - -520, 13, -859, -859, -859, 14, -394, -859, -859, 33, - 42, 44, -859, -859, -395, -859, -859, -859, -859, -121, - -859, -381, -369, -859, 9, -859, 0, -424, -859, -859, - -859, -859, 113, -859, -859, -859, -545, -549, -252, -365, - -617, -859, -391, -618, -858, -859, -450, -859, -859, -459, - -458, -859, -859, 43, -721, -387, -859, -173, -859, -422, - -859, -170, -859, -859, -859, -859, -168, -859, -859, -859, - -859, -859, -859, -859, -859, 67, -859, -859, 2, -859, - -97, -300, -386, -859, -859, -859, -326, -323, -327, -859, - -859, -330, -325, -328, -332, -859, -331, -334, -859, -390, - -530 + -872, -544, -872, -872, -872, -872, -872, -872, -872, -872, + -872, -872, -436, -872, -392, -391, -490, -390, -269, -266, + -268, -264, -262, -260, -872, -482, -872, -499, -872, -492, + -534, 6, -872, -872, -872, 1, -403, -872, -872, 45, + 44, 49, -872, -872, -406, -872, -872, -872, -872, -104, + -872, -389, -375, -872, 12, -872, 0, -433, -872, -872, + -872, -553, 145, -872, -872, -872, -560, -556, -233, -344, + -614, -872, -373, -626, -871, -872, -430, -872, -872, -440, + -437, -872, -872, 63, -737, -363, -872, -144, -872, -399, + -872, -142, -872, -872, -872, -872, -134, -872, -872, -872, + -872, -872, -872, -872, -872, 97, -872, -872, 2, -872, + -71, -308, -416, -872, -872, -872, -304, -307, -302, -872, + -872, -315, -310, -306, -300, -314, -872, -299, -317, -872, + -395, -538 }; - /* YYDEFGOTO[NTERM-NUM]. */ +/* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 520, 521, 522, 781, 523, 524, 525, 526, 527, - 528, 529, 609, 531, 577, 578, 579, 580, 581, 582, - 583, 584, 585, 586, 587, 610, 839, 611, 764, 612, - 695, 613, 378, 640, 498, 614, 380, 381, 382, 427, - 428, 429, 383, 384, 385, 386, 387, 388, 477, 478, - 389, 390, 391, 392, 532, 480, 533, 483, 440, 441, - 534, 395, 396, 397, 569, 473, 567, 568, 704, 705, - 638, 776, 617, 618, 619, 620, 621, 736, 875, 911, - 903, 904, 905, 912, 622, 623, 624, 625, 906, 878, - 626, 627, 907, 926, 628, 629, 630, 842, 740, 844, - 882, 901, 902, 631, 398, 399, 400, 424, 632, 470, - 471, 450, 451, 788, 789, 402, 673, 674, 678, 403, - 404, 684, 685, 688, 691, 405, 696, 697, 406, 452, - 453 + 0, 530, 531, 532, 798, 533, 534, 535, 536, 537, + 538, 539, 620, 541, 587, 588, 589, 590, 591, 592, + 593, 594, 595, 596, 597, 621, 856, 622, 781, 623, + 711, 624, 388, 651, 508, 625, 390, 391, 392, 437, + 438, 439, 393, 394, 395, 396, 397, 398, 487, 488, + 399, 400, 401, 402, 542, 490, 599, 493, 450, 451, + 544, 405, 406, 407, 579, 483, 577, 578, 721, 722, + 649, 793, 628, 629, 630, 631, 632, 753, 892, 928, + 920, 921, 922, 929, 633, 634, 635, 636, 923, 895, + 637, 638, 924, 943, 639, 640, 641, 859, 757, 861, + 899, 918, 919, 642, 408, 409, 410, 434, 643, 480, + 481, 460, 461, 805, 806, 412, 684, 685, 689, 413, + 414, 695, 696, 703, 704, 707, 415, 713, 714, 416, + 462, 463 }; - /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule whose - number is the opposite. If YYTABLE_NINF, syntax error. */ +/* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 394, 430, 401, 637, 768, 646, 445, 444, 588, 393, - 494, 445, 667, 377, 379, 841, 535, 772, 707, 775, - 446, 437, 777, 466, 708, 446, 786, 677, 667, 668, - 421, 475, 687, 719, 720, 730, 417, 407, 655, 661, - 910, 699, 662, 481, 661, 430, 658, 918, 541, 562, - 709, 482, 481, 563, 542, 476, 422, 910, 659, 634, - 787, 437, 669, 670, 671, 672, 633, 635, 418, 721, - 722, 731, 589, 663, 676, 408, 589, 437, 663, 676, - 590, 647, 648, 639, 492, 676, 481, 589, 676, 328, - 329, 330, 565, 493, 773, 778, 495, 676, 715, 496, - 716, -35, 497, 649, 745, 409, 747, 650, 456, 458, - 460, 462, 464, 465, 468, 543, 734, 827, 828, 829, - 830, 544, 843, 753, 754, 755, 756, 757, 758, 759, - 760, 761, 762, 549, 557, 432, 571, 410, 433, 550, - 558, 411, 572, 763, 637, 573, 637, 652, 412, 637, - 665, 574, 782, 653, 664, 780, 851, 415, 790, 707, - 664, 765, 664, 784, 542, 664, 693, 664, 413, 664, - 664, 792, 794, 796, 664, 799, 801, 793, 795, 797, - 414, 800, 802, 803, 806, 809, 565, 811, 565, 804, - 807, 810, 425, 812, 883, 884, 437, 889, 925, 890, - 765, 765, 891, 793, 892, 797, 893, 894, 800, 921, - 804, 426, 807, 812, 856, 765, 858, 419, 857, 642, - 859, 434, 643, 768, 680, 681, 682, 683, 454, 707, - 530, 455, 457, 717, 718, 455, 886, 445, 444, 765, - 459, 817, 766, 455, 818, 845, 852, 461, 853, 847, - 455, 446, 463, 467, 675, 455, 455, 455, 679, 565, - 686, 455, 689, 455, 692, 455, 698, 455, 765, 455, - 817, 846, 576, 872, 849, 850, 420, 862, 677, 816, - 667, 723, 724, 637, 866, 687, 712, 713, 714, 423, - 644, 645, 920, 765, 848, 765, 895, 823, 824, 439, - 825, 826, 831, 832, 447, 449, 469, 768, 474, 479, - 484, 325, 481, 490, 491, 536, 537, 538, 561, 540, - 539, 559, 657, 546, 676, 676, 545, 565, 547, 548, - 551, 676, 676, 552, 553, 554, 555, 676, 576, 676, - 556, 560, 874, 576, 570, 876, 564, 651, 656, 576, - 492, 641, 576, 725, 589, 666, 662, 727, 690, 700, - 703, 576, 726, 637, 728, 729, 711, 732, 737, 741, - 735, 738, 742, 746, 779, -36, 739, 743, 748, 783, - 576, 749, 431, -34, 750, 876, 751, -29, 798, 752, - 438, 393, 805, 791, 808, 813, 814, 565, 394, 393, - 401, 394, 913, 840, 855, 908, 394, 393, 401, 765, - 393, 377, 379, 868, 887, 393, 472, 922, 896, 637, - 448, 888, 898, 899, 879, 897, 431, 486, -569, 909, - 431, 915, 914, 591, 833, 393, 919, 927, 916, 393, - 928, 835, 834, 838, 416, 836, 438, 877, 837, 785, - 815, 710, 873, 880, 917, 393, 923, 881, 924, 769, - 900, 446, 770, 488, 771, 443, 701, 485, 487, 861, - 860, 863, 865, 566, 489, 864, 869, 867, 871, 870, - 0, 0, 393, 0, 616, 0, 0, 877, 0, 0, - 0, 0, 0, 615, 0, 0, 0, 0, 0, 0, - 0, 446, 0, 820, 821, 822, 576, 576, 576, 576, - 576, 576, 576, 576, 576, 576, 576, 576, 576, 576, - 576, 576, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 660, 0, + 404, 389, 411, 440, 648, 455, 387, 785, 454, 598, + 455, 504, 403, 540, 678, 712, 858, 545, 702, 725, + 657, 724, 456, 688, 679, 447, 747, 456, 476, 672, + 678, 789, 673, 792, 736, 737, 794, 716, 431, 666, + 427, 669, 803, 672, 927, 485, 726, 440, 491, 442, + 417, 935, 443, 670, 418, 586, 492, 680, 681, 682, + 683, 927, 748, 674, 432, 447, 419, 644, 646, 486, + 738, 739, 428, 655, 656, 687, 804, 674, -694, 420, + 491, 447, 658, 659, -694, 600, 687, 645, 502, 687, + 491, 795, 600, 601, 575, 449, 600, 503, 687, 650, + 551, 553, -35, 790, 660, 668, 552, 554, 661, 421, + 466, 468, 470, 472, 474, 475, 478, 422, 751, 559, + 762, 586, 764, 505, 567, 560, 506, 581, 423, 507, + 568, 860, 586, 582, 675, 586, 464, 583, 467, 465, + 675, 465, 675, 584, 586, 675, 648, 675, 648, 675, + 675, 648, 663, 797, 675, 676, 807, 809, 664, 782, + 811, 813, 552, 810, 586, 801, 812, 814, 799, 724, + 572, 709, 469, 424, 573, 465, 868, 770, 771, 772, + 773, 774, 775, 776, 777, 778, 779, 816, 575, 425, + 575, 471, 818, 817, 465, 820, 823, 780, 819, 942, + 447, 821, 824, 826, 828, 900, 901, 906, 907, 827, + 829, 782, 782, 810, 814, 908, 909, 910, 911, 938, + 429, 817, 821, 824, 829, 782, 873, 875, 734, 735, + 874, 876, 785, 802, 732, 430, 733, 455, 436, 724, + 454, 698, 699, 700, 701, 521, 844, 845, 846, 847, + 653, 433, 473, 654, 456, 465, 903, 691, 692, 693, + 694, 477, 575, 686, 465, 690, 465, 862, 465, 697, + 705, 864, 465, 465, 712, 435, 712, 702, 702, 449, + 879, 688, 866, 867, 869, 708, 870, 833, 465, 678, + 444, 648, 457, 837, 838, 839, 586, 586, 586, 586, + 586, 586, 586, 586, 586, 586, 586, 586, 586, 586, + 586, 586, 937, 459, 715, 782, 785, 465, 783, 834, + 782, 834, 835, 863, 889, 334, 335, 336, 740, 741, + 782, 865, 687, 687, 782, 912, 575, 729, 730, 731, + 840, 841, 479, 842, 843, 687, 484, 687, 331, 494, + 848, 849, 489, 500, 501, 491, 547, 548, 549, 546, + 555, 550, 574, 742, 891, 569, 556, 893, 652, 557, + 558, 648, 561, 562, 600, 563, 564, 565, 586, 586, + 566, 570, 571, 667, 580, 662, -34, 502, 706, 745, + 673, 586, 441, 586, 717, 746, 677, 743, 744, 749, + 448, 754, 752, 755, 403, 756, 575, 893, 404, 389, + 411, 404, 403, 925, 387, 720, 404, 458, 411, 758, + 403, 728, 759, 403, 930, 760, 482, 648, 403, 763, + 766, 765, -36, 815, 767, 768, 441, 496, 769, 939, + 441, 796, 800, -29, 808, 822, 825, 830, 403, 543, + 831, 857, 403, 894, 872, 885, 448, 782, 896, 904, + 905, 916, 913, 915, 926, 932, 914, -580, 403, 931, + 456, 602, 936, 850, 945, 944, 852, 851, 727, 933, + 497, 853, 426, 576, 854, 498, 832, 855, 897, 499, + 890, 934, 940, 894, 627, 403, 941, 495, 898, 786, + 917, 787, 718, 877, 882, 453, 626, 881, 878, 788, + 456, 886, 888, 880, 0, 0, 884, 0, 0, 0, + 0, 883, 0, 0, 0, 0, 0, 0, 887, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 671, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 719, 0, 576, 0, 576, + 0, 0, 0, 0, 0, 0, 0, 403, 0, 403, + 0, 403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 702, 0, 566, 0, 566, - 0, 0, 0, 0, 393, 0, 393, 0, 393, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 576, 576, - 0, 0, 0, 0, 0, 576, 576, 0, 0, 0, - 0, 576, 0, 576, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, - 0, 615, 394, 0, 0, 0, 0, 0, 0, 0, - 566, 393, 0, 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 627, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 404, 0, 626, 0, 0, 0, 0, + 0, 576, 0, 0, 0, 403, 0, 0, 0, 0, + 0, 0, 0, 403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 566, 0, - 0, 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 616, 0, 0, 0, - 616, 0, 0, 0, 0, 615, 0, 0, 0, 615, + 0, 0, 0, 0, 0, 576, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 627, 0, 0, 0, 627, 0, 0, + 0, 0, 0, 0, 0, 626, 0, 0, 0, 626, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 566, 0, - 0, 0, 0, 0, 0, 0, 0, 393, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 576, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 616, 616, 0, 616, 0, 401, 0, 0, 0, - 615, 615, 0, 615, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 627, 627, + 0, 627, 0, 411, 0, 0, 0, 0, 0, 0, + 626, 626, 0, 626, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 627, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 616, 0, 0, 0, 0, 0, 0, 0, - 0, 615, 0, 0, 0, 0, 0, 0, 616, 0, - 0, 0, 0, 0, 0, 616, 0, 615, 0, 0, - 0, 0, 0, 0, 615, 616, 0, 0, 0, 616, - 0, 0, 0, 0, 615, 616, 0, 0, 615, 0, - 0, 0, 442, 0, 615, 1, 2, 3, 4, 5, + 0, 626, 0, 0, 0, 627, 0, 0, 0, 0, + 0, 0, 627, 0, 0, 0, 0, 626, 0, 0, + 0, 0, 627, 0, 626, 0, 627, 0, 0, 0, + 0, 0, 627, 0, 626, 0, 0, 0, 626, 0, + 0, 0, 452, 0, 626, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, @@ -1810,20 +1790,21 @@ static const yytype_int16 yytable[] = 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, + 326, 327, 328, 329, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, - 0, 326, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 327, 328, 329, 330, 331, - 0, 0, 0, 0, 0, 0, 0, 0, 332, 333, - 334, 335, 336, 337, 338, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 331, + 0, 0, 0, 0, 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 339, 340, 341, 342, 343, 344, 0, 0, 0, 0, - 0, 0, 0, 0, 345, 0, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 0, 333, 334, 335, 336, 337, 0, 0, 0, 0, + 0, 0, 0, 0, 338, 339, 340, 341, 342, 343, + 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 345, 346, 347, 348, + 349, 350, 351, 0, 0, 0, 0, 0, 0, 0, + 0, 352, 0, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 1, 2, 3, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 381, 382, 383, 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, @@ -1856,19 +1837,20 @@ static const yytype_int16 yytable[] = 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 0, 0, 499, 500, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 501, 502, 0, 325, 0, 591, 592, 0, - 0, 0, 0, 593, 503, 504, 505, 506, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 327, 328, 329, - 330, 331, 0, 0, 0, 507, 508, 509, 510, 511, - 332, 333, 334, 335, 336, 337, 338, 594, 595, 596, - 597, 0, 598, 599, 600, 601, 602, 603, 604, 605, - 606, 607, 339, 340, 341, 342, 343, 344, 512, 513, - 514, 515, 516, 517, 518, 519, 345, 608, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, + 324, 325, 326, 327, 328, 329, 330, 0, 0, 509, + 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 511, 512, + 0, 331, 0, 602, 603, 0, 0, 0, 0, 604, + 513, 514, 515, 516, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 333, 334, 335, 336, 337, 0, 0, + 0, 517, 518, 519, 520, 521, 338, 339, 340, 341, + 342, 343, 344, 605, 606, 607, 608, 0, 609, 610, + 611, 612, 613, 614, 615, 616, 617, 618, 345, 346, + 347, 348, 349, 350, 351, 522, 523, 524, 525, 526, + 527, 528, 529, 352, 619, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 1, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, 383, 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -1901,20 +1883,21 @@ static const yytype_int16 yytable[] = 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 0, 0, 499, 500, 0, 0, 0, + 322, 323, 324, 325, 326, 327, 328, 329, 330, 0, + 0, 509, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 501, 502, 0, 325, 0, 591, - 767, 0, 0, 0, 0, 593, 503, 504, 505, 506, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 327, - 328, 329, 330, 331, 0, 0, 0, 507, 508, 509, - 510, 511, 332, 333, 334, 335, 336, 337, 338, 594, - 595, 596, 597, 0, 598, 599, 600, 601, 602, 603, - 604, 605, 606, 607, 339, 340, 341, 342, 343, 344, - 512, 513, 514, 515, 516, 517, 518, 519, 345, 608, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 511, 512, 0, 331, 0, 602, 784, 0, 0, 0, + 0, 604, 513, 514, 515, 516, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 333, 334, 335, 336, 337, + 0, 0, 0, 517, 518, 519, 520, 521, 338, 339, + 340, 341, 342, 343, 344, 605, 606, 607, 608, 0, + 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, + 345, 346, 347, 348, 349, 350, 351, 522, 523, 524, + 525, 526, 527, 528, 529, 352, 619, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, + 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, @@ -1946,20 +1929,21 @@ static const yytype_int16 yytable[] = 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 0, 0, 499, 500, 0, + 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, + 330, 0, 0, 509, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 501, 502, 0, 325, - 0, 591, 0, 0, 0, 0, 0, 593, 503, 504, - 505, 506, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 327, 328, 329, 330, 331, 0, 0, 0, 507, - 508, 509, 510, 511, 332, 333, 334, 335, 336, 337, - 338, 594, 595, 596, 597, 0, 598, 599, 600, 601, - 602, 603, 604, 605, 606, 607, 339, 340, 341, 342, - 343, 344, 512, 513, 514, 515, 516, 517, 518, 519, - 345, 608, 346, 347, 348, 349, 350, 351, 352, 353, + 0, 0, 511, 512, 0, 331, 0, 602, 0, 0, + 0, 0, 0, 604, 513, 514, 515, 516, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 333, 334, 335, + 336, 337, 0, 0, 0, 517, 518, 519, 520, 521, + 338, 339, 340, 341, 342, 343, 344, 605, 606, 607, + 608, 0, 609, 610, 611, 612, 613, 614, 615, 616, + 617, 618, 345, 346, 347, 348, 349, 350, 351, 522, + 523, 524, 525, 526, 527, 528, 529, 352, 619, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, - 374, 375, 376, 1, 2, 3, 4, 5, 6, 7, + 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, + 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, @@ -1991,20 +1975,21 @@ static const yytype_int16 yytable[] = 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 0, 0, 499, - 500, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 501, 502, - 0, 325, 0, 484, 0, 0, 0, 0, 0, 593, - 503, 504, 505, 506, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 327, 328, 329, 330, 331, 0, 0, - 0, 507, 508, 509, 510, 511, 332, 333, 334, 335, - 336, 337, 338, 594, 595, 596, 597, 0, 598, 599, - 600, 601, 602, 603, 604, 605, 606, 607, 339, 340, - 341, 342, 343, 344, 512, 513, 514, 515, 516, 517, - 518, 519, 345, 608, 346, 347, 348, 349, 350, 351, - 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 0, 0, 509, 510, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 511, 512, 0, 331, 0, 494, + 0, 0, 0, 0, 0, 604, 513, 514, 515, 516, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 333, + 334, 335, 336, 337, 0, 0, 0, 517, 518, 519, + 520, 521, 338, 339, 340, 341, 342, 343, 344, 605, + 606, 607, 608, 0, 609, 610, 611, 612, 613, 614, + 615, 616, 617, 618, 345, 346, 347, 348, 349, 350, + 351, 522, 523, 524, 525, 526, 527, 528, 529, 352, + 619, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 375, 376, 1, 2, 3, 4, 5, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, + 382, 383, 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, @@ -2036,20 +2021,21 @@ static const yytype_int16 yytable[] = 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, 317, 318, 319, 320, 321, 322, 323, 324, 0, - 0, 499, 500, 0, 0, 0, 0, 0, 0, 0, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, + 326, 327, 328, 329, 330, 0, 0, 509, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 501, 502, 0, 325, 0, 0, 0, 0, 0, 0, - 0, 593, 503, 504, 505, 506, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 327, 328, 329, 330, 331, - 0, 0, 0, 507, 508, 509, 510, 511, 332, 333, - 334, 335, 336, 337, 338, 594, 595, 596, 597, 0, - 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, - 339, 340, 341, 342, 343, 344, 512, 513, 514, 515, - 516, 517, 518, 519, 345, 608, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 0, 0, 0, 0, 0, 0, 511, 512, 0, 331, + 0, 0, 0, 0, 0, 0, 0, 604, 513, 514, + 515, 516, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 333, 334, 335, 336, 337, 0, 0, 0, 517, + 518, 519, 520, 521, 338, 339, 340, 341, 342, 343, + 344, 605, 606, 607, 608, 0, 609, 610, 611, 612, + 613, 614, 615, 616, 617, 618, 345, 346, 347, 348, + 349, 350, 351, 522, 523, 524, 525, 526, 527, 528, + 529, 352, 619, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 1, 2, 3, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 381, 382, 383, 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, @@ -2082,19 +2068,20 @@ static const yytype_int16 yytable[] = 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 0, 0, 499, 500, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 501, 502, 0, 325, 0, 0, 0, 0, - 0, 0, 0, 593, 503, 504, 505, 506, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 327, 328, 329, - 330, 331, 0, 0, 0, 507, 508, 509, 510, 511, - 332, 333, 334, 335, 336, 337, 338, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 339, 340, 341, 342, 343, 344, 512, 513, - 514, 515, 516, 517, 518, 519, 345, 0, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, + 324, 325, 326, 327, 328, 329, 330, 0, 0, 509, + 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 511, 512, + 0, 331, 0, 0, 0, 0, 0, 0, 0, 604, + 513, 514, 515, 516, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 333, 334, 335, 336, 337, 0, 0, + 0, 517, 518, 519, 520, 521, 338, 339, 340, 341, + 342, 343, 344, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 345, 346, + 347, 348, 349, 350, 351, 522, 523, 524, 525, 526, + 527, 528, 529, 352, 0, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 1, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, 383, 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -2126,21 +2113,22 @@ static const yytype_int16 yytable[] = 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, - 312, 313, 314, 0, 0, 0, 318, 319, 320, 321, - 322, 323, 324, 0, 0, 499, 500, 0, 0, 0, + 312, 313, 314, 315, 316, 317, 0, 0, 0, 321, + 322, 323, 324, 325, 326, 327, 328, 329, 330, 0, + 0, 509, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 501, 502, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 503, 504, 505, 506, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 327, - 328, 329, 330, 0, 0, 0, 0, 507, 508, 509, - 510, 511, 332, 333, 334, 335, 336, 337, 338, 0, + 511, 512, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 513, 514, 515, 516, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 333, 334, 335, 336, 0, + 0, 0, 0, 517, 518, 519, 520, 521, 338, 339, + 340, 341, 342, 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 339, 340, 341, 342, 343, 344, - 512, 513, 514, 515, 516, 517, 518, 519, 345, 0, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 345, 346, 347, 348, 349, 350, 351, 522, 523, 524, + 525, 526, 527, 528, 529, 352, 0, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, + 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, @@ -2172,20 +2160,21 @@ static const yytype_int16 yytable[] = 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 0, 0, 0, 0, 0, + 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, + 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, - 0, 0, 0, 0, 0, 0, 0, 326, 0, 0, + 0, 0, 0, 0, 0, 331, 0, 0, 0, 0, + 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 333, 334, 335, + 336, 337, 0, 0, 0, 0, 0, 0, 0, 0, + 338, 339, 340, 341, 342, 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 327, 328, 329, 330, 331, 0, 0, 0, 0, - 0, 0, 0, 0, 332, 333, 334, 335, 336, 337, - 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 339, 340, 341, 342, - 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, - 345, 0, 346, 347, 348, 349, 350, 351, 352, 353, + 0, 0, 345, 346, 347, 348, 349, 350, 351, 0, + 0, 0, 0, 0, 0, 0, 0, 352, 0, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, - 374, 375, 376, 1, 2, 3, 4, 5, 6, 7, + 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, + 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, @@ -2216,21 +2205,22 @@ static const yytype_int16 yytable[] = 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 0, 0, 0, - 318, 319, 320, 321, 322, 323, 324, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, + 0, 0, 0, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 327, 328, 329, 330, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 332, 333, 334, 335, - 336, 337, 338, 594, 0, 0, 597, 0, 598, 599, - 0, 0, 602, 0, 0, 0, 0, 0, 339, 340, - 341, 342, 343, 344, 0, 0, 0, 0, 0, 0, - 0, 0, 345, 0, 346, 347, 348, 349, 350, 351, - 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 333, + 334, 335, 336, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 338, 339, 340, 341, 342, 343, 344, 605, + 0, 0, 608, 0, 609, 610, 0, 0, 613, 0, + 0, 0, 0, 0, 345, 346, 347, 348, 349, 350, + 351, 0, 0, 0, 0, 0, 0, 0, 0, 352, + 0, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 375, 376, 1, 2, 3, 4, 5, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, + 382, 383, 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, @@ -2261,21 +2251,22 @@ static const yytype_int16 yytable[] = 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 0, - 0, 0, 318, 319, 320, 321, 322, 323, 324, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, + 316, 317, 0, 0, 0, 321, 322, 323, 324, 325, + 326, 327, 328, 329, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 435, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 327, 328, 329, 330, 0, - 0, 0, 0, 0, 0, 0, 0, 436, 332, 333, - 334, 335, 336, 337, 338, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 445, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 339, 340, 341, 342, 343, 344, 0, 0, 0, 0, - 0, 0, 0, 0, 345, 0, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 0, 333, 334, 335, 336, 0, 0, 0, 0, 0, + 0, 0, 0, 446, 338, 339, 340, 341, 342, 343, + 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 345, 346, 347, 348, + 349, 350, 351, 0, 0, 0, 0, 0, 0, 0, + 0, 352, 0, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 1, 2, 3, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 381, 382, 383, 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, @@ -2307,20 +2298,21 @@ static const yytype_int16 yytable[] = 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 0, 0, 0, 318, 319, 320, 321, 322, 323, - 324, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 314, 315, 316, 317, 0, 0, 0, 321, 322, 323, + 324, 325, 326, 327, 328, 329, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 327, 328, 329, - 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 332, 333, 334, 335, 336, 337, 338, 0, 0, 0, + 0, 331, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 339, 340, 341, 342, 343, 344, 0, 0, - 0, 0, 0, 0, 0, 0, 345, 0, 346, 347, - 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, + 0, 0, 0, 333, 334, 335, 336, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 338, 339, 340, 341, + 342, 343, 344, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 345, 346, + 347, 348, 349, 350, 351, 0, 0, 0, 0, 0, + 0, 0, 0, 352, 0, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, - 368, 369, 370, 371, 372, 373, 374, 375, 376, 1, + 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, 383, 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -2352,21 +2344,22 @@ static const yytype_int16 yytable[] = 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, - 312, 313, 314, 0, 0, 0, 318, 319, 320, 321, - 322, 323, 324, 0, 0, 0, 0, 0, 0, 0, + 312, 313, 314, 315, 316, 317, 0, 0, 0, 321, + 322, 323, 324, 325, 326, 327, 328, 329, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 706, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 327, - 328, 329, 330, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 332, 333, 334, 335, 336, 337, 338, 0, + 0, 0, 0, 0, 0, 0, 723, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 339, 340, 341, 342, 343, 344, - 0, 0, 0, 0, 0, 0, 0, 0, 345, 0, - 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 0, 0, 0, 0, 0, 333, 334, 335, 336, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 338, 339, + 340, 341, 342, 343, 344, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 345, 346, 347, 348, 349, 350, 351, 0, 0, 0, + 0, 0, 0, 0, 0, 352, 0, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, - 376, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, + 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, @@ -2397,21 +2390,22 @@ static const yytype_int16 yytable[] = 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 0, 0, 0, 318, 319, - 320, 321, 322, 323, 324, 0, 0, 0, 0, 0, + 310, 311, 312, 313, 314, 315, 316, 317, 0, 0, + 0, 321, 322, 323, 324, 325, 326, 327, 328, 329, + 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 836, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 819, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 333, 334, 335, + 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 338, 339, 340, 341, 342, 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 327, 328, 329, 330, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 332, 333, 334, 335, 336, 337, - 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 339, 340, 341, 342, - 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, - 345, 0, 346, 347, 348, 349, 350, 351, 352, 353, + 0, 0, 345, 346, 347, 348, 349, 350, 351, 0, + 0, 0, 0, 0, 0, 0, 0, 352, 0, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, - 374, 375, 376, 1, 2, 3, 4, 5, 6, 7, + 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, + 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, @@ -2442,21 +2436,22 @@ static const yytype_int16 yytable[] = 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 0, 0, 0, - 318, 319, 320, 321, 322, 323, 324, 0, 0, 0, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, + 0, 0, 0, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 854, 0, 0, 0, 0, 0, + 871, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 333, + 334, 335, 336, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 338, 339, 340, 341, 342, 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 327, 328, 329, 330, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 332, 333, 334, 335, - 336, 337, 338, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 339, 340, - 341, 342, 343, 344, 0, 0, 0, 0, 0, 0, - 0, 0, 345, 0, 346, 347, 348, 349, 350, 351, - 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 0, 0, 0, 0, 345, 346, 347, 348, 349, 350, + 351, 0, 0, 0, 0, 0, 0, 0, 0, 352, + 0, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, - 372, 373, 374, 375, 376, 1, 2, 3, 4, 5, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, + 382, 383, 384, 385, 386, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, @@ -2487,21 +2482,22 @@ static const yytype_int16 yytable[] = 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 0, - 0, 0, 318, 319, 320, 321, 322, 323, 324, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, + 316, 317, 0, 0, 0, 321, 322, 323, 324, 325, + 326, 327, 328, 329, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 327, 328, 329, 330, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 332, 333, - 334, 335, 336, 337, 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 339, 340, 341, 342, 343, 344, 0, 0, 0, 0, - 0, 0, 0, 0, 345, 0, 346, 347, 348, 349, - 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, + 0, 333, 334, 335, 336, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 338, 339, 340, 341, 342, 343, + 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 345, 346, 347, 348, + 349, 350, 351, 0, 0, 0, 0, 0, 0, 0, + 0, 352, 0, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, - 370, 371, 372, 373, 374, 375, 376, 2, 3, 4, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, + 380, 381, 382, 383, 384, 385, 386, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, @@ -2518,7 +2514,7 @@ static const yytype_int16 yytable[] = 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 165, 0, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, @@ -2533,502 +2529,511 @@ static const yytype_int16 yytable[] = 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 0, 0, 0, 0, 0, 0, 321, 0, 0, 0, - 0, 0, 499, 500, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 501, 502, 0, 0, 0, 636, 774, 0, 0, - 0, 0, 0, 503, 504, 505, 506, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 507, 508, 509, 510, 511, 332, - 0, 0, 0, 0, 337, 338, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 512, 513, 514, - 515, 516, 517, 518, 519, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 358, - 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 0, 0, 61, - 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, - 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, - 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, - 312, 313, 314, 0, 0, 0, 0, 0, 0, 321, - 0, 0, 0, 0, 0, 499, 500, 0, 0, 0, + 315, 316, 317, 0, 0, 0, 0, 0, 0, 324, + 0, 0, 0, 328, 329, 330, 0, 0, 509, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 501, 502, 0, 0, 0, 636, - 885, 0, 0, 0, 0, 0, 503, 504, 505, 506, + 0, 0, 0, 0, 0, 0, 0, 511, 512, 0, + 0, 0, 647, 791, 0, 0, 0, 0, 0, 513, + 514, 515, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 507, 508, 509, - 510, 511, 332, 0, 0, 0, 0, 337, 338, 0, + 517, 518, 519, 520, 521, 338, 0, 0, 0, 0, + 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 522, 523, 524, 525, 526, 527, + 528, 529, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 365, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 0, 0, 0, 0, 0, 0, 324, + 0, 0, 0, 328, 329, 330, 0, 0, 509, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 512, 513, 514, 515, 516, 517, 518, 519, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 511, 512, 0, + 0, 0, 647, 902, 0, 0, 0, 0, 0, 513, + 514, 515, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 358, 2, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 0, 0, 61, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 0, 0, 0, 0, - 0, 0, 321, 0, 0, 0, 0, 0, 499, 500, + 517, 518, 519, 520, 521, 338, 0, 0, 0, 0, + 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 501, 502, 0, - 0, 575, 0, 0, 0, 0, 0, 0, 0, 503, - 504, 505, 506, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 522, 523, 524, 525, 526, 527, + 528, 529, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 365, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 0, 0, 0, 0, 0, 0, 324, + 0, 0, 0, 328, 329, 330, 0, 0, 509, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 507, 508, 509, 510, 511, 332, 0, 0, 0, 0, - 337, 338, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 511, 512, 0, + 0, 585, 0, 0, 0, 0, 0, 0, 0, 513, + 514, 515, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 512, 513, 514, 515, 516, 517, 518, - 519, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 358, 2, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 0, 0, 61, 62, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 0, - 0, 0, 0, 0, 0, 321, 0, 0, 0, 0, - 0, 499, 500, 0, 0, 0, 0, 0, 0, 0, + 517, 518, 519, 520, 521, 338, 0, 0, 0, 0, + 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 501, 502, 0, 0, 0, 636, 0, 0, 0, 0, - 0, 0, 503, 504, 505, 506, 0, 0, 0, 0, + 0, 0, 0, 0, 522, 523, 524, 525, 526, 527, + 528, 529, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 365, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 0, 0, 0, 0, 0, 0, 324, + 0, 0, 0, 328, 329, 330, 0, 0, 509, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 507, 508, 509, 510, 511, 332, 0, - 0, 0, 0, 337, 338, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 511, 512, 0, + 0, 0, 647, 0, 0, 0, 0, 0, 0, 513, + 514, 515, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 512, 513, 514, 515, - 516, 517, 518, 519, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 358, 2, - 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 0, 0, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 0, 0, 0, 0, 0, 0, 321, 0, - 0, 0, 0, 0, 499, 500, 0, 0, 0, 0, + 517, 518, 519, 520, 521, 338, 0, 0, 0, 0, + 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 501, 502, 0, 0, 733, 0, 0, - 0, 0, 0, 0, 0, 503, 504, 505, 506, 0, + 0, 0, 0, 0, 522, 523, 524, 525, 526, 527, + 528, 529, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 365, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 0, 0, 0, 0, 0, 0, 324, + 0, 0, 0, 328, 329, 330, 0, 0, 509, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 507, 508, 509, 510, - 511, 332, 0, 0, 0, 0, 337, 338, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 511, 512, 0, + 0, 750, 0, 0, 0, 0, 0, 0, 0, 513, + 514, 515, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 512, - 513, 514, 515, 516, 517, 518, 519, 0, 0, 0, + 517, 518, 519, 520, 521, 338, 0, 0, 0, 0, + 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 358, 2, 3, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 0, - 0, 61, 62, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 0, 0, 0, 0, 0, - 0, 321, 0, 0, 0, 0, 0, 499, 500, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 501, 502, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 744, 503, 504, - 505, 506, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 507, - 508, 509, 510, 511, 332, 0, 0, 0, 0, 337, - 338, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 522, 523, 524, 525, 526, 527, + 528, 529, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 365, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 0, 0, 0, 0, 0, 0, 324, + 0, 0, 0, 328, 329, 330, 0, 0, 509, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 512, 513, 514, 515, 516, 517, 518, 519, + 0, 0, 0, 0, 0, 0, 0, 511, 512, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 761, 513, + 514, 515, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 358, 2, 3, 4, 5, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 0, 0, 61, 62, 63, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, - 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, - 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, - 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, - 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, - 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, - 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, - 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, - 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, - 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, - 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, - 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, - 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, - 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, - 307, 308, 309, 310, 311, 312, 313, 314, 0, 0, - 0, 0, 0, 0, 321, 0, 0, 0, 0, 0, - 499, 500, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 501, - 502, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 503, 504, 505, 506, 0, 0, 0, 0, 0, + 517, 518, 519, 520, 521, 338, 0, 0, 0, 0, + 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 507, 508, 509, 510, 511, 332, 0, 0, - 0, 0, 337, 338, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 522, 523, 524, 525, 526, 527, + 528, 529, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 365, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 0, 0, 0, 0, 0, 0, 324, + 0, 0, 0, 328, 329, 330, 0, 0, 509, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 512, 513, 514, 515, 516, - 517, 518, 519, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 358, 2, 3, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 0, 0, 61, 62, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 0, 0, 0, 0, 0, 0, 321, 0, 0, - 0, 0, 0, 499, 500, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 511, 512, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 513, + 514, 515, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 501, 502, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 503, 504, 505, 506, 0, 0, + 517, 518, 519, 520, 521, 338, 0, 0, 0, 0, + 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 507, 508, 509, 510, 511, - 332, 0, 0, 0, 0, 337, 654, 0, 0, 0, + 0, 0, 0, 0, 522, 523, 524, 525, 526, 527, + 528, 529, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 365, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 0, 0, 0, 0, 0, 0, 324, + 0, 0, 0, 328, 329, 330, 0, 0, 509, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 512, 513, - 514, 515, 516, 517, 518, 519, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 511, 512, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 513, + 514, 515, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 358, 2, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 0, 0, - 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 0, 0, 0, 0, 0, 0, - 321, 0, 0, 0, 0, 0, 499, 500, 0, 0, + 517, 518, 519, 520, 521, 338, 0, 0, 0, 0, + 343, 665, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 501, 502, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 503, 504, 505, - 506, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 507, 508, - 509, 510, 694, 332, 0, 0, 0, 0, 337, 338, + 0, 0, 0, 0, 522, 523, 524, 525, 526, 527, + 528, 529, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 365, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 0, 0, 0, 0, 0, 0, 324, + 0, 0, 0, 328, 329, 330, 0, 0, 509, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 511, 512, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 513, + 514, 515, 516, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 512, 513, 514, 515, 516, 517, 518, 519, 0, + 517, 518, 519, 520, 710, 338, 0, 0, 0, 0, + 343, 344, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 358, 2, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 0, 0, 61, 62, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 0, 0, 0, - 0, 0, 0, 321, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 522, 523, 524, 525, 526, 527, + 528, 529, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 365, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 0, 0, 61, 62, 63, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, + 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, + 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 0, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, + 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, + 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, + 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, + 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, + 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, + 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, + 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, + 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, + 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 0, 0, 0, 0, 0, 0, 324, + 0, 0, 0, 328, 329, 330, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 332, 0, 0, 0, - 0, 337, 338 + 0, 0, 0, 0, 0, 338, 0, 0, 0, 0, + 343, 344 }; static const yytype_int16 yycheck[] = { - 0, 382, 0, 493, 622, 502, 401, 401, 481, 0, - 434, 406, 542, 0, 0, 736, 440, 634, 567, 636, - 401, 390, 639, 413, 569, 406, 348, 547, 558, 348, - 359, 385, 552, 331, 332, 336, 353, 349, 528, 348, - 898, 561, 351, 351, 348, 426, 356, 905, 350, 352, - 570, 359, 351, 356, 356, 409, 385, 915, 368, 358, - 382, 430, 381, 382, 383, 384, 490, 491, 385, 367, - 368, 372, 351, 382, 547, 349, 351, 446, 382, 552, - 359, 329, 330, 358, 349, 558, 351, 351, 561, 374, - 375, 376, 473, 358, 358, 640, 353, 570, 361, 356, - 363, 349, 359, 351, 601, 349, 603, 355, 408, 409, - 410, 411, 412, 413, 414, 350, 589, 719, 720, 721, - 722, 356, 740, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 350, 350, 356, 350, 349, 359, 356, - 356, 349, 356, 358, 634, 350, 636, 350, 349, 639, - 540, 356, 649, 356, 540, 350, 773, 351, 350, 708, - 546, 356, 548, 653, 356, 551, 556, 553, 349, 555, - 556, 350, 350, 350, 560, 350, 350, 356, 356, 356, - 349, 356, 356, 350, 350, 350, 567, 350, 569, 356, - 356, 356, 350, 356, 350, 350, 565, 350, 919, 350, - 356, 356, 350, 356, 350, 356, 350, 350, 356, 350, - 356, 356, 356, 356, 352, 356, 352, 349, 356, 356, - 356, 385, 359, 841, 381, 382, 383, 384, 382, 778, - 439, 385, 382, 327, 328, 385, 853, 632, 632, 356, - 382, 356, 359, 385, 359, 742, 354, 382, 356, 746, - 385, 632, 382, 382, 382, 385, 385, 385, 382, 640, - 382, 385, 382, 385, 382, 385, 382, 385, 356, 385, - 356, 359, 481, 359, 764, 765, 349, 797, 798, 703, - 810, 333, 334, 773, 804, 805, 364, 365, 366, 359, - 499, 500, 909, 356, 357, 356, 357, 715, 716, 367, - 717, 718, 723, 724, 359, 385, 385, 925, 353, 385, - 353, 351, 351, 385, 385, 350, 385, 359, 349, 356, - 358, 350, 531, 356, 797, 798, 358, 708, 356, 356, - 356, 804, 805, 356, 356, 356, 356, 810, 547, 812, - 356, 356, 839, 552, 358, 842, 359, 350, 349, 558, - 349, 385, 561, 371, 351, 385, 351, 369, 348, 352, - 385, 570, 370, 853, 335, 337, 385, 352, 349, 349, - 354, 359, 349, 349, 385, 349, 359, 359, 357, 385, - 589, 359, 382, 349, 359, 882, 359, 350, 356, 359, - 390, 382, 356, 358, 356, 350, 350, 778, 398, 390, - 398, 401, 899, 352, 352, 895, 406, 398, 406, 356, - 401, 398, 398, 348, 348, 406, 416, 914, 354, 909, - 406, 382, 350, 349, 393, 385, 426, 425, 353, 358, - 430, 350, 359, 353, 725, 426, 353, 359, 397, 430, - 354, 727, 726, 730, 331, 728, 446, 842, 729, 658, - 702, 572, 817, 844, 904, 446, 915, 844, 916, 632, - 882, 842, 632, 430, 632, 398, 563, 424, 426, 795, - 793, 798, 802, 473, 430, 800, 808, 805, 812, 810, - -1, -1, 473, -1, 484, -1, -1, 882, -1, -1, - -1, -1, -1, 484, -1, -1, -1, -1, -1, -1, - -1, 882, -1, 712, 713, 714, 715, 716, 717, 718, - 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, - 729, 730, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 536, -1, + 0, 0, 0, 392, 503, 411, 0, 633, 411, 491, + 416, 444, 0, 449, 552, 568, 753, 450, 562, 579, + 512, 577, 411, 557, 354, 400, 342, 416, 423, 354, + 568, 645, 357, 647, 337, 338, 650, 571, 365, 538, + 359, 362, 354, 354, 915, 391, 580, 436, 357, 362, + 355, 922, 365, 374, 355, 491, 365, 387, 388, 389, + 390, 932, 378, 388, 391, 440, 355, 500, 501, 415, + 373, 374, 391, 509, 510, 557, 388, 388, 356, 355, + 357, 456, 335, 336, 362, 357, 568, 364, 355, 571, + 357, 651, 357, 365, 483, 373, 357, 364, 580, 364, + 356, 356, 355, 364, 357, 541, 362, 362, 361, 355, + 418, 419, 420, 421, 422, 423, 424, 355, 600, 356, + 612, 557, 614, 359, 356, 362, 362, 356, 355, 365, + 362, 757, 568, 362, 550, 571, 388, 356, 388, 391, + 556, 391, 558, 362, 580, 561, 645, 563, 647, 565, + 566, 650, 356, 356, 570, 550, 356, 356, 362, 362, + 356, 356, 362, 362, 600, 664, 362, 362, 660, 725, + 358, 566, 388, 355, 362, 391, 790, 344, 345, 346, + 347, 348, 349, 350, 351, 352, 353, 356, 577, 357, + 579, 388, 356, 362, 391, 356, 356, 364, 362, 936, + 575, 362, 362, 356, 356, 356, 356, 356, 356, 362, + 362, 362, 362, 362, 362, 356, 356, 356, 356, 356, + 355, 362, 362, 362, 362, 362, 358, 358, 333, 334, + 362, 362, 858, 669, 367, 355, 369, 643, 362, 795, + 643, 387, 388, 389, 390, 391, 736, 737, 738, 739, + 362, 365, 388, 365, 643, 391, 870, 387, 388, 389, + 390, 388, 651, 388, 391, 388, 391, 759, 391, 388, + 388, 763, 391, 391, 827, 356, 829, 821, 822, 373, + 814, 815, 781, 782, 360, 388, 362, 720, 391, 827, + 391, 790, 365, 729, 730, 731, 732, 733, 734, 735, + 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, + 746, 747, 926, 391, 388, 362, 942, 391, 365, 362, + 362, 362, 365, 365, 365, 380, 381, 382, 339, 340, + 362, 363, 814, 815, 362, 363, 725, 370, 371, 372, + 732, 733, 391, 734, 735, 827, 359, 829, 357, 359, + 740, 741, 391, 391, 391, 357, 391, 365, 364, 356, + 364, 362, 365, 377, 856, 356, 362, 859, 391, 362, + 362, 870, 362, 362, 357, 362, 362, 362, 814, 815, + 362, 362, 355, 355, 364, 356, 355, 355, 354, 341, + 357, 827, 392, 829, 358, 343, 391, 376, 375, 358, + 400, 355, 360, 365, 392, 365, 795, 899, 408, 408, + 408, 411, 400, 912, 408, 391, 416, 416, 416, 355, + 408, 391, 355, 411, 916, 365, 426, 926, 416, 355, + 365, 363, 355, 362, 365, 365, 436, 435, 365, 931, + 440, 391, 391, 356, 364, 362, 362, 356, 436, 449, + 356, 358, 440, 859, 358, 354, 456, 362, 399, 354, + 388, 355, 360, 356, 364, 356, 391, 359, 456, 365, + 859, 359, 359, 742, 360, 365, 744, 743, 582, 403, + 436, 745, 337, 483, 746, 440, 719, 747, 861, 440, + 834, 921, 932, 899, 494, 483, 933, 434, 861, 643, + 899, 643, 573, 810, 819, 408, 494, 817, 812, 643, + 899, 825, 829, 815, -1, -1, 822, -1, -1, -1, + -1, 821, -1, -1, -1, -1, -1, -1, 827, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 546, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 565, -1, 567, -1, 569, - -1, -1, -1, -1, 565, -1, 567, -1, 569, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 797, 798, - -1, -1, -1, -1, -1, 804, 805, -1, -1, -1, - -1, 810, -1, 812, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 575, -1, 577, -1, 579, + -1, -1, -1, -1, -1, -1, -1, 575, -1, 577, + -1, 579, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 622, -1, -1, -1, -1, -1, -1, -1, - -1, 622, 632, -1, -1, -1, -1, -1, -1, -1, - 640, 632, -1, -1, -1, -1, -1, -1, -1, 640, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 633, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 643, -1, 633, -1, -1, -1, -1, + -1, 651, -1, -1, -1, 643, -1, -1, -1, -1, + -1, -1, -1, 651, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 708, -1, - -1, -1, -1, -1, -1, -1, -1, 708, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 736, -1, -1, -1, - 740, -1, -1, -1, -1, 736, -1, -1, -1, 740, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 725, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 725, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 778, -1, - -1, -1, -1, -1, -1, -1, -1, 778, -1, -1, + -1, -1, -1, 753, -1, -1, -1, 757, -1, -1, + -1, -1, -1, -1, -1, 753, -1, -1, -1, 757, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 795, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 795, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 841, 842, -1, 844, -1, 844, -1, -1, -1, - 841, 842, -1, 844, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 858, 859, + -1, 861, -1, 861, -1, -1, -1, -1, -1, -1, + 858, 859, -1, 861, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 882, -1, -1, -1, -1, -1, -1, -1, - -1, 882, -1, -1, -1, -1, -1, -1, 898, -1, - -1, -1, -1, -1, -1, 905, -1, 898, -1, -1, - -1, -1, -1, -1, 905, 915, -1, -1, -1, 919, - -1, -1, -1, -1, 915, 925, -1, -1, 919, -1, - -1, -1, 0, -1, 925, 3, 4, 5, 6, 7, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 899, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 899, -1, -1, -1, 915, -1, -1, -1, -1, + -1, -1, 922, -1, -1, -1, -1, 915, -1, -1, + -1, -1, 932, -1, 922, -1, 936, -1, -1, -1, + -1, -1, 942, -1, 932, -1, -1, -1, 936, -1, + -1, -1, 0, -1, 942, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, @@ -3060,20 +3065,21 @@ static const yytype_int16 yycheck[] = 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 351, -1, -1, -1, -1, -1, -1, - -1, 359, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 373, 374, 375, 376, 377, - -1, -1, -1, -1, -1, -1, -1, -1, 386, 387, - 388, 389, 390, 391, 392, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 357, + -1, -1, -1, -1, -1, -1, -1, 365, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 408, 409, 410, 411, 412, 413, -1, -1, -1, -1, - -1, -1, -1, -1, 422, -1, 424, 425, 426, 427, - 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, + -1, 379, 380, 381, 382, 383, -1, -1, -1, -1, + -1, -1, -1, -1, 392, 393, 394, 395, 396, 397, + 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 414, 415, 416, 417, + 418, 419, 420, -1, -1, -1, -1, -1, -1, -1, + -1, 429, -1, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 450, 451, 452, 453, 454, 3, 4, 5, + 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, @@ -3106,19 +3112,20 @@ static const yytype_int16 yycheck[] = 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, - 326, -1, -1, 329, 330, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 348, 349, -1, 351, -1, 353, 354, -1, - -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 373, 374, 375, - 376, 377, -1, -1, -1, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, - 396, -1, 398, 399, 400, 401, 402, 403, 404, 405, + 326, 327, 328, 329, 330, 331, 332, -1, -1, 335, + 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 354, 355, + -1, 357, -1, 359, 360, -1, -1, -1, -1, 365, + 366, 367, 368, 369, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 379, 380, 381, 382, 383, -1, -1, + -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 3, + 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, @@ -3151,20 +3158,21 @@ static const yytype_int16 yycheck[] = 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, - 324, 325, 326, -1, -1, 329, 330, -1, -1, -1, + 324, 325, 326, 327, 328, 329, 330, 331, 332, -1, + -1, 335, 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 348, 349, -1, 351, -1, 353, - 354, -1, -1, -1, -1, 359, 360, 361, 362, 363, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 373, - 374, 375, 376, 377, -1, -1, -1, 381, 382, 383, - 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, - 394, 395, 396, -1, 398, 399, 400, 401, 402, 403, + 354, 355, -1, 357, -1, 359, 360, -1, -1, -1, + -1, 365, 366, 367, 368, 369, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 379, 380, 381, 382, 383, + -1, -1, -1, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, - 454, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, @@ -3196,20 +3204,21 @@ static const yytype_int16 yycheck[] = 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 325, 326, -1, -1, 329, 330, -1, + 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, + 332, -1, -1, 335, 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 348, 349, -1, 351, - -1, 353, -1, -1, -1, -1, -1, 359, 360, 361, - 362, 363, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 373, 374, 375, 376, 377, -1, -1, -1, 381, - 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, - 392, 393, 394, 395, 396, -1, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, + -1, -1, 354, 355, -1, 357, -1, 359, -1, -1, + -1, -1, -1, 365, 366, 367, 368, 369, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 379, 380, 381, + 382, 383, -1, -1, -1, 387, 388, 389, 390, 391, + 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, + 402, -1, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, - 452, 453, 454, 3, 4, 5, 6, 7, 8, 9, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, @@ -3241,20 +3250,21 @@ static const yytype_int16 yycheck[] = 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, - 320, 321, 322, 323, 324, 325, 326, -1, -1, 329, - 330, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 348, 349, - -1, 351, -1, 353, -1, -1, -1, -1, -1, 359, - 360, 361, 362, 363, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 373, 374, 375, 376, 377, -1, -1, - -1, 381, 382, 383, 384, 385, 386, 387, 388, 389, - 390, 391, 392, 393, 394, 395, 396, -1, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, + 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, + 330, 331, 332, -1, -1, 335, 336, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 354, 355, -1, 357, -1, 359, + -1, -1, -1, -1, -1, 365, 366, 367, 368, 369, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 379, + 380, 381, 382, 383, -1, -1, -1, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, + 400, 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, - 450, 451, 452, 453, 454, 3, 4, 5, 6, 7, + 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, @@ -3286,20 +3296,21 @@ static const yytype_int16 yycheck[] = 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, - 318, 319, 320, 321, 322, 323, 324, 325, 326, -1, - -1, 329, 330, -1, -1, -1, -1, -1, -1, -1, + 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, -1, -1, 335, 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 348, 349, -1, 351, -1, -1, -1, -1, -1, -1, - -1, 359, 360, 361, 362, 363, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 373, 374, 375, 376, 377, - -1, -1, -1, 381, 382, 383, 384, 385, 386, 387, - 388, 389, 390, 391, 392, 393, 394, 395, 396, -1, - 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, + -1, -1, -1, -1, -1, -1, 354, 355, -1, 357, + -1, -1, -1, -1, -1, -1, -1, 365, 366, 367, + 368, 369, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 379, 380, 381, 382, 383, -1, -1, -1, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, -1, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 450, 451, 452, 453, 454, 3, 4, 5, + 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, @@ -3332,19 +3343,20 @@ static const yytype_int16 yycheck[] = 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, - 326, -1, -1, 329, 330, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 348, 349, -1, 351, -1, -1, -1, -1, - -1, -1, -1, 359, 360, 361, 362, 363, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 373, 374, 375, - 376, 377, -1, -1, -1, 381, 382, 383, 384, 385, - 386, 387, 388, 389, 390, 391, 392, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 408, 409, 410, 411, 412, 413, 414, 415, - 416, 417, 418, 419, 420, 421, 422, -1, 424, 425, - 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, + 326, 327, 328, 329, 330, 331, 332, -1, -1, 335, + 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 354, 355, + -1, 357, -1, -1, -1, -1, -1, -1, -1, 365, + 366, 367, 368, 369, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 379, 380, 381, 382, 383, -1, -1, + -1, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, 428, 429, -1, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 3, + 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, @@ -3376,21 +3388,22 @@ static const yytype_int16 yycheck[] = 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, -1, -1, -1, 320, 321, 322, 323, - 324, 325, 326, -1, -1, 329, 330, -1, -1, -1, + 314, 315, 316, 317, 318, 319, -1, -1, -1, 323, + 324, 325, 326, 327, 328, 329, 330, 331, 332, -1, + -1, 335, 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 348, 349, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 360, 361, 362, 363, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 373, - 374, 375, 376, -1, -1, -1, -1, 381, 382, 383, - 384, 385, 386, 387, 388, 389, 390, 391, 392, -1, + 354, 355, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 366, 367, 368, 369, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 379, 380, 381, 382, -1, + -1, -1, -1, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 408, 409, 410, 411, 412, 413, - 414, 415, 416, 417, 418, 419, 420, 421, 422, -1, - 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, + 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, + 424, 425, 426, 427, 428, 429, -1, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, - 454, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, @@ -3422,20 +3435,21 @@ static const yytype_int16 yycheck[] = 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 325, 326, -1, -1, -1, -1, -1, + 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, + 332, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 351, - -1, -1, -1, -1, -1, -1, -1, 359, -1, -1, + -1, -1, -1, -1, -1, 357, -1, -1, -1, -1, + -1, -1, -1, 365, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 379, 380, 381, + 382, 383, -1, -1, -1, -1, -1, -1, -1, -1, + 392, 393, 394, 395, 396, 397, 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 373, 374, 375, 376, 377, -1, -1, -1, -1, - -1, -1, -1, -1, 386, 387, 388, 389, 390, 391, - 392, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 408, 409, 410, 411, - 412, 413, -1, -1, -1, -1, -1, -1, -1, -1, - 422, -1, 424, 425, 426, 427, 428, 429, 430, 431, + -1, -1, 414, 415, 416, 417, 418, 419, 420, -1, + -1, -1, -1, -1, -1, -1, -1, 429, -1, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, - 452, 453, 454, 3, 4, 5, 6, 7, 8, 9, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, @@ -3466,21 +3480,22 @@ static const yytype_int16 yycheck[] = 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, -1, -1, -1, - 320, 321, 322, 323, 324, 325, 326, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, + -1, -1, -1, 323, 324, 325, 326, 327, 328, 329, + 330, 331, 332, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 373, 374, 375, 376, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 386, 387, 388, 389, - 390, 391, 392, 393, -1, -1, 396, -1, 398, 399, - -1, -1, 402, -1, -1, -1, -1, -1, 408, 409, - 410, 411, 412, 413, -1, -1, -1, -1, -1, -1, - -1, -1, 422, -1, 424, 425, 426, 427, 428, 429, - 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 379, + 380, 381, 382, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 392, 393, 394, 395, 396, 397, 398, 399, + -1, -1, 402, -1, 404, 405, -1, -1, 408, -1, + -1, -1, -1, -1, 414, 415, 416, 417, 418, 419, + 420, -1, -1, -1, -1, -1, -1, -1, -1, 429, + -1, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, - 450, 451, 452, 453, 454, 3, 4, 5, 6, 7, + 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, @@ -3511,21 +3526,22 @@ static const yytype_int16 yycheck[] = 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, -1, - -1, -1, 320, 321, 322, 323, 324, 325, 326, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, + 318, 319, -1, -1, -1, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 359, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 373, 374, 375, 376, -1, - -1, -1, -1, -1, -1, -1, -1, 385, 386, 387, - 388, 389, 390, 391, 392, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 365, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 408, 409, 410, 411, 412, 413, -1, -1, -1, -1, - -1, -1, -1, -1, 422, -1, 424, 425, 426, 427, - 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, + -1, 379, 380, 381, 382, -1, -1, -1, -1, -1, + -1, -1, -1, 391, 392, 393, 394, 395, 396, 397, + 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 414, 415, 416, 417, + 418, 419, 420, -1, -1, -1, -1, -1, -1, -1, + -1, 429, -1, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 450, 451, 452, 453, 454, 3, 4, 5, + 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, @@ -3557,20 +3573,21 @@ static const yytype_int16 yycheck[] = 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, -1, -1, -1, 320, 321, 322, 323, 324, 325, - 326, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 316, 317, 318, 319, -1, -1, -1, 323, 324, 325, + 326, 327, 328, 329, 330, 331, 332, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 351, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 373, 374, 375, - 376, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 386, 387, 388, 389, 390, 391, 392, -1, -1, -1, + -1, 357, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 408, 409, 410, 411, 412, 413, -1, -1, - -1, -1, -1, -1, -1, -1, 422, -1, 424, 425, - 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, + -1, -1, -1, 379, 380, 381, 382, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 392, 393, 394, 395, + 396, 397, 398, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 414, 415, + 416, 417, 418, 419, 420, -1, -1, -1, -1, -1, + -1, -1, -1, 429, -1, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, - 446, 447, 448, 449, 450, 451, 452, 453, 454, 3, + 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, @@ -3602,21 +3619,22 @@ static const yytype_int16 yycheck[] = 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, -1, -1, -1, 320, 321, 322, 323, - 324, 325, 326, -1, -1, -1, -1, -1, -1, -1, + 314, 315, 316, 317, 318, 319, -1, -1, -1, 323, + 324, 325, 326, 327, 328, 329, 330, 331, 332, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 354, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 373, - 374, 375, 376, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 386, 387, 388, 389, 390, 391, 392, -1, + -1, -1, -1, -1, -1, -1, 360, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 408, 409, 410, 411, 412, 413, - -1, -1, -1, -1, -1, -1, -1, -1, 422, -1, - 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, + -1, -1, -1, -1, -1, 379, 380, 381, 382, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 392, 393, + 394, 395, 396, 397, 398, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 414, 415, 416, 417, 418, 419, 420, -1, -1, -1, + -1, -1, -1, -1, -1, 429, -1, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, - 454, 3, 4, 5, 6, 7, 8, 9, 10, 11, + 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, + 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, @@ -3647,21 +3665,22 @@ static const yytype_int16 yycheck[] = 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, - 312, 313, 314, 315, 316, -1, -1, -1, 320, 321, - 322, 323, 324, 325, 326, -1, -1, -1, -1, -1, + 312, 313, 314, 315, 316, 317, 318, 319, -1, -1, + -1, 323, 324, 325, 326, 327, 328, 329, 330, 331, + 332, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 360, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 354, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 379, 380, 381, + 382, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 392, 393, 394, 395, 396, 397, 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 373, 374, 375, 376, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 386, 387, 388, 389, 390, 391, - 392, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 408, 409, 410, 411, - 412, 413, -1, -1, -1, -1, -1, -1, -1, -1, - 422, -1, 424, 425, 426, 427, 428, 429, 430, 431, + -1, -1, 414, 415, 416, 417, 418, 419, 420, -1, + -1, -1, -1, -1, -1, -1, -1, 429, -1, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, - 452, 453, 454, 3, 4, 5, 6, 7, 8, 9, + 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, + 462, 463, 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, @@ -3692,21 +3711,22 @@ static const yytype_int16 yycheck[] = 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, -1, -1, -1, - 320, 321, 322, 323, 324, 325, 326, -1, -1, -1, + 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, + -1, -1, -1, 323, 324, 325, 326, 327, 328, 329, + 330, 331, 332, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 354, -1, -1, -1, -1, -1, + 360, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 379, + 380, 381, 382, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 392, 393, 394, 395, 396, 397, 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 373, 374, 375, 376, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 386, 387, 388, 389, - 390, 391, 392, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 408, 409, - 410, 411, 412, 413, -1, -1, -1, -1, -1, -1, - -1, -1, 422, -1, 424, 425, 426, 427, 428, 429, - 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, + -1, -1, -1, -1, 414, 415, 416, 417, 418, 419, + 420, -1, -1, -1, -1, -1, -1, -1, -1, 429, + -1, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, - 450, 451, 452, 453, 454, 3, 4, 5, 6, 7, + 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, @@ -3737,21 +3757,154 @@ static const yytype_int16 yycheck[] = 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, -1, - -1, -1, 320, 321, 322, 323, 324, 325, 326, -1, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, + 318, 319, -1, -1, -1, 323, 324, 325, 326, 327, + 328, 329, 330, 331, 332, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 379, 380, 381, 382, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 392, 393, 394, 395, 396, 397, + 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 414, 415, 416, 417, + 418, 419, 420, -1, -1, -1, -1, -1, -1, -1, + -1, 429, -1, 431, 432, 433, 434, 435, 436, 437, + 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, + 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, -1, -1, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, -1, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, -1, -1, -1, -1, -1, -1, 326, + -1, -1, -1, 330, 331, 332, -1, -1, 335, 336, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 354, 355, -1, + -1, -1, 359, 360, -1, -1, -1, -1, -1, 366, + 367, 368, 369, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 387, 388, 389, 390, 391, 392, -1, -1, -1, -1, + 397, 398, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 421, 422, 423, 424, 425, 426, + 427, 428, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 443, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, -1, -1, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, -1, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, -1, -1, -1, -1, -1, -1, 326, + -1, -1, -1, 330, 331, 332, -1, -1, 335, 336, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 354, 355, -1, + -1, -1, 359, 360, -1, -1, -1, -1, -1, 366, + 367, 368, 369, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 387, 388, 389, 390, 391, 392, -1, -1, -1, -1, + 397, 398, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 421, 422, 423, 424, 425, 426, + 427, 428, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 443, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, -1, -1, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, -1, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, -1, -1, -1, -1, -1, -1, 326, + -1, -1, -1, 330, 331, 332, -1, -1, 335, 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 354, 355, -1, + -1, 358, -1, -1, -1, -1, -1, -1, -1, 366, + 367, 368, 369, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 373, 374, 375, 376, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 386, 387, - 388, 389, 390, 391, 392, -1, -1, -1, -1, -1, + 387, 388, 389, 390, 391, 392, -1, -1, -1, -1, + 397, 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 408, 409, 410, 411, 412, 413, -1, -1, -1, -1, - -1, -1, -1, -1, 422, -1, 424, 425, 426, 427, - 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, - 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 450, 451, 452, 453, 454, 4, 5, 6, + -1, -1, -1, -1, 421, 422, 423, 424, 425, 426, + 427, 428, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 443, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, @@ -3768,7 +3921,7 @@ static const yytype_int16 yycheck[] = 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, - 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, + 167, -1, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, @@ -3783,408 +3936,283 @@ static const yytype_int16 yycheck[] = 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, - -1, -1, -1, -1, -1, -1, 323, -1, -1, -1, - -1, -1, 329, 330, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 348, 349, -1, -1, -1, 353, 354, -1, -1, - -1, -1, -1, 360, 361, 362, 363, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 381, 382, 383, 384, 385, 386, - -1, -1, -1, -1, 391, 392, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 414, 415, 416, - 417, 418, 419, 420, 421, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 436, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, -1, -1, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, - 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, - 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, - 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, - 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, - 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, - 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, - 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, - 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, - 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, - 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, - 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, - 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, - 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, - 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, - 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, - 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, - 314, 315, 316, -1, -1, -1, -1, -1, -1, 323, - -1, -1, -1, -1, -1, 329, 330, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 348, 349, -1, -1, -1, 353, - 354, -1, -1, -1, -1, -1, 360, 361, 362, 363, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 381, 382, 383, - 384, 385, 386, -1, -1, -1, -1, 391, 392, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 414, 415, 416, 417, 418, 419, 420, 421, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 436, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, - -1, -1, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, - 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, - 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, - 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, - 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, - 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, - 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, - 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, - 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, - 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, - 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, - 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, - 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, - 311, 312, 313, 314, 315, 316, -1, -1, -1, -1, - -1, -1, 323, -1, -1, -1, -1, -1, 329, 330, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 348, 349, -1, - -1, 352, -1, -1, -1, -1, -1, -1, -1, 360, - 361, 362, 363, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 381, 382, 383, 384, 385, 386, -1, -1, -1, -1, - 391, 392, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 414, 415, 416, 417, 418, 419, 420, - 421, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 436, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, -1, -1, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, - 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, - 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, - 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, - 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, - 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, - 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, - 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, - 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, - 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, - 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, - 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, - 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, - 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, - 308, 309, 310, 311, 312, 313, 314, 315, 316, -1, - -1, -1, -1, -1, -1, 323, -1, -1, -1, -1, - -1, 329, 330, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 348, 349, -1, -1, -1, 353, -1, -1, -1, -1, - -1, -1, 360, 361, 362, 363, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 381, 382, 383, 384, 385, 386, -1, - -1, -1, -1, 391, 392, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 414, 415, 416, 417, - 418, 419, 420, 421, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 436, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, -1, -1, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, - 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, - 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, - 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, - 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, - 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, - 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, - 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, - 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, - 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, - 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, - 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, - 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, - 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, - 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, -1, -1, -1, -1, -1, -1, 323, -1, - -1, -1, -1, -1, 329, 330, -1, -1, -1, -1, + 317, 318, 319, -1, -1, -1, -1, -1, -1, 326, + -1, -1, -1, 330, 331, 332, -1, -1, 335, 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 348, 349, -1, -1, 352, -1, -1, - -1, -1, -1, -1, -1, 360, 361, 362, 363, -1, + -1, -1, -1, -1, -1, -1, -1, 354, 355, -1, + -1, -1, 359, -1, -1, -1, -1, -1, -1, 366, + 367, 368, 369, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 381, 382, 383, 384, - 385, 386, -1, -1, -1, -1, 391, 392, -1, -1, + 387, 388, 389, 390, 391, 392, -1, -1, -1, -1, + 397, 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 414, - 415, 416, 417, 418, 419, 420, 421, -1, -1, -1, + -1, -1, -1, -1, 421, 422, 423, 424, 425, 426, + 427, 428, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 443, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, -1, -1, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, -1, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, -1, -1, -1, -1, -1, -1, 326, + -1, -1, -1, 330, 331, 332, -1, -1, 335, 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 436, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, -1, - -1, 63, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, - 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, - 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, - 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, - 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, - 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, - 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, - 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, - 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, - 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, - 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, - 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, - 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, - 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, - 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, - 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, - 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, - 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, - 312, 313, 314, 315, 316, -1, -1, -1, -1, -1, - -1, 323, -1, -1, -1, -1, -1, 329, 330, -1, + -1, -1, -1, -1, -1, -1, -1, 354, 355, -1, + -1, 358, -1, -1, -1, -1, -1, -1, -1, 366, + 367, 368, 369, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 348, 349, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 359, 360, 361, - 362, 363, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 381, - 382, 383, 384, 385, 386, -1, -1, -1, -1, 391, - 392, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 387, 388, 389, 390, 391, 392, -1, -1, -1, -1, + 397, 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 414, 415, 416, 417, 418, 419, 420, 421, + -1, -1, -1, -1, 421, 422, 423, 424, 425, 426, + 427, 428, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 443, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, -1, -1, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, -1, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, -1, -1, -1, -1, -1, -1, 326, + -1, -1, -1, 330, 331, 332, -1, -1, 335, 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 436, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, - 59, 60, -1, -1, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, - 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, - 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, - 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, - 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, - 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, - 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, - 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, - 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, - 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, - 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, - 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, - 309, 310, 311, 312, 313, 314, 315, 316, -1, -1, - -1, -1, -1, -1, 323, -1, -1, -1, -1, -1, - 329, 330, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 348, - 349, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 360, 361, 362, 363, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 354, 355, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 365, 366, + 367, 368, 369, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 381, 382, 383, 384, 385, 386, -1, -1, - -1, -1, 391, 392, -1, -1, -1, -1, -1, -1, + 387, 388, 389, 390, 391, 392, -1, -1, -1, -1, + 397, 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 414, 415, 416, 417, 418, - 419, 420, 421, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 436, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, -1, -1, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, - 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, - 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, - 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, - 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, - 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, - 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, - 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, - 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, - 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, - 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, - 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, - 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, - 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, - 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, - 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, - 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, - 316, -1, -1, -1, -1, -1, -1, 323, -1, -1, - -1, -1, -1, 329, 330, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 421, 422, 423, 424, 425, 426, + 427, 428, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 443, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, -1, -1, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, -1, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, -1, -1, -1, -1, -1, -1, 326, + -1, -1, -1, 330, 331, 332, -1, -1, 335, 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 348, 349, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 360, 361, 362, 363, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 354, 355, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 366, + 367, 368, 369, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 381, 382, 383, 384, 385, - 386, -1, -1, -1, -1, 391, 392, -1, -1, -1, + 387, 388, 389, 390, 391, 392, -1, -1, -1, -1, + 397, 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 414, 415, - 416, 417, 418, 419, 420, 421, -1, -1, -1, -1, + -1, -1, -1, -1, 421, 422, 423, 424, 425, 426, + 427, 428, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 443, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, -1, -1, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, -1, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, -1, -1, -1, -1, -1, -1, 326, + -1, -1, -1, 330, 331, 332, -1, -1, 335, 336, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 354, 355, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 366, + 367, 368, 369, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 436, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, -1, -1, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, - 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, - 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, - 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, - 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, - 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, - 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, - 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, - 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, - 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, - 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, - 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, - 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, - 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, - 313, 314, 315, 316, -1, -1, -1, -1, -1, -1, - 323, -1, -1, -1, -1, -1, 329, 330, -1, -1, + 387, 388, 389, 390, 391, 392, -1, -1, -1, -1, + 397, 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 348, 349, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 360, 361, 362, - 363, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 381, 382, - 383, 384, 385, 386, -1, -1, -1, -1, 391, 392, + -1, -1, -1, -1, 421, 422, 423, 424, 425, 426, + 427, 428, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 443, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, -1, -1, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, -1, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, -1, -1, -1, -1, -1, -1, 326, + -1, -1, -1, 330, 331, 332, -1, -1, 335, 336, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 354, 355, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 366, + 367, 368, 369, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 414, 415, 416, 417, 418, 419, 420, 421, -1, + 387, 388, 389, 390, 391, 392, -1, -1, -1, -1, + 397, 398, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 436, 4, 5, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, -1, -1, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, - 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, - 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, - 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, - 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, - 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, - 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, - 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, - 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, - 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, - 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, - 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, - 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, - 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, - 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, - 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, - 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, - 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, - 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, - 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, - 310, 311, 312, 313, 314, 315, 316, -1, -1, -1, - -1, -1, -1, 323, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 421, 422, 423, 424, 425, 426, + 427, 428, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 443, 4, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, -1, -1, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, + 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, + 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, + 167, -1, 169, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, + 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, + 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, + 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, + 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, + 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, + 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, + 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, + 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, + 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, + 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, + 317, 318, 319, -1, -1, -1, -1, -1, -1, 326, + -1, -1, -1, 330, 331, 332, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 386, -1, -1, -1, - -1, 391, 392 + -1, -1, -1, -1, -1, 392, -1, -1, -1, -1, + 397, 398 }; - /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ +/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of + state STATE-NUM. */ static const yytype_int16 yystos[] = { 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, @@ -4219,144 +4247,148 @@ static const yytype_int16 yystos[] = 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, - 322, 323, 324, 325, 326, 351, 359, 373, 374, 375, - 376, 377, 386, 387, 388, 389, 390, 391, 392, 408, - 409, 410, 411, 412, 413, 422, 424, 425, 426, 427, - 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, + 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, + 332, 357, 365, 379, 380, 381, 382, 383, 392, 393, + 394, 395, 396, 397, 398, 414, 415, 416, 417, 418, + 419, 420, 429, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, - 448, 449, 450, 451, 452, 453, 454, 486, 487, 490, - 491, 492, 493, 497, 498, 499, 500, 501, 502, 505, - 506, 507, 508, 509, 511, 516, 517, 518, 559, 560, - 561, 563, 570, 574, 575, 580, 583, 349, 349, 349, - 349, 349, 349, 349, 349, 351, 517, 353, 385, 349, - 349, 359, 385, 359, 562, 350, 356, 494, 495, 496, - 506, 511, 356, 359, 385, 359, 385, 507, 511, 367, - 513, 514, 0, 560, 491, 499, 506, 359, 490, 385, - 566, 567, 584, 585, 382, 385, 566, 382, 566, 382, - 566, 382, 566, 382, 566, 566, 584, 382, 566, 385, - 564, 565, 511, 520, 353, 385, 409, 503, 504, 385, - 510, 351, 359, 512, 353, 538, 563, 495, 494, 496, - 385, 385, 349, 358, 512, 353, 356, 359, 489, 329, - 330, 348, 349, 360, 361, 362, 363, 381, 382, 383, - 384, 385, 414, 415, 416, 417, 418, 419, 420, 421, - 456, 457, 458, 460, 461, 462, 463, 464, 465, 466, - 467, 468, 509, 511, 515, 512, 350, 385, 359, 358, - 356, 350, 356, 350, 356, 358, 356, 356, 356, 350, - 356, 356, 356, 356, 356, 356, 356, 350, 356, 350, - 356, 349, 352, 356, 359, 506, 511, 521, 522, 519, - 358, 350, 356, 350, 356, 352, 467, 469, 470, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 351, - 359, 353, 354, 359, 393, 394, 395, 396, 398, 399, - 400, 401, 402, 403, 404, 405, 406, 407, 423, 467, - 480, 482, 484, 486, 490, 509, 511, 527, 528, 529, - 530, 531, 539, 540, 541, 542, 545, 546, 549, 550, - 551, 558, 563, 512, 358, 512, 353, 482, 525, 358, - 488, 385, 356, 359, 467, 467, 484, 329, 330, 351, - 355, 350, 350, 356, 392, 482, 349, 467, 356, 368, - 563, 348, 351, 382, 567, 584, 385, 585, 348, 381, - 382, 383, 384, 571, 572, 382, 480, 485, 573, 382, - 381, 382, 383, 384, 576, 577, 382, 485, 578, 382, - 348, 579, 382, 584, 385, 485, 581, 582, 382, 485, - 352, 565, 511, 385, 523, 524, 354, 522, 521, 485, - 504, 385, 364, 365, 366, 361, 363, 327, 328, 331, - 332, 367, 368, 333, 334, 371, 370, 369, 335, 337, - 336, 372, 352, 352, 480, 354, 532, 349, 359, 359, - 553, 349, 349, 359, 359, 484, 349, 484, 357, 359, - 359, 359, 359, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 358, 483, 356, 359, 354, 528, 542, - 546, 551, 525, 358, 354, 525, 526, 525, 521, 385, - 350, 459, 484, 385, 482, 467, 348, 382, 568, 569, - 350, 358, 350, 356, 350, 356, 350, 356, 356, 350, - 356, 350, 356, 350, 356, 356, 350, 356, 356, 350, - 356, 350, 356, 350, 350, 523, 512, 356, 359, 354, - 467, 467, 467, 469, 469, 470, 470, 471, 471, 471, - 471, 472, 472, 473, 474, 475, 476, 477, 478, 481, - 352, 539, 552, 528, 554, 484, 359, 484, 357, 482, - 482, 525, 354, 356, 354, 352, 352, 356, 352, 356, - 572, 571, 485, 573, 577, 576, 485, 578, 348, 579, - 581, 582, 359, 524, 484, 533, 484, 499, 544, 393, - 527, 540, 555, 350, 350, 354, 525, 348, 382, 350, - 350, 350, 350, 350, 350, 357, 354, 385, 350, 349, - 544, 556, 557, 535, 536, 537, 543, 547, 482, 358, - 529, 534, 538, 484, 359, 350, 397, 531, 529, 353, - 525, 350, 484, 534, 535, 539, 548, 359, 354 + 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, + 458, 459, 460, 461, 462, 463, 464, 496, 497, 500, + 501, 502, 503, 507, 508, 509, 510, 511, 512, 515, + 516, 517, 518, 519, 521, 526, 527, 528, 569, 570, + 571, 573, 580, 584, 585, 591, 594, 355, 355, 355, + 355, 355, 355, 355, 355, 357, 527, 359, 391, 355, + 355, 365, 391, 365, 572, 356, 362, 504, 505, 506, + 516, 521, 362, 365, 391, 365, 391, 517, 521, 373, + 523, 524, 0, 570, 501, 509, 516, 365, 500, 391, + 576, 577, 595, 596, 388, 391, 576, 388, 576, 388, + 576, 388, 576, 388, 576, 576, 595, 388, 576, 391, + 574, 575, 521, 530, 359, 391, 415, 513, 514, 391, + 520, 357, 365, 522, 359, 548, 573, 505, 504, 506, + 391, 391, 355, 364, 522, 359, 362, 365, 499, 335, + 336, 354, 355, 366, 367, 368, 369, 387, 388, 389, + 390, 391, 421, 422, 423, 424, 425, 426, 427, 428, + 466, 467, 468, 470, 471, 472, 473, 474, 475, 476, + 477, 478, 519, 521, 525, 522, 356, 391, 365, 364, + 362, 356, 362, 356, 362, 364, 362, 362, 362, 356, + 362, 362, 362, 362, 362, 362, 362, 356, 362, 356, + 362, 355, 358, 362, 365, 516, 521, 531, 532, 529, + 364, 356, 362, 356, 362, 358, 477, 479, 480, 481, + 482, 483, 484, 485, 486, 487, 488, 489, 490, 521, + 357, 365, 359, 360, 365, 399, 400, 401, 402, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 430, + 477, 490, 492, 494, 496, 500, 519, 521, 537, 538, + 539, 540, 541, 549, 550, 551, 552, 555, 556, 559, + 560, 561, 568, 573, 522, 364, 522, 359, 492, 535, + 364, 498, 391, 362, 365, 477, 477, 494, 335, 336, + 357, 361, 356, 356, 362, 398, 492, 355, 477, 362, + 374, 573, 354, 357, 388, 577, 595, 391, 596, 354, + 387, 388, 389, 390, 581, 582, 388, 490, 495, 583, + 388, 387, 388, 389, 390, 586, 587, 388, 387, 388, + 389, 390, 466, 588, 589, 388, 354, 590, 388, 595, + 391, 495, 526, 592, 593, 388, 495, 358, 575, 521, + 391, 533, 534, 360, 532, 531, 495, 514, 391, 370, + 371, 372, 367, 369, 333, 334, 337, 338, 373, 374, + 339, 340, 377, 376, 375, 341, 343, 342, 378, 358, + 358, 490, 360, 542, 355, 365, 365, 563, 355, 355, + 365, 365, 494, 355, 494, 363, 365, 365, 365, 365, + 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, + 364, 493, 362, 365, 360, 538, 552, 556, 561, 535, + 364, 360, 535, 536, 535, 531, 391, 356, 469, 494, + 391, 492, 477, 354, 388, 578, 579, 356, 364, 356, + 362, 356, 362, 356, 362, 362, 356, 362, 356, 362, + 356, 362, 362, 356, 362, 362, 356, 362, 356, 362, + 356, 356, 533, 522, 362, 365, 360, 477, 477, 477, + 479, 479, 480, 480, 481, 481, 481, 481, 482, 482, + 483, 484, 485, 486, 487, 488, 491, 358, 549, 562, + 538, 564, 494, 365, 494, 363, 492, 492, 535, 360, + 362, 360, 358, 358, 362, 358, 362, 582, 581, 495, + 583, 587, 586, 589, 588, 354, 590, 592, 593, 365, + 534, 494, 543, 494, 509, 554, 399, 537, 550, 565, + 356, 356, 360, 535, 354, 388, 356, 356, 356, 356, + 356, 356, 363, 360, 391, 356, 355, 554, 566, 567, + 545, 546, 547, 553, 557, 492, 364, 539, 544, 548, + 494, 365, 356, 403, 541, 539, 359, 535, 356, 494, + 544, 545, 549, 558, 365, 360 }; - /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */ static const yytype_int16 yyr1[] = { - 0, 455, 456, 457, 457, 457, 457, 457, 457, 457, - 457, 457, 457, 457, 457, 457, 457, 457, 458, 458, - 458, 458, 458, 458, 459, 460, 461, 462, 462, 463, - 463, 464, 464, 465, 466, 466, 466, 467, 467, 467, - 467, 468, 468, 468, 468, 469, 469, 469, 469, 470, - 470, 470, 471, 471, 471, 472, 472, 472, 472, 472, - 473, 473, 473, 474, 474, 475, 475, 476, 476, 477, - 477, 478, 478, 479, 479, 480, 481, 480, 482, 482, - 483, 483, 483, 483, 483, 483, 483, 483, 483, 483, - 483, 484, 484, 485, 486, 486, 486, 486, 486, 486, - 486, 486, 486, 486, 486, 488, 487, 489, 489, 490, - 490, 490, 490, 491, 491, 492, 492, 493, 494, 494, - 495, 495, 495, 495, 496, 497, 497, 497, 497, 497, - 498, 498, 498, 498, 498, 499, 499, 500, 501, 501, - 501, 501, 501, 501, 501, 501, 502, 503, 503, 504, - 504, 504, 505, 506, 506, 507, 507, 507, 507, 507, - 507, 507, 507, 507, 507, 507, 508, 508, 508, 508, - 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, - 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, - 508, 508, 508, 508, 508, 508, 508, 508, 508, 508, - 508, 509, 510, 510, 511, 511, 512, 512, 512, 512, - 513, 513, 514, 515, 515, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 516, 516, 516, 516, 516, 516, 516, 516, 516, 516, - 517, 517, 517, 519, 518, 520, 518, 521, 521, 522, - 522, 523, 523, 524, 524, 525, 525, 525, 525, 526, - 526, 527, 528, 528, 529, 529, 529, 529, 529, 529, - 529, 529, 530, 531, 532, 533, 531, 534, 534, 536, - 535, 537, 535, 538, 538, 539, 539, 540, 540, 541, - 541, 542, 543, 543, 544, 544, 545, 545, 547, 546, - 548, 548, 549, 549, 550, 550, 552, 551, 553, 551, - 554, 551, 555, 555, 556, 556, 557, 557, 558, 558, - 558, 558, 558, 558, 558, 558, 559, 559, 560, 560, - 560, 562, 561, 563, 564, 564, 565, 565, 566, 566, - 567, 567, 568, 568, 569, 569, 570, 570, 570, 570, - 570, 570, 571, 571, 572, 572, 572, 572, 572, 573, - 573, 574, 574, 575, 575, 575, 575, 575, 575, 575, - 575, 576, 576, 577, 577, 577, 577, 578, 578, 579, - 579, 580, 580, 580, 580, 581, 581, 582, 583, 583, - 584, 584, 585, 585 + 0, 465, 466, 467, 467, 467, 467, 467, 467, 467, + 467, 467, 467, 467, 467, 467, 467, 467, 468, 468, + 468, 468, 468, 468, 469, 470, 471, 472, 472, 473, + 473, 474, 474, 475, 476, 476, 476, 477, 477, 477, + 477, 478, 478, 478, 478, 479, 479, 479, 479, 480, + 480, 480, 481, 481, 481, 482, 482, 482, 482, 482, + 483, 483, 483, 484, 484, 485, 485, 486, 486, 487, + 487, 488, 488, 489, 489, 490, 491, 490, 492, 492, + 493, 493, 493, 493, 493, 493, 493, 493, 493, 493, + 493, 494, 494, 495, 496, 496, 496, 496, 496, 496, + 496, 496, 496, 496, 496, 498, 497, 499, 499, 500, + 500, 500, 500, 501, 501, 502, 502, 503, 504, 504, + 505, 505, 505, 505, 506, 507, 507, 507, 507, 507, + 508, 508, 508, 508, 508, 509, 509, 510, 511, 511, + 511, 511, 511, 511, 511, 511, 511, 511, 512, 513, + 513, 514, 514, 514, 515, 516, 516, 517, 517, 517, + 517, 517, 517, 517, 517, 517, 517, 517, 518, 518, + 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, + 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, + 518, 518, 518, 518, 518, 518, 518, 518, 518, 518, + 518, 518, 518, 518, 518, 518, 519, 520, 520, 521, + 521, 522, 522, 522, 522, 523, 523, 524, 525, 525, + 525, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 526, 526, 526, 526, 526, 526, 526, 526, 526, + 526, 527, 527, 527, 529, 528, 530, 528, 531, 531, + 532, 532, 533, 533, 534, 534, 535, 535, 535, 535, + 536, 536, 537, 538, 538, 539, 539, 539, 539, 539, + 539, 539, 539, 540, 541, 542, 543, 541, 544, 544, + 546, 545, 547, 545, 548, 548, 549, 549, 550, 550, + 551, 551, 552, 553, 553, 554, 554, 555, 555, 557, + 556, 558, 558, 559, 559, 560, 560, 562, 561, 563, + 561, 564, 561, 565, 565, 566, 566, 567, 567, 568, + 568, 568, 568, 568, 568, 568, 568, 569, 569, 570, + 570, 570, 572, 571, 573, 574, 574, 575, 575, 576, + 576, 577, 577, 578, 578, 579, 579, 580, 580, 580, + 580, 580, 580, 581, 581, 582, 582, 582, 582, 582, + 583, 583, 584, 584, 585, 585, 585, 585, 585, 585, + 585, 585, 586, 586, 587, 587, 587, 587, 588, 588, + 589, 589, 589, 589, 589, 590, 590, 591, 591, 591, + 591, 592, 592, 593, 593, 594, 594, 595, 595, 596, + 596 }; - /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */ static const yytype_int8 yyr2[] = { 0, 2, 1, 1, 3, 1, 1, 1, 1, 1, @@ -4373,14 +4405,15 @@ static const yytype_int8 yyr2[] = 3, 3, 4, 1, 1, 2, 3, 3, 2, 3, 2, 1, 2, 1, 1, 1, 3, 4, 6, 5, 1, 2, 3, 5, 4, 1, 2, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 4, 1, 3, 1, - 3, 1, 1, 1, 2, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, + 3, 1, 3, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 4, 1, 1, 3, 2, 3, 2, 3, 3, 4, - 1, 0, 3, 1, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 4, 1, 1, 1, 3, 2, + 3, 2, 3, 3, 4, 1, 0, 3, 1, 1, + 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -4412,22 +4445,23 @@ static const yytype_int8 yyr2[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 6, 0, 5, 1, 2, 3, - 4, 1, 3, 1, 2, 1, 3, 4, 2, 1, - 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 0, 0, 5, 1, 1, 0, - 2, 0, 2, 2, 3, 1, 2, 1, 2, 1, - 2, 5, 3, 1, 1, 4, 1, 2, 0, 8, - 0, 1, 3, 2, 1, 2, 0, 6, 0, 8, - 0, 7, 1, 1, 1, 0, 2, 3, 2, 2, - 2, 3, 2, 2, 2, 2, 1, 2, 1, 1, - 1, 0, 3, 5, 1, 3, 1, 4, 1, 3, - 5, 5, 1, 3, 1, 3, 4, 6, 6, 8, - 6, 8, 1, 3, 1, 1, 1, 1, 1, 1, - 3, 4, 6, 4, 6, 6, 8, 6, 8, 6, - 8, 1, 3, 1, 1, 1, 1, 1, 3, 1, - 3, 6, 8, 4, 6, 1, 3, 1, 4, 6, - 1, 3, 3, 3 + 1, 1, 1, 1, 0, 6, 0, 5, 1, 2, + 3, 4, 1, 3, 1, 2, 1, 3, 4, 2, + 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 2, 0, 0, 5, 1, 1, + 0, 2, 0, 2, 2, 3, 1, 2, 1, 2, + 1, 2, 5, 3, 1, 1, 4, 1, 2, 0, + 8, 0, 1, 3, 2, 1, 2, 0, 6, 0, + 8, 0, 7, 1, 1, 1, 0, 2, 3, 2, + 2, 2, 3, 2, 2, 2, 2, 1, 2, 1, + 1, 1, 0, 3, 5, 1, 3, 1, 4, 1, + 3, 5, 5, 1, 3, 1, 3, 4, 6, 6, + 8, 6, 8, 1, 3, 1, 1, 1, 1, 1, + 1, 3, 4, 6, 4, 6, 6, 8, 6, 8, + 6, 8, 1, 3, 1, 1, 1, 1, 1, 3, + 1, 1, 1, 1, 1, 1, 3, 6, 8, 4, + 6, 1, 3, 1, 1, 4, 6, 1, 3, 3, + 3 }; @@ -4439,6 +4473,7 @@ enum { YYENOMEM = -2 }; #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrorlab +#define YYNOMEM goto yyexhaustedlab #define YYRECOVERING() (!!yyerrstatus) @@ -4479,10 +4514,7 @@ do { \ YYFPRINTF Args; \ } while (0) -/* This macro is provided for backward compatibility. */ -# ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif + # define YY_SYMBOL_PRINT(Title, Kind, Value, Location) \ @@ -4506,16 +4538,12 @@ yy_symbol_value_print (FILE *yyo, yysymbol_kind_t yykind, YYSTYPE const * const yyvaluep, glslang::TParseContext* pParseContext) { FILE *yyoutput = yyo; - YYUSE (yyoutput); - YYUSE (pParseContext); + YY_USE (yyoutput); + YY_USE (pParseContext); if (!yyvaluep) return; -# ifdef YYPRINT - if (yykind < YYNTOKENS) - YYPRINT (yyo, yytoknum[yykind], *yyvaluep); -# endif YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -4896,14 +4924,14 @@ static void yydestruct (const char *yymsg, yysymbol_kind_t yykind, YYSTYPE *yyvaluep, glslang::TParseContext* pParseContext) { - YYUSE (yyvaluep); - YYUSE (pParseContext); + YY_USE (yyvaluep); + YY_USE (pParseContext); if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yykind, yyvaluep, yylocationp); YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN - YYUSE (yykind); + YY_USE (yykind); YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -4975,6 +5003,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); YYDPRINTF ((stderr, "Starting parse\n")); yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; @@ -5000,7 +5029,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); if (yyss + yystacksize - 1 <= yyssp) #if !defined yyoverflow && !defined YYSTACK_RELOCATE - goto yyexhaustedlab; + YYNOMEM; #else { /* Get the current used size of the three stacks, in elements. */ @@ -5028,7 +5057,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); # else /* defined YYSTACK_RELOCATE */ /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; + YYNOMEM; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; @@ -5039,7 +5068,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); YY_CAST (union yyalloc *, YYSTACK_ALLOC (YY_CAST (YYSIZE_T, YYSTACK_BYTES (yystacksize)))); if (! yyptr) - goto yyexhaustedlab; + YYNOMEM; YYSTACK_RELOCATE (yyss_alloc, yyss); YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE @@ -5061,6 +5090,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } #endif /* !defined yyoverflow && !defined YYSTACK_RELOCATE */ + if (yystate == YYFINAL) YYACCEPT; @@ -5173,302 +5203,325 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); switch (yyn) { case 2: /* variable_identifier: IDENTIFIER */ -#line 392 "MachineIndependent/glslang.y" +#line 355 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleVariable((yyvsp[0].lex).loc, (yyvsp[0].lex).symbol, (yyvsp[0].lex).string); } -#line 5181 "MachineIndependent/glslang_tab.cpp" +#line 5211 "MachineIndependent/glslang_tab.cpp" break; case 3: /* primary_expression: variable_identifier */ -#line 398 "MachineIndependent/glslang.y" +#line 361 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5189 "MachineIndependent/glslang_tab.cpp" +#line 5219 "MachineIndependent/glslang_tab.cpp" break; case 4: /* primary_expression: LEFT_PAREN expression RIGHT_PAREN */ -#line 401 "MachineIndependent/glslang.y" +#line 364 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode); if ((yyval.interm.intermTypedNode)->getAsConstantUnion()) (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); } -#line 5199 "MachineIndependent/glslang_tab.cpp" +#line 5229 "MachineIndependent/glslang_tab.cpp" break; case 5: /* primary_expression: FLOATCONSTANT */ -#line 406 "MachineIndependent/glslang.y" +#line 369 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); } -#line 5207 "MachineIndependent/glslang_tab.cpp" +#line 5237 "MachineIndependent/glslang_tab.cpp" break; case 6: /* primary_expression: INTCONSTANT */ -#line 409 "MachineIndependent/glslang.y" +#line 372 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); } -#line 5215 "MachineIndependent/glslang_tab.cpp" +#line 5245 "MachineIndependent/glslang_tab.cpp" break; case 7: /* primary_expression: UINTCONSTANT */ -#line 412 "MachineIndependent/glslang.y" +#line 375 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); } -#line 5224 "MachineIndependent/glslang_tab.cpp" +#line 5254 "MachineIndependent/glslang_tab.cpp" break; case 8: /* primary_expression: BOOLCONSTANT */ -#line 416 "MachineIndependent/glslang.y" +#line 379 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); } -#line 5232 "MachineIndependent/glslang_tab.cpp" +#line 5262 "MachineIndependent/glslang_tab.cpp" break; case 9: /* primary_expression: STRING_LITERAL */ -#line 420 "MachineIndependent/glslang.y" +#line 382 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true); } -#line 5240 "MachineIndependent/glslang_tab.cpp" +#line 5270 "MachineIndependent/glslang_tab.cpp" break; case 10: /* primary_expression: INT32CONSTANT */ -#line 423 "MachineIndependent/glslang.y" +#line 385 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); } -#line 5249 "MachineIndependent/glslang_tab.cpp" +#line 5279 "MachineIndependent/glslang_tab.cpp" break; case 11: /* primary_expression: UINT32CONSTANT */ -#line 427 "MachineIndependent/glslang.y" +#line 389 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); } -#line 5258 "MachineIndependent/glslang_tab.cpp" +#line 5288 "MachineIndependent/glslang_tab.cpp" break; case 12: /* primary_expression: INT64CONSTANT */ -#line 431 "MachineIndependent/glslang.y" +#line 393 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i64, (yyvsp[0].lex).loc, true); } -#line 5267 "MachineIndependent/glslang_tab.cpp" +#line 5297 "MachineIndependent/glslang_tab.cpp" break; case 13: /* primary_expression: UINT64CONSTANT */ -#line 435 "MachineIndependent/glslang.y" +#line 397 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u64, (yyvsp[0].lex).loc, true); } -#line 5276 "MachineIndependent/glslang_tab.cpp" +#line 5306 "MachineIndependent/glslang_tab.cpp" break; case 14: /* primary_expression: INT16CONSTANT */ -#line 439 "MachineIndependent/glslang.y" +#line 401 "MachineIndependent/glslang.y" { parseContext.explicitInt16Check((yyvsp[0].lex).loc, "16-bit integer literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((short)(yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); } -#line 5285 "MachineIndependent/glslang_tab.cpp" +#line 5315 "MachineIndependent/glslang_tab.cpp" break; case 15: /* primary_expression: UINT16CONSTANT */ -#line 443 "MachineIndependent/glslang.y" +#line 405 "MachineIndependent/glslang.y" { parseContext.explicitInt16Check((yyvsp[0].lex).loc, "16-bit unsigned integer literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((unsigned short)(yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); } -#line 5294 "MachineIndependent/glslang_tab.cpp" +#line 5324 "MachineIndependent/glslang_tab.cpp" break; case 16: /* primary_expression: DOUBLECONSTANT */ -#line 447 "MachineIndependent/glslang.y" +#line 409 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double literal"); if (! parseContext.symbolTable.atBuiltInLevel()) parseContext.doubleCheck((yyvsp[0].lex).loc, "double literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtDouble, (yyvsp[0].lex).loc, true); } -#line 5305 "MachineIndependent/glslang_tab.cpp" +#line 5335 "MachineIndependent/glslang_tab.cpp" break; case 17: /* primary_expression: FLOAT16CONSTANT */ -#line 453 "MachineIndependent/glslang.y" +#line 415 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float literal"); (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat16, (yyvsp[0].lex).loc, true); } -#line 5314 "MachineIndependent/glslang_tab.cpp" +#line 5344 "MachineIndependent/glslang_tab.cpp" break; case 18: /* postfix_expression: primary_expression */ -#line 461 "MachineIndependent/glslang.y" +#line 422 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5322 "MachineIndependent/glslang_tab.cpp" +#line 5352 "MachineIndependent/glslang_tab.cpp" break; case 19: /* postfix_expression: postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET */ -#line 464 "MachineIndependent/glslang.y" +#line 425 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBracketDereference((yyvsp[-2].lex).loc, (yyvsp[-3].interm.intermTypedNode), (yyvsp[-1].interm.intermTypedNode)); } -#line 5330 "MachineIndependent/glslang_tab.cpp" +#line 5360 "MachineIndependent/glslang_tab.cpp" break; case 20: /* postfix_expression: function_call */ -#line 467 "MachineIndependent/glslang.y" +#line 428 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5338 "MachineIndependent/glslang_tab.cpp" +#line 5368 "MachineIndependent/glslang_tab.cpp" break; case 21: /* postfix_expression: postfix_expression DOT IDENTIFIER */ -#line 470 "MachineIndependent/glslang.y" +#line 431 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleDotDereference((yyvsp[0].lex).loc, (yyvsp[-2].interm.intermTypedNode), *(yyvsp[0].lex).string); } -#line 5346 "MachineIndependent/glslang_tab.cpp" +#line 5376 "MachineIndependent/glslang_tab.cpp" break; case 22: /* postfix_expression: postfix_expression INC_OP */ -#line 473 "MachineIndependent/glslang.y" +#line 434 "MachineIndependent/glslang.y" { parseContext.variableCheck((yyvsp[-1].interm.intermTypedNode)); parseContext.lValueErrorCheck((yyvsp[0].lex).loc, "++", (yyvsp[-1].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[0].lex).loc, "++", EOpPostIncrement, (yyvsp[-1].interm.intermTypedNode)); } -#line 5356 "MachineIndependent/glslang_tab.cpp" +#line 5386 "MachineIndependent/glslang_tab.cpp" break; case 23: /* postfix_expression: postfix_expression DEC_OP */ -#line 478 "MachineIndependent/glslang.y" +#line 439 "MachineIndependent/glslang.y" { parseContext.variableCheck((yyvsp[-1].interm.intermTypedNode)); parseContext.lValueErrorCheck((yyvsp[0].lex).loc, "--", (yyvsp[-1].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[0].lex).loc, "--", EOpPostDecrement, (yyvsp[-1].interm.intermTypedNode)); } -#line 5366 "MachineIndependent/glslang_tab.cpp" +#line 5396 "MachineIndependent/glslang_tab.cpp" break; case 24: /* integer_expression: expression */ -#line 486 "MachineIndependent/glslang.y" +#line 447 "MachineIndependent/glslang.y" { parseContext.integerCheck((yyvsp[0].interm.intermTypedNode), "[]"); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5375 "MachineIndependent/glslang_tab.cpp" +#line 5405 "MachineIndependent/glslang_tab.cpp" break; case 25: /* function_call: function_call_or_method */ -#line 493 "MachineIndependent/glslang.y" +#line 454 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleFunctionCall((yyvsp[0].interm).loc, (yyvsp[0].interm).function, (yyvsp[0].interm).intermNode); delete (yyvsp[0].interm).function; } -#line 5384 "MachineIndependent/glslang_tab.cpp" +#line 5414 "MachineIndependent/glslang_tab.cpp" break; case 26: /* function_call_or_method: function_call_generic */ -#line 500 "MachineIndependent/glslang.y" +#line 461 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[0].interm); } -#line 5392 "MachineIndependent/glslang_tab.cpp" +#line 5422 "MachineIndependent/glslang_tab.cpp" break; case 27: /* function_call_generic: function_call_header_with_parameters RIGHT_PAREN */ -#line 506 "MachineIndependent/glslang.y" +#line 467 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[-1].interm); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 5401 "MachineIndependent/glslang_tab.cpp" +#line 5431 "MachineIndependent/glslang_tab.cpp" break; case 28: /* function_call_generic: function_call_header_no_parameters RIGHT_PAREN */ -#line 510 "MachineIndependent/glslang.y" +#line 471 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[-1].interm); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 5410 "MachineIndependent/glslang_tab.cpp" +#line 5440 "MachineIndependent/glslang_tab.cpp" break; case 29: /* function_call_header_no_parameters: function_call_header VOID */ -#line 517 "MachineIndependent/glslang.y" +#line 478 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[-1].interm); } -#line 5418 "MachineIndependent/glslang_tab.cpp" +#line 5448 "MachineIndependent/glslang_tab.cpp" break; case 30: /* function_call_header_no_parameters: function_call_header */ -#line 520 "MachineIndependent/glslang.y" +#line 481 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[0].interm); } -#line 5426 "MachineIndependent/glslang_tab.cpp" +#line 5456 "MachineIndependent/glslang_tab.cpp" break; case 31: /* function_call_header_with_parameters: function_call_header assignment_expression */ -#line 526 "MachineIndependent/glslang.y" +#line 487 "MachineIndependent/glslang.y" { - TParameter param = { 0, new TType }; - param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); - (yyvsp[-1].interm).function->addParameter(param); - (yyval.interm).function = (yyvsp[-1].interm).function; - (yyval.interm).intermNode = (yyvsp[0].interm.intermTypedNode); + if (parseContext.spvVersion.vulkan > 0 + && parseContext.spvVersion.vulkanRelaxed + && (yyvsp[0].interm.intermTypedNode)->getType().containsOpaque()) + { + (yyval.interm).intermNode = parseContext.vkRelaxedRemapFunctionArgument((yyval.interm).loc, (yyvsp[-1].interm).function, (yyvsp[0].interm.intermTypedNode)); + (yyval.interm).function = (yyvsp[-1].interm).function; + } + else + { + TParameter param = { 0, new TType }; + param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); + + (yyvsp[-1].interm).function->addParameter(param); + (yyval.interm).function = (yyvsp[-1].interm).function; + (yyval.interm).intermNode = (yyvsp[0].interm.intermTypedNode); + } } -#line 5438 "MachineIndependent/glslang_tab.cpp" +#line 5479 "MachineIndependent/glslang_tab.cpp" break; case 32: /* function_call_header_with_parameters: function_call_header_with_parameters COMMA assignment_expression */ -#line 533 "MachineIndependent/glslang.y" +#line 505 "MachineIndependent/glslang.y" { - TParameter param = { 0, new TType }; - param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); - (yyvsp[-2].interm).function->addParameter(param); - (yyval.interm).function = (yyvsp[-2].interm).function; - (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-2].interm).intermNode, (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); + if (parseContext.spvVersion.vulkan > 0 + && parseContext.spvVersion.vulkanRelaxed + && (yyvsp[0].interm.intermTypedNode)->getType().containsOpaque()) + { + TIntermNode* remappedNode = parseContext.vkRelaxedRemapFunctionArgument((yyvsp[-1].lex).loc, (yyvsp[-2].interm).function, (yyvsp[0].interm.intermTypedNode)); + (yyval.interm).intermNode = parseContext.intermediate.mergeAggregate((yyvsp[-2].interm).intermNode, remappedNode, (yyvsp[-1].lex).loc); + (yyval.interm).function = (yyvsp[-2].interm).function; + } + else + { + TParameter param = { 0, new TType }; + param.type->shallowCopy((yyvsp[0].interm.intermTypedNode)->getType()); + + (yyvsp[-2].interm).function->addParameter(param); + (yyval.interm).function = (yyvsp[-2].interm).function; + (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-2].interm).intermNode, (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); + } } -#line 5450 "MachineIndependent/glslang_tab.cpp" +#line 5503 "MachineIndependent/glslang_tab.cpp" break; case 33: /* function_call_header: function_identifier LEFT_PAREN */ -#line 543 "MachineIndependent/glslang.y" +#line 527 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[-1].interm); } -#line 5458 "MachineIndependent/glslang_tab.cpp" +#line 5511 "MachineIndependent/glslang_tab.cpp" break; case 34: /* function_identifier: type_specifier */ -#line 551 "MachineIndependent/glslang.y" +#line 535 "MachineIndependent/glslang.y" { // Constructor (yyval.interm).intermNode = 0; (yyval.interm).function = parseContext.handleConstructorCall((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); } -#line 5468 "MachineIndependent/glslang_tab.cpp" +#line 5521 "MachineIndependent/glslang_tab.cpp" break; case 35: /* function_identifier: postfix_expression */ -#line 556 "MachineIndependent/glslang.y" +#line 540 "MachineIndependent/glslang.y" { // // Should be a method or subroutine call, but we haven't recognized the arguments yet. @@ -5496,50 +5549,50 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm).function = new TFunction(empty, TType(EbtVoid), EOpNull); } } -#line 5500 "MachineIndependent/glslang_tab.cpp" +#line 5553 "MachineIndependent/glslang_tab.cpp" break; case 36: /* function_identifier: non_uniform_qualifier */ -#line 584 "MachineIndependent/glslang.y" +#line 567 "MachineIndependent/glslang.y" { // Constructor (yyval.interm).intermNode = 0; (yyval.interm).function = parseContext.handleConstructorCall((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); } -#line 5510 "MachineIndependent/glslang_tab.cpp" +#line 5563 "MachineIndependent/glslang_tab.cpp" break; case 37: /* unary_expression: postfix_expression */ -#line 593 "MachineIndependent/glslang.y" +#line 575 "MachineIndependent/glslang.y" { parseContext.variableCheck((yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); if (TIntermMethod* method = (yyvsp[0].interm.intermTypedNode)->getAsMethodNode()) parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "incomplete method syntax", method->getMethodName().c_str(), ""); } -#line 5521 "MachineIndependent/glslang_tab.cpp" +#line 5574 "MachineIndependent/glslang_tab.cpp" break; case 38: /* unary_expression: INC_OP unary_expression */ -#line 599 "MachineIndependent/glslang.y" +#line 581 "MachineIndependent/glslang.y" { parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "++", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "++", EOpPreIncrement, (yyvsp[0].interm.intermTypedNode)); } -#line 5530 "MachineIndependent/glslang_tab.cpp" +#line 5583 "MachineIndependent/glslang_tab.cpp" break; case 39: /* unary_expression: DEC_OP unary_expression */ -#line 603 "MachineIndependent/glslang.y" +#line 585 "MachineIndependent/glslang.y" { parseContext.lValueErrorCheck((yyvsp[-1].lex).loc, "--", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.handleUnaryMath((yyvsp[-1].lex).loc, "--", EOpPreDecrement, (yyvsp[0].interm.intermTypedNode)); } -#line 5539 "MachineIndependent/glslang_tab.cpp" +#line 5592 "MachineIndependent/glslang_tab.cpp" break; case 40: /* unary_expression: unary_operator unary_expression */ -#line 607 "MachineIndependent/glslang.y" +#line 589 "MachineIndependent/glslang.y" { if ((yyvsp[-1].interm).op != EOpNull) { char errorOp[2] = {0, 0}; @@ -5556,179 +5609,179 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.intermTypedNode)->getAsConstantUnion()->setExpression(); } } -#line 5560 "MachineIndependent/glslang_tab.cpp" +#line 5613 "MachineIndependent/glslang_tab.cpp" break; case 41: /* unary_operator: PLUS */ -#line 627 "MachineIndependent/glslang.y" +#line 609 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNull; } -#line 5566 "MachineIndependent/glslang_tab.cpp" +#line 5619 "MachineIndependent/glslang_tab.cpp" break; case 42: /* unary_operator: DASH */ -#line 628 "MachineIndependent/glslang.y" +#line 610 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpNegative; } -#line 5572 "MachineIndependent/glslang_tab.cpp" +#line 5625 "MachineIndependent/glslang_tab.cpp" break; case 43: /* unary_operator: BANG */ -#line 629 "MachineIndependent/glslang.y" +#line 611 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLogicalNot; } -#line 5578 "MachineIndependent/glslang_tab.cpp" +#line 5631 "MachineIndependent/glslang_tab.cpp" break; case 44: /* unary_operator: TILDE */ -#line 630 "MachineIndependent/glslang.y" +#line 612 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpBitwiseNot; parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise not"); } -#line 5585 "MachineIndependent/glslang_tab.cpp" +#line 5638 "MachineIndependent/glslang_tab.cpp" break; case 45: /* multiplicative_expression: unary_expression */ -#line 636 "MachineIndependent/glslang.y" +#line 618 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5591 "MachineIndependent/glslang_tab.cpp" +#line 5644 "MachineIndependent/glslang_tab.cpp" break; case 46: /* multiplicative_expression: multiplicative_expression STAR unary_expression */ -#line 637 "MachineIndependent/glslang.y" +#line 619 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "*", EOpMul, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5601 "MachineIndependent/glslang_tab.cpp" +#line 5654 "MachineIndependent/glslang_tab.cpp" break; case 47: /* multiplicative_expression: multiplicative_expression SLASH unary_expression */ -#line 642 "MachineIndependent/glslang.y" +#line 624 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "/", EOpDiv, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5611 "MachineIndependent/glslang_tab.cpp" +#line 5664 "MachineIndependent/glslang_tab.cpp" break; case 48: /* multiplicative_expression: multiplicative_expression PERCENT unary_expression */ -#line 647 "MachineIndependent/glslang.y" +#line 629 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "%"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "%", EOpMod, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5622 "MachineIndependent/glslang_tab.cpp" +#line 5675 "MachineIndependent/glslang_tab.cpp" break; case 49: /* additive_expression: multiplicative_expression */ -#line 656 "MachineIndependent/glslang.y" +#line 638 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5628 "MachineIndependent/glslang_tab.cpp" +#line 5681 "MachineIndependent/glslang_tab.cpp" break; case 50: /* additive_expression: additive_expression PLUS multiplicative_expression */ -#line 657 "MachineIndependent/glslang.y" +#line 639 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "+", EOpAdd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5638 "MachineIndependent/glslang_tab.cpp" +#line 5691 "MachineIndependent/glslang_tab.cpp" break; case 51: /* additive_expression: additive_expression DASH multiplicative_expression */ -#line 662 "MachineIndependent/glslang.y" +#line 644 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "-", EOpSub, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5648 "MachineIndependent/glslang_tab.cpp" +#line 5701 "MachineIndependent/glslang_tab.cpp" break; case 52: /* shift_expression: additive_expression */ -#line 670 "MachineIndependent/glslang.y" +#line 652 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5654 "MachineIndependent/glslang_tab.cpp" +#line 5707 "MachineIndependent/glslang_tab.cpp" break; case 53: /* shift_expression: shift_expression LEFT_OP additive_expression */ -#line 671 "MachineIndependent/glslang.y" +#line 653 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift left"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<<", EOpLeftShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5665 "MachineIndependent/glslang_tab.cpp" +#line 5718 "MachineIndependent/glslang_tab.cpp" break; case 54: /* shift_expression: shift_expression RIGHT_OP additive_expression */ -#line 677 "MachineIndependent/glslang.y" +#line 659 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bit shift right"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">>", EOpRightShift, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5676 "MachineIndependent/glslang_tab.cpp" +#line 5729 "MachineIndependent/glslang_tab.cpp" break; case 55: /* relational_expression: shift_expression */ -#line 686 "MachineIndependent/glslang.y" +#line 668 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5682 "MachineIndependent/glslang_tab.cpp" +#line 5735 "MachineIndependent/glslang_tab.cpp" break; case 56: /* relational_expression: relational_expression LEFT_ANGLE shift_expression */ -#line 687 "MachineIndependent/glslang.y" +#line 669 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<", EOpLessThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5692 "MachineIndependent/glslang_tab.cpp" +#line 5745 "MachineIndependent/glslang_tab.cpp" break; case 57: /* relational_expression: relational_expression RIGHT_ANGLE shift_expression */ -#line 692 "MachineIndependent/glslang.y" +#line 674 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">", EOpGreaterThan, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5702 "MachineIndependent/glslang_tab.cpp" +#line 5755 "MachineIndependent/glslang_tab.cpp" break; case 58: /* relational_expression: relational_expression LE_OP shift_expression */ -#line 697 "MachineIndependent/glslang.y" +#line 679 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "<=", EOpLessThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5712 "MachineIndependent/glslang_tab.cpp" +#line 5765 "MachineIndependent/glslang_tab.cpp" break; case 59: /* relational_expression: relational_expression GE_OP shift_expression */ -#line 702 "MachineIndependent/glslang.y" +#line 684 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, ">=", EOpGreaterThanEqual, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5722 "MachineIndependent/glslang_tab.cpp" +#line 5775 "MachineIndependent/glslang_tab.cpp" break; case 60: /* equality_expression: relational_expression */ -#line 710 "MachineIndependent/glslang.y" +#line 692 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5728 "MachineIndependent/glslang_tab.cpp" +#line 5781 "MachineIndependent/glslang_tab.cpp" break; case 61: /* equality_expression: equality_expression EQ_OP relational_expression */ -#line 711 "MachineIndependent/glslang.y" +#line 693 "MachineIndependent/glslang.y" { parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "=="); @@ -5738,11 +5791,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5742 "MachineIndependent/glslang_tab.cpp" +#line 5795 "MachineIndependent/glslang_tab.cpp" break; case 62: /* equality_expression: equality_expression NE_OP relational_expression */ -#line 720 "MachineIndependent/glslang.y" +#line 702 "MachineIndependent/glslang.y" { parseContext.arrayObjectCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array comparison"); parseContext.opaqueCheck((yyvsp[-1].lex).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "!="); @@ -5752,124 +5805,124 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5756 "MachineIndependent/glslang_tab.cpp" +#line 5809 "MachineIndependent/glslang_tab.cpp" break; case 63: /* and_expression: equality_expression */ -#line 732 "MachineIndependent/glslang.y" +#line 714 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5762 "MachineIndependent/glslang_tab.cpp" +#line 5815 "MachineIndependent/glslang_tab.cpp" break; case 64: /* and_expression: and_expression AMPERSAND equality_expression */ -#line 733 "MachineIndependent/glslang.y" +#line 715 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise and"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&", EOpAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5773 "MachineIndependent/glslang_tab.cpp" +#line 5826 "MachineIndependent/glslang_tab.cpp" break; case 65: /* exclusive_or_expression: and_expression */ -#line 742 "MachineIndependent/glslang.y" +#line 724 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5779 "MachineIndependent/glslang_tab.cpp" +#line 5832 "MachineIndependent/glslang_tab.cpp" break; case 66: /* exclusive_or_expression: exclusive_or_expression CARET and_expression */ -#line 743 "MachineIndependent/glslang.y" +#line 725 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise exclusive or"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^", EOpExclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5790 "MachineIndependent/glslang_tab.cpp" +#line 5843 "MachineIndependent/glslang_tab.cpp" break; case 67: /* inclusive_or_expression: exclusive_or_expression */ -#line 752 "MachineIndependent/glslang.y" +#line 734 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5796 "MachineIndependent/glslang_tab.cpp" +#line 5849 "MachineIndependent/glslang_tab.cpp" break; case 68: /* inclusive_or_expression: inclusive_or_expression VERTICAL_BAR exclusive_or_expression */ -#line 753 "MachineIndependent/glslang.y" +#line 735 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[-1].lex).loc, "bitwise inclusive or"); (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "|", EOpInclusiveOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 5807 "MachineIndependent/glslang_tab.cpp" +#line 5860 "MachineIndependent/glslang_tab.cpp" break; case 69: /* logical_and_expression: inclusive_or_expression */ -#line 762 "MachineIndependent/glslang.y" +#line 744 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5813 "MachineIndependent/glslang_tab.cpp" +#line 5866 "MachineIndependent/glslang_tab.cpp" break; case 70: /* logical_and_expression: logical_and_expression AND_OP inclusive_or_expression */ -#line 763 "MachineIndependent/glslang.y" +#line 745 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "&&", EOpLogicalAnd, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5823 "MachineIndependent/glslang_tab.cpp" +#line 5876 "MachineIndependent/glslang_tab.cpp" break; case 71: /* logical_xor_expression: logical_and_expression */ -#line 771 "MachineIndependent/glslang.y" +#line 753 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5829 "MachineIndependent/glslang_tab.cpp" +#line 5882 "MachineIndependent/glslang_tab.cpp" break; case 72: /* logical_xor_expression: logical_xor_expression XOR_OP logical_and_expression */ -#line 772 "MachineIndependent/glslang.y" +#line 754 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "^^", EOpLogicalXor, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5839 "MachineIndependent/glslang_tab.cpp" +#line 5892 "MachineIndependent/glslang_tab.cpp" break; case 73: /* logical_or_expression: logical_xor_expression */ -#line 780 "MachineIndependent/glslang.y" +#line 762 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5845 "MachineIndependent/glslang_tab.cpp" +#line 5898 "MachineIndependent/glslang_tab.cpp" break; case 74: /* logical_or_expression: logical_or_expression OR_OP logical_xor_expression */ -#line 781 "MachineIndependent/glslang.y" +#line 763 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.handleBinaryMath((yyvsp[-1].lex).loc, "||", EOpLogicalOr, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) (yyval.interm.intermTypedNode) = parseContext.intermediate.addConstantUnion(false, (yyvsp[-1].lex).loc); } -#line 5855 "MachineIndependent/glslang_tab.cpp" +#line 5908 "MachineIndependent/glslang_tab.cpp" break; case 75: /* conditional_expression: logical_or_expression */ -#line 789 "MachineIndependent/glslang.y" +#line 771 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5861 "MachineIndependent/glslang_tab.cpp" +#line 5914 "MachineIndependent/glslang_tab.cpp" break; case 76: /* $@1: %empty */ -#line 790 "MachineIndependent/glslang.y" +#line 772 "MachineIndependent/glslang.y" { ++parseContext.controlFlowNestingLevel; } -#line 5869 "MachineIndependent/glslang_tab.cpp" +#line 5922 "MachineIndependent/glslang_tab.cpp" break; case 77: /* conditional_expression: logical_or_expression QUESTION $@1 expression COLON assignment_expression */ -#line 793 "MachineIndependent/glslang.y" +#line 775 "MachineIndependent/glslang.y" { --parseContext.controlFlowNestingLevel; parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-5].interm.intermTypedNode)); @@ -5878,21 +5931,21 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.rValueErrorCheck((yyvsp[-1].lex).loc, ":", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.intermediate.addSelection((yyvsp[-5].interm.intermTypedNode), (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-4].lex).loc); if ((yyval.interm.intermTypedNode) == 0) { - parseContext.binaryOpError((yyvsp[-4].lex).loc, ":", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); + parseContext.binaryOpError((yyvsp[-4].lex).loc, ":", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), (yyvsp[0].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs())); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } -#line 5886 "MachineIndependent/glslang_tab.cpp" +#line 5939 "MachineIndependent/glslang_tab.cpp" break; case 78: /* assignment_expression: conditional_expression */ -#line 808 "MachineIndependent/glslang.y" +#line 790 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 5892 "MachineIndependent/glslang_tab.cpp" +#line 5945 "MachineIndependent/glslang_tab.cpp" break; case 79: /* assignment_expression: unary_expression assignment_operator assignment_expression */ -#line 809 "MachineIndependent/glslang.y" +#line 791 "MachineIndependent/glslang.y" { parseContext.arrayObjectCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "array assignment"); parseContext.opaqueCheck((yyvsp[-1].interm).loc, (yyvsp[-2].interm.intermTypedNode)->getType(), "="); @@ -5902,155 +5955,155 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.rValueErrorCheck((yyvsp[-1].interm).loc, "assign", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.addAssign((yyvsp[-1].interm).loc, (yyvsp[-1].interm).op, (yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); if ((yyval.interm.intermTypedNode) == 0) { - parseContext.assignError((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); + parseContext.assignError((yyvsp[-1].interm).loc, "assign", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), (yyvsp[0].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs())); (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } } -#line 5910 "MachineIndependent/glslang_tab.cpp" +#line 5963 "MachineIndependent/glslang_tab.cpp" break; case 80: /* assignment_operator: EQUAL */ -#line 825 "MachineIndependent/glslang.y" +#line 807 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAssign; } -#line 5919 "MachineIndependent/glslang_tab.cpp" +#line 5972 "MachineIndependent/glslang_tab.cpp" break; case 81: /* assignment_operator: MUL_ASSIGN */ -#line 829 "MachineIndependent/glslang.y" +#line 811 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpMulAssign; } -#line 5928 "MachineIndependent/glslang_tab.cpp" +#line 5981 "MachineIndependent/glslang_tab.cpp" break; case 82: /* assignment_operator: DIV_ASSIGN */ -#line 833 "MachineIndependent/glslang.y" +#line 815 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpDivAssign; } -#line 5937 "MachineIndependent/glslang_tab.cpp" +#line 5990 "MachineIndependent/glslang_tab.cpp" break; case 83: /* assignment_operator: MOD_ASSIGN */ -#line 837 "MachineIndependent/glslang.y" +#line 819 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "%="); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpModAssign; } -#line 5947 "MachineIndependent/glslang_tab.cpp" +#line 6000 "MachineIndependent/glslang_tab.cpp" break; case 84: /* assignment_operator: ADD_ASSIGN */ -#line 842 "MachineIndependent/glslang.y" +#line 824 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAddAssign; } -#line 5956 "MachineIndependent/glslang_tab.cpp" +#line 6009 "MachineIndependent/glslang_tab.cpp" break; case 85: /* assignment_operator: SUB_ASSIGN */ -#line 846 "MachineIndependent/glslang.y" +#line 828 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpSubAssign; } -#line 5965 "MachineIndependent/glslang_tab.cpp" +#line 6018 "MachineIndependent/glslang_tab.cpp" break; case 86: /* assignment_operator: LEFT_ASSIGN */ -#line 850 "MachineIndependent/glslang.y" +#line 832 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift left assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpLeftShiftAssign; } -#line 5974 "MachineIndependent/glslang_tab.cpp" +#line 6027 "MachineIndependent/glslang_tab.cpp" break; case 87: /* assignment_operator: RIGHT_ASSIGN */ -#line 854 "MachineIndependent/glslang.y" +#line 836 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bit-shift right assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpRightShiftAssign; } -#line 5983 "MachineIndependent/glslang_tab.cpp" +#line 6036 "MachineIndependent/glslang_tab.cpp" break; case 88: /* assignment_operator: AND_ASSIGN */ -#line 858 "MachineIndependent/glslang.y" +#line 840 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-and assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpAndAssign; } -#line 5992 "MachineIndependent/glslang_tab.cpp" +#line 6045 "MachineIndependent/glslang_tab.cpp" break; case 89: /* assignment_operator: XOR_ASSIGN */ -#line 862 "MachineIndependent/glslang.y" +#line 844 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-xor assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpExclusiveOrAssign; } -#line 6001 "MachineIndependent/glslang_tab.cpp" +#line 6054 "MachineIndependent/glslang_tab.cpp" break; case 90: /* assignment_operator: OR_ASSIGN */ -#line 866 "MachineIndependent/glslang.y" +#line 848 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "bitwise-or assign"); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).op = EOpInclusiveOrAssign; } -#line 6010 "MachineIndependent/glslang_tab.cpp" +#line 6063 "MachineIndependent/glslang_tab.cpp" break; case 91: /* expression: assignment_expression */ -#line 873 "MachineIndependent/glslang.y" +#line 855 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 6018 "MachineIndependent/glslang_tab.cpp" +#line 6071 "MachineIndependent/glslang_tab.cpp" break; case 92: /* expression: expression COMMA assignment_expression */ -#line 876 "MachineIndependent/glslang.y" +#line 858 "MachineIndependent/glslang.y" { parseContext.samplerConstructorLocationCheck((yyvsp[-1].lex).loc, ",", (yyvsp[0].interm.intermTypedNode)); (yyval.interm.intermTypedNode) = parseContext.intermediate.addComma((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode), (yyvsp[-1].lex).loc); if ((yyval.interm.intermTypedNode) == 0) { - parseContext.binaryOpError((yyvsp[-1].lex).loc, ",", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(), (yyvsp[0].interm.intermTypedNode)->getCompleteString()); + parseContext.binaryOpError((yyvsp[-1].lex).loc, ",", (yyvsp[-2].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs()), (yyvsp[0].interm.intermTypedNode)->getCompleteString(parseContext.intermediate.getEnhancedMsgs())); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } } -#line 6031 "MachineIndependent/glslang_tab.cpp" +#line 6084 "MachineIndependent/glslang_tab.cpp" break; case 93: /* constant_expression: conditional_expression */ -#line 887 "MachineIndependent/glslang.y" +#line 869 "MachineIndependent/glslang.y" { parseContext.constantValueCheck((yyvsp[0].interm.intermTypedNode), ""); (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 6040 "MachineIndependent/glslang_tab.cpp" +#line 6093 "MachineIndependent/glslang_tab.cpp" break; case 94: /* declaration: function_prototype SEMICOLON */ -#line 894 "MachineIndependent/glslang.y" +#line 876 "MachineIndependent/glslang.y" { parseContext.handleFunctionDeclarator((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).function, true /* prototype */); (yyval.interm.intermNode) = 0; // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature } -#line 6050 "MachineIndependent/glslang_tab.cpp" +#line 6103 "MachineIndependent/glslang_tab.cpp" break; case 95: /* declaration: spirv_instruction_qualifier function_prototype SEMICOLON */ -#line 900 "MachineIndependent/glslang.y" +#line 881 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[-1].interm).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V instruction qualifier"); (yyvsp[-1].interm).function->setSpirvInstruction(*(yyvsp[-2].interm.spirvInst)); // Attach SPIR-V intruction qualifier @@ -6058,31 +6111,31 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.intermNode) = 0; // TODO: 4.0 functionality: subroutines: make the identifier a user type for this signature } -#line 6062 "MachineIndependent/glslang_tab.cpp" +#line 6115 "MachineIndependent/glslang_tab.cpp" break; case 96: /* declaration: spirv_execution_mode_qualifier SEMICOLON */ -#line 907 "MachineIndependent/glslang.y" +#line 888 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "SPIR-V execution mode qualifier"); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V execution mode qualifier"); (yyval.interm.intermNode) = 0; } -#line 6072 "MachineIndependent/glslang_tab.cpp" +#line 6125 "MachineIndependent/glslang_tab.cpp" break; case 97: /* declaration: init_declarator_list SEMICOLON */ -#line 913 "MachineIndependent/glslang.y" +#line 893 "MachineIndependent/glslang.y" { if ((yyvsp[-1].interm).intermNode && (yyvsp[-1].interm).intermNode->getAsAggregate()) (yyvsp[-1].interm).intermNode->getAsAggregate()->setOperator(EOpSequence); (yyval.interm.intermNode) = (yyvsp[-1].interm).intermNode; } -#line 6082 "MachineIndependent/glslang_tab.cpp" +#line 6135 "MachineIndependent/glslang_tab.cpp" break; case 98: /* declaration: PRECISION precision_qualifier type_specifier SEMICOLON */ -#line 918 "MachineIndependent/glslang.y" +#line 898 "MachineIndependent/glslang.y" { parseContext.profileRequires((yyvsp[-3].lex).loc, ENoProfile, 130, 0, "precision statement"); // lazy setting of the previous scope's defaults, has effect only the first time it is called in a particular scope @@ -6090,75 +6143,75 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.setDefaultPrecision((yyvsp[-3].lex).loc, (yyvsp[-1].interm.type), (yyvsp[-2].interm.type).qualifier.precision); (yyval.interm.intermNode) = 0; } -#line 6094 "MachineIndependent/glslang_tab.cpp" +#line 6147 "MachineIndependent/glslang_tab.cpp" break; case 99: /* declaration: block_structure SEMICOLON */ -#line 925 "MachineIndependent/glslang.y" +#line 905 "MachineIndependent/glslang.y" { parseContext.declareBlock((yyvsp[-1].interm).loc, *(yyvsp[-1].interm).typeList); (yyval.interm.intermNode) = 0; } -#line 6103 "MachineIndependent/glslang_tab.cpp" +#line 6156 "MachineIndependent/glslang_tab.cpp" break; case 100: /* declaration: block_structure IDENTIFIER SEMICOLON */ -#line 929 "MachineIndependent/glslang.y" +#line 909 "MachineIndependent/glslang.y" { parseContext.declareBlock((yyvsp[-2].interm).loc, *(yyvsp[-2].interm).typeList, (yyvsp[-1].lex).string); (yyval.interm.intermNode) = 0; } -#line 6112 "MachineIndependent/glslang_tab.cpp" +#line 6165 "MachineIndependent/glslang_tab.cpp" break; case 101: /* declaration: block_structure IDENTIFIER array_specifier SEMICOLON */ -#line 933 "MachineIndependent/glslang.y" +#line 913 "MachineIndependent/glslang.y" { parseContext.declareBlock((yyvsp[-3].interm).loc, *(yyvsp[-3].interm).typeList, (yyvsp[-2].lex).string, (yyvsp[-1].interm).arraySizes); (yyval.interm.intermNode) = 0; } -#line 6121 "MachineIndependent/glslang_tab.cpp" +#line 6174 "MachineIndependent/glslang_tab.cpp" break; case 102: /* declaration: type_qualifier SEMICOLON */ -#line 937 "MachineIndependent/glslang.y" +#line 917 "MachineIndependent/glslang.y" { parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier); parseContext.updateStandaloneQualifierDefaults((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type)); (yyval.interm.intermNode) = 0; } -#line 6131 "MachineIndependent/glslang_tab.cpp" +#line 6184 "MachineIndependent/glslang_tab.cpp" break; case 103: /* declaration: type_qualifier IDENTIFIER SEMICOLON */ -#line 942 "MachineIndependent/glslang.y" +#line 922 "MachineIndependent/glslang.y" { parseContext.checkNoShaderLayouts((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).shaderQualifiers); parseContext.addQualifierToExisting((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).qualifier, *(yyvsp[-1].lex).string); (yyval.interm.intermNode) = 0; } -#line 6141 "MachineIndependent/glslang_tab.cpp" +#line 6194 "MachineIndependent/glslang_tab.cpp" break; case 104: /* declaration: type_qualifier IDENTIFIER identifier_list SEMICOLON */ -#line 947 "MachineIndependent/glslang.y" +#line 927 "MachineIndependent/glslang.y" { parseContext.checkNoShaderLayouts((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).shaderQualifiers); (yyvsp[-1].interm.identifierList)->push_back((yyvsp[-2].lex).string); parseContext.addQualifierToExisting((yyvsp[-3].interm.type).loc, (yyvsp[-3].interm.type).qualifier, *(yyvsp[-1].interm.identifierList)); (yyval.interm.intermNode) = 0; } -#line 6152 "MachineIndependent/glslang_tab.cpp" +#line 6205 "MachineIndependent/glslang_tab.cpp" break; case 105: /* $@2: %empty */ -#line 956 "MachineIndependent/glslang.y" +#line 936 "MachineIndependent/glslang.y" { parseContext.nestedBlockCheck((yyvsp[-2].interm.type).loc); } -#line 6158 "MachineIndependent/glslang_tab.cpp" +#line 6211 "MachineIndependent/glslang_tab.cpp" break; case 106: /* block_structure: type_qualifier IDENTIFIER LEFT_BRACE $@2 struct_declaration_list RIGHT_BRACE */ -#line 956 "MachineIndependent/glslang.y" +#line 936 "MachineIndependent/glslang.y" { --parseContext.blockNestingLevel; parseContext.blockName = (yyvsp[-4].lex).string; @@ -6168,101 +6221,107 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm).loc = (yyvsp[-5].interm.type).loc; (yyval.interm).typeList = (yyvsp[-1].interm.typeList); } -#line 6172 "MachineIndependent/glslang_tab.cpp" +#line 6225 "MachineIndependent/glslang_tab.cpp" break; case 107: /* identifier_list: COMMA IDENTIFIER */ -#line 967 "MachineIndependent/glslang.y" +#line 947 "MachineIndependent/glslang.y" { (yyval.interm.identifierList) = new TIdentifierList; (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); } -#line 6181 "MachineIndependent/glslang_tab.cpp" +#line 6234 "MachineIndependent/glslang_tab.cpp" break; case 108: /* identifier_list: identifier_list COMMA IDENTIFIER */ -#line 971 "MachineIndependent/glslang.y" +#line 951 "MachineIndependent/glslang.y" { (yyval.interm.identifierList) = (yyvsp[-2].interm.identifierList); (yyval.interm.identifierList)->push_back((yyvsp[0].lex).string); } -#line 6190 "MachineIndependent/glslang_tab.cpp" +#line 6243 "MachineIndependent/glslang_tab.cpp" break; case 109: /* function_prototype: function_declarator RIGHT_PAREN */ -#line 978 "MachineIndependent/glslang.y" +#line 958 "MachineIndependent/glslang.y" { (yyval.interm).function = (yyvsp[-1].interm.function); + if (parseContext.compileOnly) (yyval.interm).function->setExport(); (yyval.interm).loc = (yyvsp[0].lex).loc; } -#line 6199 "MachineIndependent/glslang_tab.cpp" +#line 6253 "MachineIndependent/glslang_tab.cpp" break; case 110: /* function_prototype: function_declarator RIGHT_PAREN attribute */ -#line 982 "MachineIndependent/glslang.y" +#line 963 "MachineIndependent/glslang.y" { (yyval.interm).function = (yyvsp[-2].interm.function); + if (parseContext.compileOnly) (yyval.interm).function->setExport(); (yyval.interm).loc = (yyvsp[-1].lex).loc; - parseContext.requireExtensions((yyvsp[-1].lex).loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute"); parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[0].interm.attributes)); } -#line 6210 "MachineIndependent/glslang_tab.cpp" +#line 6264 "MachineIndependent/glslang_tab.cpp" break; case 111: /* function_prototype: attribute function_declarator RIGHT_PAREN */ -#line 988 "MachineIndependent/glslang.y" +#line 969 "MachineIndependent/glslang.y" { (yyval.interm).function = (yyvsp[-1].interm.function); + if (parseContext.compileOnly) (yyval.interm).function->setExport(); (yyval.interm).loc = (yyvsp[0].lex).loc; - parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute"); parseContext.handleFunctionAttributes((yyvsp[0].lex).loc, *(yyvsp[-2].interm.attributes)); } -#line 6221 "MachineIndependent/glslang_tab.cpp" +#line 6275 "MachineIndependent/glslang_tab.cpp" break; case 112: /* function_prototype: attribute function_declarator RIGHT_PAREN attribute */ -#line 994 "MachineIndependent/glslang.y" +#line 975 "MachineIndependent/glslang.y" { (yyval.interm).function = (yyvsp[-2].interm.function); + if (parseContext.compileOnly) (yyval.interm).function->setExport(); (yyval.interm).loc = (yyvsp[-1].lex).loc; - parseContext.requireExtensions((yyvsp[-1].lex).loc, 1, &E_GL_EXT_subgroup_uniform_control_flow, "attribute"); parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[-3].interm.attributes)); parseContext.handleFunctionAttributes((yyvsp[-1].lex).loc, *(yyvsp[0].interm.attributes)); } -#line 6233 "MachineIndependent/glslang_tab.cpp" +#line 6287 "MachineIndependent/glslang_tab.cpp" break; case 113: /* function_declarator: function_header */ -#line 1004 "MachineIndependent/glslang.y" +#line 985 "MachineIndependent/glslang.y" { (yyval.interm.function) = (yyvsp[0].interm.function); } -#line 6241 "MachineIndependent/glslang_tab.cpp" +#line 6295 "MachineIndependent/glslang_tab.cpp" break; case 114: /* function_declarator: function_header_with_parameters */ -#line 1007 "MachineIndependent/glslang.y" +#line 988 "MachineIndependent/glslang.y" { (yyval.interm.function) = (yyvsp[0].interm.function); } -#line 6249 "MachineIndependent/glslang_tab.cpp" +#line 6303 "MachineIndependent/glslang_tab.cpp" break; case 115: /* function_header_with_parameters: function_header parameter_declaration */ -#line 1014 "MachineIndependent/glslang.y" +#line 995 "MachineIndependent/glslang.y" { // Add the parameter (yyval.interm.function) = (yyvsp[-1].interm.function); if ((yyvsp[0].interm).param.type->getBasicType() != EbtVoid) - (yyvsp[-1].interm.function)->addParameter((yyvsp[0].interm).param); + { + if (!(parseContext.spvVersion.vulkan > 0 && parseContext.spvVersion.vulkanRelaxed)) + (yyvsp[-1].interm.function)->addParameter((yyvsp[0].interm).param); + else + parseContext.vkRelaxedRemapFunctionParameter((yyvsp[-1].interm.function), (yyvsp[0].interm).param); + } else delete (yyvsp[0].interm).param.type; } -#line 6262 "MachineIndependent/glslang_tab.cpp" +#line 6321 "MachineIndependent/glslang_tab.cpp" break; case 116: /* function_header_with_parameters: function_header_with_parameters COMMA parameter_declaration */ -#line 1022 "MachineIndependent/glslang.y" +#line 1008 "MachineIndependent/glslang.y" { // // Only first parameter of one-parameter functions can be void @@ -6277,14 +6336,17 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } else { // Add the parameter (yyval.interm.function) = (yyvsp[-2].interm.function); - (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm).param); + if (!(parseContext.spvVersion.vulkan > 0 && parseContext.spvVersion.vulkanRelaxed)) + (yyvsp[-2].interm.function)->addParameter((yyvsp[0].interm).param); + else + parseContext.vkRelaxedRemapFunctionParameter((yyvsp[-2].interm.function), (yyvsp[0].interm).param); } } -#line 6284 "MachineIndependent/glslang_tab.cpp" +#line 6346 "MachineIndependent/glslang_tab.cpp" break; case 117: /* function_header: fully_specified_type IDENTIFIER LEFT_PAREN */ -#line 1042 "MachineIndependent/glslang.y" +#line 1031 "MachineIndependent/glslang.y" { if ((yyvsp[-2].interm.type).qualifier.storage != EvqGlobal && (yyvsp[-2].interm.type).qualifier.storage != EvqTemporary) { parseContext.error((yyvsp[-1].lex).loc, "no qualifiers allowed for function return", @@ -6304,11 +6366,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); function = new TFunction((yyvsp[-1].lex).string, type); (yyval.interm.function) = function; } -#line 6308 "MachineIndependent/glslang_tab.cpp" +#line 6370 "MachineIndependent/glslang_tab.cpp" break; case 118: /* parameter_declarator: type_specifier IDENTIFIER */ -#line 1065 "MachineIndependent/glslang.y" +#line 1054 "MachineIndependent/glslang.y" { if ((yyvsp[-1].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-1].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); @@ -6324,11 +6386,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm).loc = (yyvsp[0].lex).loc; (yyval.interm).param = param; } -#line 6328 "MachineIndependent/glslang_tab.cpp" +#line 6390 "MachineIndependent/glslang_tab.cpp" break; case 119: /* parameter_declarator: type_specifier IDENTIFIER array_specifier */ -#line 1080 "MachineIndependent/glslang.y" +#line 1069 "MachineIndependent/glslang.y" { if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); @@ -6348,175 +6410,173 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm).loc = (yyvsp[-1].lex).loc; (yyval.interm).param = param; } -#line 6352 "MachineIndependent/glslang_tab.cpp" +#line 6414 "MachineIndependent/glslang_tab.cpp" break; case 120: /* parameter_declaration: type_qualifier parameter_declarator */ -#line 1105 "MachineIndependent/glslang.y" +#line 1094 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[0].interm); if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) (yyval.interm).param.type->getQualifier().precision = (yyvsp[-1].interm.type).qualifier.precision; - parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier(), (yyval.interm).param.type->isCoopMat()); parseContext.checkNoShaderLayouts((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).shaderQualifiers); parseContext.parameterTypeCheck((yyvsp[0].interm).loc, (yyvsp[-1].interm.type).qualifier.storage, *(yyval.interm).param.type); parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); } -#line 6368 "MachineIndependent/glslang_tab.cpp" +#line 6430 "MachineIndependent/glslang_tab.cpp" break; case 121: /* parameter_declaration: parameter_declarator */ -#line 1116 "MachineIndependent/glslang.y" +#line 1105 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[0].interm); parseContext.parameterTypeCheck((yyvsp[0].interm).loc, EvqIn, *(yyvsp[0].interm).param.type); parseContext.paramCheckFixStorage((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); - parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier(), (yyval.interm).param.type->isCoopMat()); } -#line 6380 "MachineIndependent/glslang_tab.cpp" +#line 6442 "MachineIndependent/glslang_tab.cpp" break; case 122: /* parameter_declaration: type_qualifier parameter_type_specifier */ -#line 1126 "MachineIndependent/glslang.y" +#line 1115 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[0].interm); if ((yyvsp[-1].interm.type).qualifier.precision != EpqNone) (yyval.interm).param.type->getQualifier().precision = (yyvsp[-1].interm.type).qualifier.precision; - parseContext.precisionQualifierCheck((yyvsp[-1].interm.type).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + parseContext.precisionQualifierCheck((yyvsp[-1].interm.type).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier(), (yyval.interm).param.type->isCoopMat()); parseContext.checkNoShaderLayouts((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).shaderQualifiers); parseContext.parameterTypeCheck((yyvsp[0].interm).loc, (yyvsp[-1].interm.type).qualifier.storage, *(yyval.interm).param.type); parseContext.paramCheckFix((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, *(yyval.interm).param.type); } -#line 6395 "MachineIndependent/glslang_tab.cpp" +#line 6457 "MachineIndependent/glslang_tab.cpp" break; case 123: /* parameter_declaration: parameter_type_specifier */ -#line 1136 "MachineIndependent/glslang.y" +#line 1125 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[0].interm); parseContext.parameterTypeCheck((yyvsp[0].interm).loc, EvqIn, *(yyvsp[0].interm).param.type); parseContext.paramCheckFixStorage((yyvsp[0].interm).loc, EvqTemporary, *(yyval.interm).param.type); - parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier()); + parseContext.precisionQualifierCheck((yyval.interm).loc, (yyval.interm).param.type->getBasicType(), (yyval.interm).param.type->getQualifier(), (yyval.interm).param.type->isCoopMat()); } -#line 6407 "MachineIndependent/glslang_tab.cpp" +#line 6469 "MachineIndependent/glslang_tab.cpp" break; case 124: /* parameter_type_specifier: type_specifier */ -#line 1146 "MachineIndependent/glslang.y" +#line 1135 "MachineIndependent/glslang.y" { TParameter param = { 0, new TType((yyvsp[0].interm.type)) }; (yyval.interm).param = param; if ((yyvsp[0].interm.type).arraySizes) parseContext.arraySizeRequiredCheck((yyvsp[0].interm.type).loc, *(yyvsp[0].interm.type).arraySizes); } -#line 6418 "MachineIndependent/glslang_tab.cpp" +#line 6480 "MachineIndependent/glslang_tab.cpp" break; case 125: /* init_declarator_list: single_declaration */ -#line 1155 "MachineIndependent/glslang.y" +#line 1144 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[0].interm); } -#line 6426 "MachineIndependent/glslang_tab.cpp" +#line 6488 "MachineIndependent/glslang_tab.cpp" break; case 126: /* init_declarator_list: init_declarator_list COMMA IDENTIFIER */ -#line 1158 "MachineIndependent/glslang.y" +#line 1147 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[-2].interm); parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-2].interm).type); } -#line 6435 "MachineIndependent/glslang_tab.cpp" +#line 6497 "MachineIndependent/glslang_tab.cpp" break; case 127: /* init_declarator_list: init_declarator_list COMMA IDENTIFIER array_specifier */ -#line 1162 "MachineIndependent/glslang.y" +#line 1151 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[-3].interm); parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-3].interm).type, (yyvsp[0].interm).arraySizes); } -#line 6444 "MachineIndependent/glslang_tab.cpp" +#line 6506 "MachineIndependent/glslang_tab.cpp" break; case 128: /* init_declarator_list: init_declarator_list COMMA IDENTIFIER array_specifier EQUAL initializer */ -#line 1166 "MachineIndependent/glslang.y" +#line 1155 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[-5].interm).type; TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-5].interm).type, (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-5].interm).intermNode, initNode, (yyvsp[-1].lex).loc); } -#line 6454 "MachineIndependent/glslang_tab.cpp" +#line 6516 "MachineIndependent/glslang_tab.cpp" break; case 129: /* init_declarator_list: init_declarator_list COMMA IDENTIFIER EQUAL initializer */ -#line 1171 "MachineIndependent/glslang.y" +#line 1160 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[-4].interm).type; TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-4].interm).type, 0, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate((yyvsp[-4].interm).intermNode, initNode, (yyvsp[-1].lex).loc); } -#line 6464 "MachineIndependent/glslang_tab.cpp" +#line 6526 "MachineIndependent/glslang_tab.cpp" break; case 130: /* single_declaration: fully_specified_type */ -#line 1179 "MachineIndependent/glslang.y" +#line 1168 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[0].interm.type); (yyval.interm).intermNode = 0; - parseContext.declareTypeDefaults((yyval.interm).loc, (yyval.interm).type); - } -#line 6476 "MachineIndependent/glslang_tab.cpp" +#line 6536 "MachineIndependent/glslang_tab.cpp" break; case 131: /* single_declaration: fully_specified_type IDENTIFIER */ -#line 1186 "MachineIndependent/glslang.y" +#line 1173 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[-1].interm.type); (yyval.interm).intermNode = 0; parseContext.declareVariable((yyvsp[0].lex).loc, *(yyvsp[0].lex).string, (yyvsp[-1].interm.type)); } -#line 6486 "MachineIndependent/glslang_tab.cpp" +#line 6546 "MachineIndependent/glslang_tab.cpp" break; case 132: /* single_declaration: fully_specified_type IDENTIFIER array_specifier */ -#line 1191 "MachineIndependent/glslang.y" +#line 1178 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[-2].interm.type); (yyval.interm).intermNode = 0; parseContext.declareVariable((yyvsp[-1].lex).loc, *(yyvsp[-1].lex).string, (yyvsp[-2].interm.type), (yyvsp[0].interm).arraySizes); } -#line 6496 "MachineIndependent/glslang_tab.cpp" +#line 6556 "MachineIndependent/glslang_tab.cpp" break; case 133: /* single_declaration: fully_specified_type IDENTIFIER array_specifier EQUAL initializer */ -#line 1196 "MachineIndependent/glslang.y" +#line 1183 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[-4].interm.type); TIntermNode* initNode = parseContext.declareVariable((yyvsp[-3].lex).loc, *(yyvsp[-3].lex).string, (yyvsp[-4].interm.type), (yyvsp[-2].interm).arraySizes, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); } -#line 6506 "MachineIndependent/glslang_tab.cpp" +#line 6566 "MachineIndependent/glslang_tab.cpp" break; case 134: /* single_declaration: fully_specified_type IDENTIFIER EQUAL initializer */ -#line 1201 "MachineIndependent/glslang.y" +#line 1188 "MachineIndependent/glslang.y" { (yyval.interm).type = (yyvsp[-3].interm.type); TIntermNode* initNode = parseContext.declareVariable((yyvsp[-2].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[-3].interm.type), 0, (yyvsp[0].interm.intermTypedNode)); (yyval.interm).intermNode = parseContext.intermediate.growAggregate(0, initNode, (yyvsp[-1].lex).loc); } -#line 6516 "MachineIndependent/glslang_tab.cpp" +#line 6576 "MachineIndependent/glslang_tab.cpp" break; case 135: /* fully_specified_type: type_specifier */ -#line 1210 "MachineIndependent/glslang.y" +#line 1197 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); @@ -6525,15 +6585,15 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.profileRequires((yyvsp[0].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); parseContext.profileRequires((yyvsp[0].interm.type).loc, EEsProfile, 300, 0, "arrayed type"); } - parseContext.precisionQualifierCheck((yyval.interm.type).loc, (yyval.interm.type).basicType, (yyval.interm.type).qualifier); + parseContext.precisionQualifierCheck((yyval.interm.type).loc, (yyval.interm.type).basicType, (yyval.interm.type).qualifier, (yyval.interm.type).isCoopmat()); } -#line 6531 "MachineIndependent/glslang_tab.cpp" +#line 6591 "MachineIndependent/glslang_tab.cpp" break; case 136: /* fully_specified_type: type_qualifier type_specifier */ -#line 1220 "MachineIndependent/glslang.y" +#line 1207 "MachineIndependent/glslang.y" { - parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier); + parseContext.globalQualifierFixCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, false, &(yyvsp[0].interm.type)); parseContext.globalQualifierTypeCheck((yyvsp[-1].interm.type).loc, (yyvsp[-1].interm.type).qualifier, (yyvsp[0].interm.type)); if ((yyvsp[0].interm.type).arraySizes) { @@ -6547,7 +6607,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.checkNoShaderLayouts((yyvsp[0].interm.type).loc, (yyvsp[-1].interm.type).shaderQualifiers); (yyvsp[0].interm.type).shaderQualifiers.merge((yyvsp[-1].interm.type).shaderQualifiers); parseContext.mergeQualifiers((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier, (yyvsp[-1].interm.type).qualifier, true); - parseContext.precisionQualifierCheck((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).basicType, (yyvsp[0].interm.type).qualifier); + parseContext.precisionQualifierCheck((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).basicType, (yyvsp[0].interm.type).qualifier, (yyvsp[0].interm.type).isCoopmat()); (yyval.interm.type) = (yyvsp[0].interm.type); @@ -6556,22 +6616,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (parseContext.language == EShLangFragment && (yyval.interm.type).qualifier.storage == EvqVaryingIn))) (yyval.interm.type).qualifier.smooth = true; } -#line 6560 "MachineIndependent/glslang_tab.cpp" +#line 6620 "MachineIndependent/glslang_tab.cpp" break; case 137: /* invariant_qualifier: INVARIANT */ -#line 1247 "MachineIndependent/glslang.y" +#line 1234 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "invariant"); parseContext.profileRequires((yyval.interm.type).loc, ENoProfile, 120, 0, "invariant"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.invariant = true; } -#line 6571 "MachineIndependent/glslang_tab.cpp" +#line 6631 "MachineIndependent/glslang_tab.cpp" break; case 138: /* interpolation_qualifier: SMOOTH */ -#line 1256 "MachineIndependent/glslang.y" +#line 1243 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "smooth"); parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "smooth"); @@ -6579,11 +6639,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.smooth = true; } -#line 6583 "MachineIndependent/glslang_tab.cpp" +#line 6643 "MachineIndependent/glslang_tab.cpp" break; case 139: /* interpolation_qualifier: FLAT */ -#line 1263 "MachineIndependent/glslang.y" +#line 1250 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "flat"); parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "flat"); @@ -6591,11 +6651,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.flat = true; } -#line 6595 "MachineIndependent/glslang_tab.cpp" +#line 6655 "MachineIndependent/glslang_tab.cpp" break; case 140: /* interpolation_qualifier: NOPERSPECTIVE */ -#line 1271 "MachineIndependent/glslang.y" +#line 1257 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "noperspective"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 0, E_GL_NV_shader_noperspective_interpolation, "noperspective"); @@ -6603,11 +6663,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.nopersp = true; } -#line 6607 "MachineIndependent/glslang_tab.cpp" +#line 6667 "MachineIndependent/glslang_tab.cpp" break; case 141: /* interpolation_qualifier: EXPLICITINTERPAMD */ -#line 1278 "MachineIndependent/glslang.y" +#line 1264 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "__explicitInterpAMD"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 450, E_GL_AMD_shader_explicit_vertex_parameter, "explicit interpolation"); @@ -6615,11 +6675,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.explicitInterp = true; } -#line 6619 "MachineIndependent/glslang_tab.cpp" +#line 6679 "MachineIndependent/glslang_tab.cpp" break; case 142: /* interpolation_qualifier: PERVERTEXNV */ -#line 1285 "MachineIndependent/glslang.y" +#line 1271 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "pervertexNV"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 0, E_GL_NV_fragment_shader_barycentric, "fragment shader barycentric"); @@ -6628,123 +6688,151 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.pervertexNV = true; } -#line 6632 "MachineIndependent/glslang_tab.cpp" +#line 6692 "MachineIndependent/glslang_tab.cpp" + break; + + case 143: /* interpolation_qualifier: PERVERTEXEXT */ +#line 1279 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "pervertexEXT"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 0, E_GL_EXT_fragment_shader_barycentric, "fragment shader barycentric"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECompatibilityProfile, 0, E_GL_EXT_fragment_shader_barycentric, "fragment shader barycentric"); + parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 0, E_GL_EXT_fragment_shader_barycentric, "fragment shader barycentric"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.pervertexEXT = true; + } +#line 6705 "MachineIndependent/glslang_tab.cpp" break; - case 143: /* interpolation_qualifier: PERPRIMITIVENV */ -#line 1293 "MachineIndependent/glslang.y" + case 144: /* interpolation_qualifier: PERPRIMITIVENV */ +#line 1287 "MachineIndependent/glslang.y" { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "perprimitiveNV"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshNVMask), "perprimitiveNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshMask), "perprimitiveNV"); // Fragment shader stage doesn't check for extension. So we explicitly add below extension check. if (parseContext.language == EShLangFragment) parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_NV_mesh_shader, "perprimitiveNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perPrimitiveNV = true; } -#line 6647 "MachineIndependent/glslang_tab.cpp" +#line 6720 "MachineIndependent/glslang_tab.cpp" + break; + + case 145: /* interpolation_qualifier: PERPRIMITIVEEXT */ +#line 1297 "MachineIndependent/glslang.y" + { + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck((yyvsp[0].lex).loc, "perprimitiveEXT"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangFragmentMask | EShLangMeshMask), "perprimitiveEXT"); + // Fragment shader stage doesn't check for extension. So we explicitly add below extension check. + if (parseContext.language == EShLangFragment) + parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_mesh_shader, "perprimitiveEXT"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.perPrimitiveNV = true; + } +#line 6735 "MachineIndependent/glslang_tab.cpp" break; - case 144: /* interpolation_qualifier: PERVIEWNV */ -#line 1303 "MachineIndependent/glslang.y" + case 146: /* interpolation_qualifier: PERVIEWNV */ +#line 1307 "MachineIndependent/glslang.y" { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "perviewNV"); - parseContext.requireStage((yyvsp[0].lex).loc, EShLangMeshNV, "perviewNV"); + parseContext.requireStage((yyvsp[0].lex).loc, EShLangMesh, "perviewNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perViewNV = true; } -#line 6659 "MachineIndependent/glslang_tab.cpp" +#line 6747 "MachineIndependent/glslang_tab.cpp" break; - case 145: /* interpolation_qualifier: PERTASKNV */ -#line 1310 "MachineIndependent/glslang.y" + case 147: /* interpolation_qualifier: PERTASKNV */ +#line 1314 "MachineIndependent/glslang.y" { // No need for profile version or extension check. Shader stage already checks both. parseContext.globalCheck((yyvsp[0].lex).loc, "taskNV"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTaskNVMask | EShLangMeshNVMask), "taskNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTaskMask | EShLangMeshMask), "taskNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.perTaskNV = true; } -#line 6671 "MachineIndependent/glslang_tab.cpp" +#line 6759 "MachineIndependent/glslang_tab.cpp" break; - case 146: /* layout_qualifier: LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN */ -#line 1321 "MachineIndependent/glslang.y" + case 148: /* layout_qualifier: LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN */ +#line 1324 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[-1].interm.type); } -#line 6679 "MachineIndependent/glslang_tab.cpp" +#line 6767 "MachineIndependent/glslang_tab.cpp" break; - case 147: /* layout_qualifier_id_list: layout_qualifier_id */ -#line 1327 "MachineIndependent/glslang.y" + case 149: /* layout_qualifier_id_list: layout_qualifier_id */ +#line 1330 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6687 "MachineIndependent/glslang_tab.cpp" +#line 6775 "MachineIndependent/glslang_tab.cpp" break; - case 148: /* layout_qualifier_id_list: layout_qualifier_id_list COMMA layout_qualifier_id */ -#line 1330 "MachineIndependent/glslang.y" + case 150: /* layout_qualifier_id_list: layout_qualifier_id_list COMMA layout_qualifier_id */ +#line 1333 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[-2].interm.type); (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); parseContext.mergeObjectLayoutQualifiers((yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); } -#line 6697 "MachineIndependent/glslang_tab.cpp" +#line 6785 "MachineIndependent/glslang_tab.cpp" break; - case 149: /* layout_qualifier_id: IDENTIFIER */ -#line 1337 "MachineIndependent/glslang.y" + case 151: /* layout_qualifier_id: IDENTIFIER */ +#line 1340 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), *(yyvsp[0].lex).string); } -#line 6706 "MachineIndependent/glslang_tab.cpp" +#line 6794 "MachineIndependent/glslang_tab.cpp" break; - case 150: /* layout_qualifier_id: IDENTIFIER EQUAL constant_expression */ -#line 1341 "MachineIndependent/glslang.y" + case 152: /* layout_qualifier_id: IDENTIFIER EQUAL constant_expression */ +#line 1344 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-2].lex).loc); parseContext.setLayoutQualifier((yyvsp[-2].lex).loc, (yyval.interm.type), *(yyvsp[-2].lex).string, (yyvsp[0].interm.intermTypedNode)); } -#line 6715 "MachineIndependent/glslang_tab.cpp" +#line 6803 "MachineIndependent/glslang_tab.cpp" break; - case 151: /* layout_qualifier_id: SHARED */ -#line 1345 "MachineIndependent/glslang.y" + case 153: /* layout_qualifier_id: SHARED */ +#line 1348 "MachineIndependent/glslang.y" { // because "shared" is both an identifier and a keyword (yyval.interm.type).init((yyvsp[0].lex).loc); TString strShared("shared"); parseContext.setLayoutQualifier((yyvsp[0].lex).loc, (yyval.interm.type), strShared); } -#line 6725 "MachineIndependent/glslang_tab.cpp" +#line 6813 "MachineIndependent/glslang_tab.cpp" break; - case 152: /* precise_qualifier: PRECISE */ -#line 1354 "MachineIndependent/glslang.y" + case 154: /* precise_qualifier: PRECISE */ +#line 1356 "MachineIndependent/glslang.y" { parseContext.profileRequires((yyval.interm.type).loc, ECoreProfile | ECompatibilityProfile, 400, E_GL_ARB_gpu_shader5, "precise"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 320, Num_AEP_gpu_shader5, AEP_gpu_shader5, "precise"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.noContraction = true; } -#line 6736 "MachineIndependent/glslang_tab.cpp" +#line 6824 "MachineIndependent/glslang_tab.cpp" break; - case 153: /* type_qualifier: single_type_qualifier */ -#line 1364 "MachineIndependent/glslang.y" + case 155: /* type_qualifier: single_type_qualifier */ +#line 1365 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6744 "MachineIndependent/glslang_tab.cpp" +#line 6832 "MachineIndependent/glslang_tab.cpp" break; - case 154: /* type_qualifier: type_qualifier single_type_qualifier */ -#line 1367 "MachineIndependent/glslang.y" + case 156: /* type_qualifier: type_qualifier single_type_qualifier */ +#line 1368 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[-1].interm.type); if ((yyval.interm.type).basicType == EbtVoid) @@ -6753,151 +6841,151 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).shaderQualifiers.merge((yyvsp[0].interm.type).shaderQualifiers); parseContext.mergeQualifiers((yyval.interm.type).loc, (yyval.interm.type).qualifier, (yyvsp[0].interm.type).qualifier, false); } -#line 6757 "MachineIndependent/glslang_tab.cpp" +#line 6845 "MachineIndependent/glslang_tab.cpp" break; - case 155: /* single_type_qualifier: storage_qualifier */ -#line 1378 "MachineIndependent/glslang.y" + case 157: /* single_type_qualifier: storage_qualifier */ +#line 1379 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6765 "MachineIndependent/glslang_tab.cpp" +#line 6853 "MachineIndependent/glslang_tab.cpp" break; - case 156: /* single_type_qualifier: layout_qualifier */ -#line 1381 "MachineIndependent/glslang.y" + case 158: /* single_type_qualifier: layout_qualifier */ +#line 1382 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6773 "MachineIndependent/glslang_tab.cpp" +#line 6861 "MachineIndependent/glslang_tab.cpp" break; - case 157: /* single_type_qualifier: precision_qualifier */ -#line 1384 "MachineIndependent/glslang.y" + case 159: /* single_type_qualifier: precision_qualifier */ +#line 1385 "MachineIndependent/glslang.y" { parseContext.checkPrecisionQualifier((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type).qualifier.precision); (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6782 "MachineIndependent/glslang_tab.cpp" +#line 6870 "MachineIndependent/glslang_tab.cpp" break; - case 158: /* single_type_qualifier: interpolation_qualifier */ -#line 1388 "MachineIndependent/glslang.y" + case 160: /* single_type_qualifier: interpolation_qualifier */ +#line 1389 "MachineIndependent/glslang.y" { // allow inheritance of storage qualifier from block declaration (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6791 "MachineIndependent/glslang_tab.cpp" +#line 6879 "MachineIndependent/glslang_tab.cpp" break; - case 159: /* single_type_qualifier: invariant_qualifier */ -#line 1392 "MachineIndependent/glslang.y" + case 161: /* single_type_qualifier: invariant_qualifier */ +#line 1393 "MachineIndependent/glslang.y" { // allow inheritance of storage qualifier from block declaration (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6800 "MachineIndependent/glslang_tab.cpp" +#line 6888 "MachineIndependent/glslang_tab.cpp" break; - case 160: /* single_type_qualifier: precise_qualifier */ + case 162: /* single_type_qualifier: precise_qualifier */ #line 1397 "MachineIndependent/glslang.y" { // allow inheritance of storage qualifier from block declaration (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6809 "MachineIndependent/glslang_tab.cpp" +#line 6897 "MachineIndependent/glslang_tab.cpp" break; - case 161: /* single_type_qualifier: non_uniform_qualifier */ + case 163: /* single_type_qualifier: non_uniform_qualifier */ #line 1401 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6817 "MachineIndependent/glslang_tab.cpp" +#line 6905 "MachineIndependent/glslang_tab.cpp" break; - case 162: /* single_type_qualifier: spirv_storage_class_qualifier */ + case 164: /* single_type_qualifier: spirv_storage_class_qualifier */ #line 1404 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].interm.type).loc, "spirv_storage_class"); parseContext.requireExtensions((yyvsp[0].interm.type).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V storage class qualifier"); (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6827 "MachineIndependent/glslang_tab.cpp" +#line 6915 "MachineIndependent/glslang_tab.cpp" break; - case 163: /* single_type_qualifier: spirv_decorate_qualifier */ + case 165: /* single_type_qualifier: spirv_decorate_qualifier */ #line 1409 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[0].interm.type).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V decorate qualifier"); (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 6836 "MachineIndependent/glslang_tab.cpp" +#line 6924 "MachineIndependent/glslang_tab.cpp" break; - case 164: /* single_type_qualifier: SPIRV_BY_REFERENCE */ + case 166: /* single_type_qualifier: SPIRV_BY_REFERENCE */ #line 1413 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_reference"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.setSpirvByReference(); } -#line 6846 "MachineIndependent/glslang_tab.cpp" +#line 6934 "MachineIndependent/glslang_tab.cpp" break; - case 165: /* single_type_qualifier: SPIRV_LITERAL */ + case 167: /* single_type_qualifier: SPIRV_LITERAL */ #line 1418 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_spirv_intrinsics, "spirv_by_literal"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.setSpirvLiteral(); } -#line 6856 "MachineIndependent/glslang_tab.cpp" +#line 6944 "MachineIndependent/glslang_tab.cpp" break; - case 166: /* storage_qualifier: CONST */ -#line 1427 "MachineIndependent/glslang.y" + case 168: /* storage_qualifier: CONST */ +#line 1426 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqConst; // will later turn into EvqConstReadOnly, if the initializer is not constant } -#line 6865 "MachineIndependent/glslang_tab.cpp" +#line 6953 "MachineIndependent/glslang_tab.cpp" break; - case 167: /* storage_qualifier: INOUT */ -#line 1431 "MachineIndependent/glslang.y" + case 169: /* storage_qualifier: INOUT */ +#line 1430 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "inout"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqInOut; } -#line 6875 "MachineIndependent/glslang_tab.cpp" +#line 6963 "MachineIndependent/glslang_tab.cpp" break; - case 168: /* storage_qualifier: IN */ -#line 1436 "MachineIndependent/glslang.y" + case 170: /* storage_qualifier: IN */ +#line 1435 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "in"); (yyval.interm.type).init((yyvsp[0].lex).loc); // whether this is a parameter "in" or a pipeline "in" will get sorted out a bit later (yyval.interm.type).qualifier.storage = EvqIn; } -#line 6886 "MachineIndependent/glslang_tab.cpp" +#line 6974 "MachineIndependent/glslang_tab.cpp" break; - case 169: /* storage_qualifier: OUT */ -#line 1442 "MachineIndependent/glslang.y" + case 171: /* storage_qualifier: OUT */ +#line 1441 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "out"); (yyval.interm.type).init((yyvsp[0].lex).loc); // whether this is a parameter "out" or a pipeline "out" will get sorted out a bit later (yyval.interm.type).qualifier.storage = EvqOut; } -#line 6897 "MachineIndependent/glslang_tab.cpp" +#line 6985 "MachineIndependent/glslang_tab.cpp" break; - case 170: /* storage_qualifier: CENTROID */ -#line 1448 "MachineIndependent/glslang.y" + case 172: /* storage_qualifier: CENTROID */ +#line 1447 "MachineIndependent/glslang.y" { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 120, 0, "centroid"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 300, 0, "centroid"); @@ -6905,44 +6993,54 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.centroid = true; } -#line 6909 "MachineIndependent/glslang_tab.cpp" +#line 6997 "MachineIndependent/glslang_tab.cpp" break; - case 171: /* storage_qualifier: UNIFORM */ -#line 1455 "MachineIndependent/glslang.y" + case 173: /* storage_qualifier: UNIFORM */ +#line 1454 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "uniform"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqUniform; } -#line 6919 "MachineIndependent/glslang_tab.cpp" +#line 7007 "MachineIndependent/glslang_tab.cpp" + break; + + case 174: /* storage_qualifier: TILEIMAGEEXT */ +#line 1459 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "tileImageEXT"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqTileImageEXT; + } +#line 7017 "MachineIndependent/glslang_tab.cpp" break; - case 172: /* storage_qualifier: SHARED */ -#line 1460 "MachineIndependent/glslang.y" + case 175: /* storage_qualifier: SHARED */ +#line 1464 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "shared"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, 430, E_GL_ARB_compute_shader, "shared"); parseContext.profileRequires((yyvsp[0].lex).loc, EEsProfile, 310, 0, "shared"); - parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshNVMask | EShLangTaskNVMask), "shared"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangComputeMask | EShLangMeshMask | EShLangTaskMask), "shared"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqShared; } -#line 6932 "MachineIndependent/glslang_tab.cpp" +#line 7030 "MachineIndependent/glslang_tab.cpp" break; - case 173: /* storage_qualifier: BUFFER */ -#line 1468 "MachineIndependent/glslang.y" + case 176: /* storage_qualifier: BUFFER */ +#line 1472 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "buffer"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqBuffer; } -#line 6942 "MachineIndependent/glslang_tab.cpp" +#line 7040 "MachineIndependent/glslang_tab.cpp" break; - case 174: /* storage_qualifier: ATTRIBUTE */ -#line 1474 "MachineIndependent/glslang.y" + case 177: /* storage_qualifier: ATTRIBUTE */ +#line 1477 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangVertex, "attribute"); parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "attribute"); @@ -6955,11 +7053,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 6959 "MachineIndependent/glslang_tab.cpp" +#line 7057 "MachineIndependent/glslang_tab.cpp" break; - case 175: /* storage_qualifier: VARYING */ -#line 1486 "MachineIndependent/glslang.y" + case 178: /* storage_qualifier: VARYING */ +#line 1489 "MachineIndependent/glslang.y" { parseContext.checkDeprecated((yyvsp[0].lex).loc, ENoProfile, 130, "varying"); parseContext.checkDeprecated((yyvsp[0].lex).loc, ECoreProfile, 130, "varying"); @@ -6974,45 +7072,58 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); else (yyval.interm.type).qualifier.storage = EvqVaryingIn; } -#line 6978 "MachineIndependent/glslang_tab.cpp" +#line 7076 "MachineIndependent/glslang_tab.cpp" break; - case 176: /* storage_qualifier: PATCH */ -#line 1500 "MachineIndependent/glslang.y" + case 179: /* storage_qualifier: PATCH */ +#line 1503 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "patch"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTessControlMask | EShLangTessEvaluationMask), "patch"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.patch = true; } -#line 6989 "MachineIndependent/glslang_tab.cpp" +#line 7087 "MachineIndependent/glslang_tab.cpp" break; - case 177: /* storage_qualifier: SAMPLE */ -#line 1506 "MachineIndependent/glslang.y" + case 180: /* storage_qualifier: SAMPLE */ +#line 1509 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "sample"); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.sample = true; } -#line 6999 "MachineIndependent/glslang_tab.cpp" +#line 7097 "MachineIndependent/glslang_tab.cpp" break; - case 178: /* storage_qualifier: HITATTRNV */ -#line 1511 "MachineIndependent/glslang.y" + case 181: /* storage_qualifier: HITATTRNV */ +#line 1514 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask | EShLangAnyHitMask), "hitAttributeNV"); parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_ray_tracing, "hitAttributeNV"); (yyval.interm.type).init((yyvsp[0].lex).loc); - (yyval.interm.type).qualifier.storage = EvqHitAttr; - } -#line 7012 "MachineIndependent/glslang_tab.cpp" + (yyval.interm.type).qualifier.storage = EvqHitAttr; + } +#line 7110 "MachineIndependent/glslang_tab.cpp" + break; + + case 182: /* storage_qualifier: HITOBJECTATTRNV */ +#line 1522 "MachineIndependent/glslang.y" + { + parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeNV"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask + | EShLangMissMask), "hitObjectAttributeNV"); + parseContext.profileRequires((yyvsp[0].lex).loc, ECoreProfile, 460, E_GL_NV_shader_invocation_reorder, "hitObjectAttributeNV"); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqHitObjectAttrNV; + } +#line 7123 "MachineIndependent/glslang_tab.cpp" break; - case 179: /* storage_qualifier: HITATTREXT */ -#line 1519 "MachineIndependent/glslang.y" + case 183: /* storage_qualifier: HITATTREXT */ +#line 1530 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "hitAttributeEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangIntersectMask | EShLangClosestHitMask @@ -7021,11 +7132,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqHitAttr; } -#line 7025 "MachineIndependent/glslang_tab.cpp" +#line 7136 "MachineIndependent/glslang_tab.cpp" break; - case 180: /* storage_qualifier: PAYLOADNV */ -#line 1527 "MachineIndependent/glslang.y" + case 184: /* storage_qualifier: PAYLOADNV */ +#line 1538 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | @@ -7034,11 +7145,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqPayload; } -#line 7038 "MachineIndependent/glslang_tab.cpp" +#line 7149 "MachineIndependent/glslang_tab.cpp" break; - case 181: /* storage_qualifier: PAYLOADEXT */ -#line 1535 "MachineIndependent/glslang.y" + case 185: /* storage_qualifier: PAYLOADEXT */ +#line 1546 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | EShLangClosestHitMask | @@ -7047,11 +7158,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqPayload; } -#line 7051 "MachineIndependent/glslang_tab.cpp" +#line 7162 "MachineIndependent/glslang_tab.cpp" break; - case 182: /* storage_qualifier: PAYLOADINNV */ -#line 1543 "MachineIndependent/glslang.y" + case 186: /* storage_qualifier: PAYLOADINNV */ +#line 1554 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadInNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangClosestHitMask | @@ -7060,11 +7171,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqPayloadIn; } -#line 7064 "MachineIndependent/glslang_tab.cpp" +#line 7175 "MachineIndependent/glslang_tab.cpp" break; - case 183: /* storage_qualifier: PAYLOADINEXT */ -#line 1551 "MachineIndependent/glslang.y" + case 187: /* storage_qualifier: PAYLOADINEXT */ +#line 1562 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "rayPayloadInEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangClosestHitMask | @@ -7073,11 +7184,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqPayloadIn; } -#line 7077 "MachineIndependent/glslang_tab.cpp" +#line 7188 "MachineIndependent/glslang_tab.cpp" break; - case 184: /* storage_qualifier: CALLDATANV */ -#line 1559 "MachineIndependent/glslang.y" + case 188: /* storage_qualifier: CALLDATANV */ +#line 1570 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | @@ -7086,11 +7197,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqCallableData; } -#line 7090 "MachineIndependent/glslang_tab.cpp" +#line 7201 "MachineIndependent/glslang_tab.cpp" break; - case 185: /* storage_qualifier: CALLDATAEXT */ -#line 1567 "MachineIndependent/glslang.y" + case 189: /* storage_qualifier: CALLDATAEXT */ +#line 1578 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangRayGenMask | @@ -7099,11 +7210,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqCallableData; } -#line 7103 "MachineIndependent/glslang_tab.cpp" +#line 7214 "MachineIndependent/glslang_tab.cpp" break; - case 186: /* storage_qualifier: CALLDATAINNV */ -#line 1575 "MachineIndependent/glslang.y" + case 190: /* storage_qualifier: CALLDATAINNV */ +#line 1586 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataInNV"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInNV"); @@ -7111,11 +7222,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqCallableDataIn; } -#line 7115 "MachineIndependent/glslang_tab.cpp" +#line 7226 "MachineIndependent/glslang_tab.cpp" break; - case 187: /* storage_qualifier: CALLDATAINEXT */ -#line 1582 "MachineIndependent/glslang.y" + case 191: /* storage_qualifier: CALLDATAINEXT */ +#line 1593 "MachineIndependent/glslang.y" { parseContext.globalCheck((yyvsp[0].lex).loc, "callableDataInEXT"); parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangCallableMask), "callableDataInEXT"); @@ -7123,197 +7234,212 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.storage = EvqCallableDataIn; } -#line 7127 "MachineIndependent/glslang_tab.cpp" +#line 7238 "MachineIndependent/glslang_tab.cpp" break; - case 188: /* storage_qualifier: COHERENT */ -#line 1589 "MachineIndependent/glslang.y" + case 192: /* storage_qualifier: COHERENT */ +#line 1600 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.coherent = true; } -#line 7136 "MachineIndependent/glslang_tab.cpp" +#line 7247 "MachineIndependent/glslang_tab.cpp" break; - case 189: /* storage_qualifier: DEVICECOHERENT */ -#line 1593 "MachineIndependent/glslang.y" + case 193: /* storage_qualifier: DEVICECOHERENT */ +#line 1604 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "devicecoherent"); (yyval.interm.type).qualifier.devicecoherent = true; } -#line 7146 "MachineIndependent/glslang_tab.cpp" +#line 7257 "MachineIndependent/glslang_tab.cpp" break; - case 190: /* storage_qualifier: QUEUEFAMILYCOHERENT */ -#line 1598 "MachineIndependent/glslang.y" + case 194: /* storage_qualifier: QUEUEFAMILYCOHERENT */ +#line 1609 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "queuefamilycoherent"); (yyval.interm.type).qualifier.queuefamilycoherent = true; } -#line 7156 "MachineIndependent/glslang_tab.cpp" +#line 7267 "MachineIndependent/glslang_tab.cpp" break; - case 191: /* storage_qualifier: WORKGROUPCOHERENT */ -#line 1603 "MachineIndependent/glslang.y" + case 195: /* storage_qualifier: WORKGROUPCOHERENT */ +#line 1614 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "workgroupcoherent"); (yyval.interm.type).qualifier.workgroupcoherent = true; } -#line 7166 "MachineIndependent/glslang_tab.cpp" +#line 7277 "MachineIndependent/glslang_tab.cpp" break; - case 192: /* storage_qualifier: SUBGROUPCOHERENT */ -#line 1608 "MachineIndependent/glslang.y" + case 196: /* storage_qualifier: SUBGROUPCOHERENT */ +#line 1619 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "subgroupcoherent"); (yyval.interm.type).qualifier.subgroupcoherent = true; } -#line 7176 "MachineIndependent/glslang_tab.cpp" +#line 7287 "MachineIndependent/glslang_tab.cpp" break; - case 193: /* storage_qualifier: NONPRIVATE */ -#line 1613 "MachineIndependent/glslang.y" + case 197: /* storage_qualifier: NONPRIVATE */ +#line 1624 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_KHR_memory_scope_semantics, "nonprivate"); (yyval.interm.type).qualifier.nonprivate = true; } -#line 7186 "MachineIndependent/glslang_tab.cpp" +#line 7297 "MachineIndependent/glslang_tab.cpp" break; - case 194: /* storage_qualifier: SHADERCALLCOHERENT */ -#line 1618 "MachineIndependent/glslang.y" + case 198: /* storage_qualifier: SHADERCALLCOHERENT */ +#line 1629 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); parseContext.requireExtensions((yyvsp[0].lex).loc, 1, &E_GL_EXT_ray_tracing, "shadercallcoherent"); (yyval.interm.type).qualifier.shadercallcoherent = true; } -#line 7196 "MachineIndependent/glslang_tab.cpp" +#line 7307 "MachineIndependent/glslang_tab.cpp" break; - case 195: /* storage_qualifier: VOLATILE */ -#line 1623 "MachineIndependent/glslang.y" + case 199: /* storage_qualifier: VOLATILE */ +#line 1634 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.volatil = true; } -#line 7205 "MachineIndependent/glslang_tab.cpp" +#line 7316 "MachineIndependent/glslang_tab.cpp" break; - case 196: /* storage_qualifier: RESTRICT */ -#line 1627 "MachineIndependent/glslang.y" + case 200: /* storage_qualifier: RESTRICT */ +#line 1638 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.restrict = true; } -#line 7214 "MachineIndependent/glslang_tab.cpp" +#line 7325 "MachineIndependent/glslang_tab.cpp" break; - case 197: /* storage_qualifier: READONLY */ -#line 1631 "MachineIndependent/glslang.y" + case 201: /* storage_qualifier: READONLY */ +#line 1642 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.readonly = true; } -#line 7223 "MachineIndependent/glslang_tab.cpp" +#line 7334 "MachineIndependent/glslang_tab.cpp" break; - case 198: /* storage_qualifier: WRITEONLY */ -#line 1635 "MachineIndependent/glslang.y" + case 202: /* storage_qualifier: WRITEONLY */ +#line 1646 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.writeonly = true; } -#line 7232 "MachineIndependent/glslang_tab.cpp" +#line 7343 "MachineIndependent/glslang_tab.cpp" break; - case 199: /* storage_qualifier: SUBROUTINE */ -#line 1639 "MachineIndependent/glslang.y" + case 203: /* storage_qualifier: SUBROUTINE */ +#line 1650 "MachineIndependent/glslang.y" { parseContext.spvRemoved((yyvsp[0].lex).loc, "subroutine"); parseContext.globalCheck((yyvsp[0].lex).loc, "subroutine"); parseContext.unimplemented((yyvsp[0].lex).loc, "subroutine"); (yyval.interm.type).init((yyvsp[0].lex).loc); } -#line 7243 "MachineIndependent/glslang_tab.cpp" +#line 7354 "MachineIndependent/glslang_tab.cpp" break; - case 200: /* storage_qualifier: SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN */ -#line 1645 "MachineIndependent/glslang.y" + case 204: /* storage_qualifier: SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN */ +#line 1656 "MachineIndependent/glslang.y" { parseContext.spvRemoved((yyvsp[-3].lex).loc, "subroutine"); parseContext.globalCheck((yyvsp[-3].lex).loc, "subroutine"); parseContext.unimplemented((yyvsp[-3].lex).loc, "subroutine"); (yyval.interm.type).init((yyvsp[-3].lex).loc); } -#line 7254 "MachineIndependent/glslang_tab.cpp" +#line 7365 "MachineIndependent/glslang_tab.cpp" break; - case 201: /* non_uniform_qualifier: NONUNIFORM */ -#line 1656 "MachineIndependent/glslang.y" + case 205: /* storage_qualifier: TASKPAYLOADWORKGROUPEXT */ +#line 1662 "MachineIndependent/glslang.y" + { + // No need for profile version or extension check. Shader stage already checks both. + parseContext.globalCheck((yyvsp[0].lex).loc, "taskPayloadSharedEXT"); + parseContext.requireStage((yyvsp[0].lex).loc, (EShLanguageMask)(EShLangTaskMask | EShLangMeshMask), "taskPayloadSharedEXT "); + (yyval.interm.type).init((yyvsp[0].lex).loc); + (yyval.interm.type).qualifier.storage = EvqtaskPayloadSharedEXT; + } +#line 7377 "MachineIndependent/glslang_tab.cpp" + break; + + case 206: /* non_uniform_qualifier: NONUNIFORM */ +#line 1672 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc); (yyval.interm.type).qualifier.nonUniform = true; } -#line 7263 "MachineIndependent/glslang_tab.cpp" +#line 7386 "MachineIndependent/glslang_tab.cpp" break; - case 202: /* type_name_list: IDENTIFIER */ -#line 1663 "MachineIndependent/glslang.y" + case 207: /* type_name_list: IDENTIFIER */ +#line 1679 "MachineIndependent/glslang.y" { // TODO } -#line 7271 "MachineIndependent/glslang_tab.cpp" +#line 7394 "MachineIndependent/glslang_tab.cpp" break; - case 203: /* type_name_list: type_name_list COMMA IDENTIFIER */ -#line 1666 "MachineIndependent/glslang.y" + case 208: /* type_name_list: type_name_list COMMA IDENTIFIER */ +#line 1682 "MachineIndependent/glslang.y" { // TODO: 4.0 semantics: subroutines // 1) make sure each identifier is a type declared earlier with SUBROUTINE // 2) save all of the identifiers for future comparison with the declared function } -#line 7281 "MachineIndependent/glslang_tab.cpp" +#line 7404 "MachineIndependent/glslang_tab.cpp" break; - case 204: /* type_specifier: type_specifier_nonarray type_parameter_specifier_opt */ -#line 1675 "MachineIndependent/glslang.y" + case 209: /* type_specifier: type_specifier_nonarray type_parameter_specifier_opt */ +#line 1690 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[-1].interm.type); (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); (yyval.interm.type).typeParameters = (yyvsp[0].interm.typeParameters); + parseContext.coopMatTypeParametersCheck((yyvsp[-1].interm.type).loc, (yyval.interm.type)); + } -#line 7291 "MachineIndependent/glslang_tab.cpp" +#line 7416 "MachineIndependent/glslang_tab.cpp" break; - case 205: /* type_specifier: type_specifier_nonarray type_parameter_specifier_opt array_specifier */ -#line 1680 "MachineIndependent/glslang.y" + case 210: /* type_specifier: type_specifier_nonarray type_parameter_specifier_opt array_specifier */ +#line 1697 "MachineIndependent/glslang.y" { parseContext.arrayOfArrayVersionCheck((yyvsp[0].interm).loc, (yyvsp[0].interm).arraySizes); (yyval.interm.type) = (yyvsp[-2].interm.type); (yyval.interm.type).qualifier.precision = parseContext.getDefaultPrecision((yyval.interm.type)); (yyval.interm.type).typeParameters = (yyvsp[-1].interm.typeParameters); (yyval.interm.type).arraySizes = (yyvsp[0].interm).arraySizes; + parseContext.coopMatTypeParametersCheck((yyvsp[-2].interm.type).loc, (yyval.interm.type)); } -#line 7303 "MachineIndependent/glslang_tab.cpp" +#line 7429 "MachineIndependent/glslang_tab.cpp" break; - case 206: /* array_specifier: LEFT_BRACKET RIGHT_BRACKET */ -#line 1690 "MachineIndependent/glslang.y" + case 211: /* array_specifier: LEFT_BRACKET RIGHT_BRACKET */ +#line 1708 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[-1].lex).loc; (yyval.interm).arraySizes = new TArraySizes; (yyval.interm).arraySizes->addInnerSize(); } -#line 7313 "MachineIndependent/glslang_tab.cpp" +#line 7439 "MachineIndependent/glslang_tab.cpp" break; - case 207: /* array_specifier: LEFT_BRACKET conditional_expression RIGHT_BRACKET */ -#line 1695 "MachineIndependent/glslang.y" + case 212: /* array_specifier: LEFT_BRACKET conditional_expression RIGHT_BRACKET */ +#line 1713 "MachineIndependent/glslang.y" { (yyval.interm).loc = (yyvsp[-2].lex).loc; (yyval.interm).arraySizes = new TArraySizes; @@ -7322,20 +7448,20 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); (yyval.interm).arraySizes->addInnerSize(size); } -#line 7326 "MachineIndependent/glslang_tab.cpp" +#line 7452 "MachineIndependent/glslang_tab.cpp" break; - case 208: /* array_specifier: array_specifier LEFT_BRACKET RIGHT_BRACKET */ -#line 1703 "MachineIndependent/glslang.y" + case 213: /* array_specifier: array_specifier LEFT_BRACKET RIGHT_BRACKET */ +#line 1721 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[-2].interm); (yyval.interm).arraySizes->addInnerSize(); } -#line 7335 "MachineIndependent/glslang_tab.cpp" +#line 7461 "MachineIndependent/glslang_tab.cpp" break; - case 209: /* array_specifier: array_specifier LEFT_BRACKET conditional_expression RIGHT_BRACKET */ -#line 1707 "MachineIndependent/glslang.y" + case 214: /* array_specifier: array_specifier LEFT_BRACKET conditional_expression RIGHT_BRACKET */ +#line 1725 "MachineIndependent/glslang.y" { (yyval.interm) = (yyvsp[-3].interm); @@ -7343,348 +7469,359 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.arraySizeCheck((yyvsp[-1].interm.intermTypedNode)->getLoc(), (yyvsp[-1].interm.intermTypedNode), size, "array size"); (yyval.interm).arraySizes->addInnerSize(size); } -#line 7347 "MachineIndependent/glslang_tab.cpp" +#line 7473 "MachineIndependent/glslang_tab.cpp" break; - case 210: /* type_parameter_specifier_opt: type_parameter_specifier */ -#line 1717 "MachineIndependent/glslang.y" + case 215: /* type_parameter_specifier_opt: type_parameter_specifier */ +#line 1735 "MachineIndependent/glslang.y" { (yyval.interm.typeParameters) = (yyvsp[0].interm.typeParameters); } -#line 7355 "MachineIndependent/glslang_tab.cpp" +#line 7481 "MachineIndependent/glslang_tab.cpp" break; - case 211: /* type_parameter_specifier_opt: %empty */ -#line 1720 "MachineIndependent/glslang.y" + case 216: /* type_parameter_specifier_opt: %empty */ +#line 1738 "MachineIndependent/glslang.y" { (yyval.interm.typeParameters) = 0; } -#line 7363 "MachineIndependent/glslang_tab.cpp" +#line 7489 "MachineIndependent/glslang_tab.cpp" break; - case 212: /* type_parameter_specifier: LEFT_ANGLE type_parameter_specifier_list RIGHT_ANGLE */ -#line 1726 "MachineIndependent/glslang.y" + case 217: /* type_parameter_specifier: LEFT_ANGLE type_parameter_specifier_list RIGHT_ANGLE */ +#line 1744 "MachineIndependent/glslang.y" { (yyval.interm.typeParameters) = (yyvsp[-1].interm.typeParameters); } -#line 7371 "MachineIndependent/glslang_tab.cpp" +#line 7497 "MachineIndependent/glslang_tab.cpp" break; - case 213: /* type_parameter_specifier_list: unary_expression */ -#line 1732 "MachineIndependent/glslang.y" + case 218: /* type_parameter_specifier_list: type_specifier */ +#line 1750 "MachineIndependent/glslang.y" + { + (yyval.interm.typeParameters) = new TTypeParameters; + (yyval.interm.typeParameters)->arraySizes = new TArraySizes; + (yyval.interm.typeParameters)->basicType = (yyvsp[0].interm.type).basicType; + } +#line 7507 "MachineIndependent/glslang_tab.cpp" + break; + + case 219: /* type_parameter_specifier_list: unary_expression */ +#line 1755 "MachineIndependent/glslang.y" { - (yyval.interm.typeParameters) = new TArraySizes; + (yyval.interm.typeParameters) = new TTypeParameters; + (yyval.interm.typeParameters)->arraySizes = new TArraySizes; TArraySize size; - parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter"); - (yyval.interm.typeParameters)->addInnerSize(size); + parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter", true); + (yyval.interm.typeParameters)->arraySizes->addInnerSize(size); } -#line 7383 "MachineIndependent/glslang_tab.cpp" +#line 7520 "MachineIndependent/glslang_tab.cpp" break; - case 214: /* type_parameter_specifier_list: type_parameter_specifier_list COMMA unary_expression */ -#line 1739 "MachineIndependent/glslang.y" + case 220: /* type_parameter_specifier_list: type_parameter_specifier_list COMMA unary_expression */ +#line 1763 "MachineIndependent/glslang.y" { (yyval.interm.typeParameters) = (yyvsp[-2].interm.typeParameters); TArraySize size; - parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter"); - (yyval.interm.typeParameters)->addInnerSize(size); + parseContext.arraySizeCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode), size, "type parameter", true); + (yyval.interm.typeParameters)->arraySizes->addInnerSize(size); } -#line 7395 "MachineIndependent/glslang_tab.cpp" +#line 7532 "MachineIndependent/glslang_tab.cpp" break; - case 215: /* type_specifier_nonarray: VOID */ -#line 1749 "MachineIndependent/glslang.y" + case 221: /* type_specifier_nonarray: VOID */ +#line 1773 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtVoid; } -#line 7404 "MachineIndependent/glslang_tab.cpp" +#line 7541 "MachineIndependent/glslang_tab.cpp" break; - case 216: /* type_specifier_nonarray: FLOAT */ -#line 1753 "MachineIndependent/glslang.y" + case 222: /* type_specifier_nonarray: FLOAT */ +#line 1777 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; } -#line 7413 "MachineIndependent/glslang_tab.cpp" +#line 7550 "MachineIndependent/glslang_tab.cpp" break; - case 217: /* type_specifier_nonarray: INT */ -#line 1757 "MachineIndependent/glslang.y" + case 223: /* type_specifier_nonarray: INT */ +#line 1781 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; } -#line 7422 "MachineIndependent/glslang_tab.cpp" +#line 7559 "MachineIndependent/glslang_tab.cpp" break; - case 218: /* type_specifier_nonarray: UINT */ -#line 1761 "MachineIndependent/glslang.y" + case 224: /* type_specifier_nonarray: UINT */ +#line 1785 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; } -#line 7432 "MachineIndependent/glslang_tab.cpp" +#line 7569 "MachineIndependent/glslang_tab.cpp" break; - case 219: /* type_specifier_nonarray: BOOL */ -#line 1766 "MachineIndependent/glslang.y" + case 225: /* type_specifier_nonarray: BOOL */ +#line 1790 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtBool; } -#line 7441 "MachineIndependent/glslang_tab.cpp" +#line 7578 "MachineIndependent/glslang_tab.cpp" break; - case 220: /* type_specifier_nonarray: VEC2 */ -#line 1770 "MachineIndependent/glslang.y" + case 226: /* type_specifier_nonarray: VEC2 */ +#line 1794 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(2); } -#line 7451 "MachineIndependent/glslang_tab.cpp" +#line 7588 "MachineIndependent/glslang_tab.cpp" break; - case 221: /* type_specifier_nonarray: VEC3 */ -#line 1775 "MachineIndependent/glslang.y" + case 227: /* type_specifier_nonarray: VEC3 */ +#line 1799 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(3); } -#line 7461 "MachineIndependent/glslang_tab.cpp" +#line 7598 "MachineIndependent/glslang_tab.cpp" break; - case 222: /* type_specifier_nonarray: VEC4 */ -#line 1780 "MachineIndependent/glslang.y" + case 228: /* type_specifier_nonarray: VEC4 */ +#line 1804 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(4); } -#line 7471 "MachineIndependent/glslang_tab.cpp" +#line 7608 "MachineIndependent/glslang_tab.cpp" break; - case 223: /* type_specifier_nonarray: BVEC2 */ -#line 1785 "MachineIndependent/glslang.y" + case 229: /* type_specifier_nonarray: BVEC2 */ +#line 1809 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtBool; (yyval.interm.type).setVector(2); } -#line 7481 "MachineIndependent/glslang_tab.cpp" +#line 7618 "MachineIndependent/glslang_tab.cpp" break; - case 224: /* type_specifier_nonarray: BVEC3 */ -#line 1790 "MachineIndependent/glslang.y" + case 230: /* type_specifier_nonarray: BVEC3 */ +#line 1814 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtBool; (yyval.interm.type).setVector(3); } -#line 7491 "MachineIndependent/glslang_tab.cpp" +#line 7628 "MachineIndependent/glslang_tab.cpp" break; - case 225: /* type_specifier_nonarray: BVEC4 */ -#line 1795 "MachineIndependent/glslang.y" + case 231: /* type_specifier_nonarray: BVEC4 */ +#line 1819 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtBool; (yyval.interm.type).setVector(4); } -#line 7501 "MachineIndependent/glslang_tab.cpp" +#line 7638 "MachineIndependent/glslang_tab.cpp" break; - case 226: /* type_specifier_nonarray: IVEC2 */ -#line 1800 "MachineIndependent/glslang.y" + case 232: /* type_specifier_nonarray: IVEC2 */ +#line 1824 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(2); } -#line 7511 "MachineIndependent/glslang_tab.cpp" +#line 7648 "MachineIndependent/glslang_tab.cpp" break; - case 227: /* type_specifier_nonarray: IVEC3 */ -#line 1805 "MachineIndependent/glslang.y" + case 233: /* type_specifier_nonarray: IVEC3 */ +#line 1829 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(3); } -#line 7521 "MachineIndependent/glslang_tab.cpp" +#line 7658 "MachineIndependent/glslang_tab.cpp" break; - case 228: /* type_specifier_nonarray: IVEC4 */ -#line 1810 "MachineIndependent/glslang.y" + case 234: /* type_specifier_nonarray: IVEC4 */ +#line 1834 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(4); } -#line 7531 "MachineIndependent/glslang_tab.cpp" +#line 7668 "MachineIndependent/glslang_tab.cpp" break; - case 229: /* type_specifier_nonarray: UVEC2 */ -#line 1815 "MachineIndependent/glslang.y" + case 235: /* type_specifier_nonarray: UVEC2 */ +#line 1839 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(2); } -#line 7542 "MachineIndependent/glslang_tab.cpp" +#line 7679 "MachineIndependent/glslang_tab.cpp" break; - case 230: /* type_specifier_nonarray: UVEC3 */ -#line 1821 "MachineIndependent/glslang.y" + case 236: /* type_specifier_nonarray: UVEC3 */ +#line 1845 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(3); } -#line 7553 "MachineIndependent/glslang_tab.cpp" +#line 7690 "MachineIndependent/glslang_tab.cpp" break; - case 231: /* type_specifier_nonarray: UVEC4 */ -#line 1827 "MachineIndependent/glslang.y" + case 237: /* type_specifier_nonarray: UVEC4 */ +#line 1851 "MachineIndependent/glslang.y" { parseContext.fullIntegerCheck((yyvsp[0].lex).loc, "unsigned integer vector"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(4); } -#line 7564 "MachineIndependent/glslang_tab.cpp" +#line 7701 "MachineIndependent/glslang_tab.cpp" break; - case 232: /* type_specifier_nonarray: MAT2 */ -#line 1833 "MachineIndependent/glslang.y" + case 238: /* type_specifier_nonarray: MAT2 */ +#line 1857 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 7574 "MachineIndependent/glslang_tab.cpp" +#line 7711 "MachineIndependent/glslang_tab.cpp" break; - case 233: /* type_specifier_nonarray: MAT3 */ -#line 1838 "MachineIndependent/glslang.y" + case 239: /* type_specifier_nonarray: MAT3 */ +#line 1862 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 7584 "MachineIndependent/glslang_tab.cpp" +#line 7721 "MachineIndependent/glslang_tab.cpp" break; - case 234: /* type_specifier_nonarray: MAT4 */ -#line 1843 "MachineIndependent/glslang.y" + case 240: /* type_specifier_nonarray: MAT4 */ +#line 1867 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 7594 "MachineIndependent/glslang_tab.cpp" +#line 7731 "MachineIndependent/glslang_tab.cpp" break; - case 235: /* type_specifier_nonarray: MAT2X2 */ -#line 1848 "MachineIndependent/glslang.y" + case 241: /* type_specifier_nonarray: MAT2X2 */ +#line 1872 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 7604 "MachineIndependent/glslang_tab.cpp" +#line 7741 "MachineIndependent/glslang_tab.cpp" break; - case 236: /* type_specifier_nonarray: MAT2X3 */ -#line 1853 "MachineIndependent/glslang.y" + case 242: /* type_specifier_nonarray: MAT2X3 */ +#line 1877 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 3); } -#line 7614 "MachineIndependent/glslang_tab.cpp" +#line 7751 "MachineIndependent/glslang_tab.cpp" break; - case 237: /* type_specifier_nonarray: MAT2X4 */ -#line 1858 "MachineIndependent/glslang.y" + case 243: /* type_specifier_nonarray: MAT2X4 */ +#line 1882 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 4); } -#line 7624 "MachineIndependent/glslang_tab.cpp" +#line 7761 "MachineIndependent/glslang_tab.cpp" break; - case 238: /* type_specifier_nonarray: MAT3X2 */ -#line 1863 "MachineIndependent/glslang.y" + case 244: /* type_specifier_nonarray: MAT3X2 */ +#line 1887 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 2); } -#line 7634 "MachineIndependent/glslang_tab.cpp" +#line 7771 "MachineIndependent/glslang_tab.cpp" break; - case 239: /* type_specifier_nonarray: MAT3X3 */ -#line 1868 "MachineIndependent/glslang.y" + case 245: /* type_specifier_nonarray: MAT3X3 */ +#line 1892 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 7644 "MachineIndependent/glslang_tab.cpp" +#line 7781 "MachineIndependent/glslang_tab.cpp" break; - case 240: /* type_specifier_nonarray: MAT3X4 */ -#line 1873 "MachineIndependent/glslang.y" + case 246: /* type_specifier_nonarray: MAT3X4 */ +#line 1897 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 4); } -#line 7654 "MachineIndependent/glslang_tab.cpp" +#line 7791 "MachineIndependent/glslang_tab.cpp" break; - case 241: /* type_specifier_nonarray: MAT4X2 */ -#line 1878 "MachineIndependent/glslang.y" + case 247: /* type_specifier_nonarray: MAT4X2 */ +#line 1902 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 2); } -#line 7664 "MachineIndependent/glslang_tab.cpp" +#line 7801 "MachineIndependent/glslang_tab.cpp" break; - case 242: /* type_specifier_nonarray: MAT4X3 */ -#line 1883 "MachineIndependent/glslang.y" + case 248: /* type_specifier_nonarray: MAT4X3 */ +#line 1907 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 3); } -#line 7674 "MachineIndependent/glslang_tab.cpp" +#line 7811 "MachineIndependent/glslang_tab.cpp" break; - case 243: /* type_specifier_nonarray: MAT4X4 */ -#line 1888 "MachineIndependent/glslang.y" + case 249: /* type_specifier_nonarray: MAT4X4 */ +#line 1912 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 7684 "MachineIndependent/glslang_tab.cpp" +#line 7821 "MachineIndependent/glslang_tab.cpp" break; - case 244: /* type_specifier_nonarray: DOUBLE */ -#line 1894 "MachineIndependent/glslang.y" + case 250: /* type_specifier_nonarray: DOUBLE */ +#line 1917 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7692,121 +7829,121 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; } -#line 7696 "MachineIndependent/glslang_tab.cpp" +#line 7833 "MachineIndependent/glslang_tab.cpp" break; - case 245: /* type_specifier_nonarray: FLOAT16_T */ -#line 1901 "MachineIndependent/glslang.y" + case 251: /* type_specifier_nonarray: FLOAT16_T */ +#line 1924 "MachineIndependent/glslang.y" { parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "float16_t", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; } -#line 7706 "MachineIndependent/glslang_tab.cpp" +#line 7843 "MachineIndependent/glslang_tab.cpp" break; - case 246: /* type_specifier_nonarray: FLOAT32_T */ -#line 1906 "MachineIndependent/glslang.y" + case 252: /* type_specifier_nonarray: FLOAT32_T */ +#line 1929 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; } -#line 7716 "MachineIndependent/glslang_tab.cpp" +#line 7853 "MachineIndependent/glslang_tab.cpp" break; - case 247: /* type_specifier_nonarray: FLOAT64_T */ -#line 1911 "MachineIndependent/glslang.y" + case 253: /* type_specifier_nonarray: FLOAT64_T */ +#line 1934 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; } -#line 7726 "MachineIndependent/glslang_tab.cpp" +#line 7863 "MachineIndependent/glslang_tab.cpp" break; - case 248: /* type_specifier_nonarray: INT8_T */ -#line 1916 "MachineIndependent/glslang.y" + case 254: /* type_specifier_nonarray: INT8_T */ +#line 1939 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; } -#line 7736 "MachineIndependent/glslang_tab.cpp" +#line 7873 "MachineIndependent/glslang_tab.cpp" break; - case 249: /* type_specifier_nonarray: UINT8_T */ -#line 1921 "MachineIndependent/glslang.y" + case 255: /* type_specifier_nonarray: UINT8_T */ +#line 1944 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint8; } -#line 7746 "MachineIndependent/glslang_tab.cpp" +#line 7883 "MachineIndependent/glslang_tab.cpp" break; - case 250: /* type_specifier_nonarray: INT16_T */ -#line 1926 "MachineIndependent/glslang.y" + case 256: /* type_specifier_nonarray: INT16_T */ +#line 1949 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt16; } -#line 7756 "MachineIndependent/glslang_tab.cpp" +#line 7893 "MachineIndependent/glslang_tab.cpp" break; - case 251: /* type_specifier_nonarray: UINT16_T */ -#line 1931 "MachineIndependent/glslang.y" + case 257: /* type_specifier_nonarray: UINT16_T */ +#line 1954 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint16; } -#line 7766 "MachineIndependent/glslang_tab.cpp" +#line 7903 "MachineIndependent/glslang_tab.cpp" break; - case 252: /* type_specifier_nonarray: INT32_T */ -#line 1936 "MachineIndependent/glslang.y" + case 258: /* type_specifier_nonarray: INT32_T */ +#line 1959 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; } -#line 7776 "MachineIndependent/glslang_tab.cpp" +#line 7913 "MachineIndependent/glslang_tab.cpp" break; - case 253: /* type_specifier_nonarray: UINT32_T */ -#line 1941 "MachineIndependent/glslang.y" + case 259: /* type_specifier_nonarray: UINT32_T */ +#line 1964 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; } -#line 7786 "MachineIndependent/glslang_tab.cpp" +#line 7923 "MachineIndependent/glslang_tab.cpp" break; - case 254: /* type_specifier_nonarray: INT64_T */ -#line 1946 "MachineIndependent/glslang.y" + case 260: /* type_specifier_nonarray: INT64_T */ +#line 1969 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; } -#line 7796 "MachineIndependent/glslang_tab.cpp" +#line 7933 "MachineIndependent/glslang_tab.cpp" break; - case 255: /* type_specifier_nonarray: UINT64_T */ -#line 1951 "MachineIndependent/glslang.y" + case 261: /* type_specifier_nonarray: UINT64_T */ +#line 1974 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; } -#line 7806 "MachineIndependent/glslang_tab.cpp" +#line 7943 "MachineIndependent/glslang_tab.cpp" break; - case 256: /* type_specifier_nonarray: DVEC2 */ -#line 1956 "MachineIndependent/glslang.y" + case 262: /* type_specifier_nonarray: DVEC2 */ +#line 1979 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7815,11 +7952,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(2); } -#line 7819 "MachineIndependent/glslang_tab.cpp" +#line 7956 "MachineIndependent/glslang_tab.cpp" break; - case 257: /* type_specifier_nonarray: DVEC3 */ -#line 1964 "MachineIndependent/glslang.y" + case 263: /* type_specifier_nonarray: DVEC3 */ +#line 1987 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7828,11 +7965,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(3); } -#line 7832 "MachineIndependent/glslang_tab.cpp" +#line 7969 "MachineIndependent/glslang_tab.cpp" break; - case 258: /* type_specifier_nonarray: DVEC4 */ -#line 1972 "MachineIndependent/glslang.y" + case 264: /* type_specifier_nonarray: DVEC4 */ +#line 1995 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double vector"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -7841,374 +7978,374 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(4); } -#line 7845 "MachineIndependent/glslang_tab.cpp" +#line 7982 "MachineIndependent/glslang_tab.cpp" break; - case 259: /* type_specifier_nonarray: F16VEC2 */ -#line 1980 "MachineIndependent/glslang.y" + case 265: /* type_specifier_nonarray: F16VEC2 */ +#line 2003 "MachineIndependent/glslang.y" { parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setVector(2); } -#line 7856 "MachineIndependent/glslang_tab.cpp" +#line 7993 "MachineIndependent/glslang_tab.cpp" break; - case 260: /* type_specifier_nonarray: F16VEC3 */ -#line 1986 "MachineIndependent/glslang.y" + case 266: /* type_specifier_nonarray: F16VEC3 */ +#line 2009 "MachineIndependent/glslang.y" { parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setVector(3); } -#line 7867 "MachineIndependent/glslang_tab.cpp" +#line 8004 "MachineIndependent/glslang_tab.cpp" break; - case 261: /* type_specifier_nonarray: F16VEC4 */ -#line 1992 "MachineIndependent/glslang.y" + case 267: /* type_specifier_nonarray: F16VEC4 */ +#line 2015 "MachineIndependent/glslang.y" { parseContext.float16ScalarVectorCheck((yyvsp[0].lex).loc, "half float vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setVector(4); } -#line 7878 "MachineIndependent/glslang_tab.cpp" +#line 8015 "MachineIndependent/glslang_tab.cpp" break; - case 262: /* type_specifier_nonarray: F32VEC2 */ -#line 1998 "MachineIndependent/glslang.y" + case 268: /* type_specifier_nonarray: F32VEC2 */ +#line 2021 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(2); } -#line 7889 "MachineIndependent/glslang_tab.cpp" +#line 8026 "MachineIndependent/glslang_tab.cpp" break; - case 263: /* type_specifier_nonarray: F32VEC3 */ -#line 2004 "MachineIndependent/glslang.y" + case 269: /* type_specifier_nonarray: F32VEC3 */ +#line 2027 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(3); } -#line 7900 "MachineIndependent/glslang_tab.cpp" +#line 8037 "MachineIndependent/glslang_tab.cpp" break; - case 264: /* type_specifier_nonarray: F32VEC4 */ -#line 2010 "MachineIndependent/glslang.y" + case 270: /* type_specifier_nonarray: F32VEC4 */ +#line 2033 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setVector(4); } -#line 7911 "MachineIndependent/glslang_tab.cpp" +#line 8048 "MachineIndependent/glslang_tab.cpp" break; - case 265: /* type_specifier_nonarray: F64VEC2 */ -#line 2016 "MachineIndependent/glslang.y" + case 271: /* type_specifier_nonarray: F64VEC2 */ +#line 2039 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(2); } -#line 7922 "MachineIndependent/glslang_tab.cpp" +#line 8059 "MachineIndependent/glslang_tab.cpp" break; - case 266: /* type_specifier_nonarray: F64VEC3 */ -#line 2022 "MachineIndependent/glslang.y" + case 272: /* type_specifier_nonarray: F64VEC3 */ +#line 2045 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(3); } -#line 7933 "MachineIndependent/glslang_tab.cpp" +#line 8070 "MachineIndependent/glslang_tab.cpp" break; - case 267: /* type_specifier_nonarray: F64VEC4 */ -#line 2028 "MachineIndependent/glslang.y" + case 273: /* type_specifier_nonarray: F64VEC4 */ +#line 2051 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setVector(4); } -#line 7944 "MachineIndependent/glslang_tab.cpp" +#line 8081 "MachineIndependent/glslang_tab.cpp" break; - case 268: /* type_specifier_nonarray: I8VEC2 */ -#line 2034 "MachineIndependent/glslang.y" + case 274: /* type_specifier_nonarray: I8VEC2 */ +#line 2057 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; (yyval.interm.type).setVector(2); } -#line 7955 "MachineIndependent/glslang_tab.cpp" +#line 8092 "MachineIndependent/glslang_tab.cpp" break; - case 269: /* type_specifier_nonarray: I8VEC3 */ -#line 2040 "MachineIndependent/glslang.y" + case 275: /* type_specifier_nonarray: I8VEC3 */ +#line 2063 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; (yyval.interm.type).setVector(3); } -#line 7966 "MachineIndependent/glslang_tab.cpp" +#line 8103 "MachineIndependent/glslang_tab.cpp" break; - case 270: /* type_specifier_nonarray: I8VEC4 */ -#line 2046 "MachineIndependent/glslang.y" + case 276: /* type_specifier_nonarray: I8VEC4 */ +#line 2069 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt8; (yyval.interm.type).setVector(4); } -#line 7977 "MachineIndependent/glslang_tab.cpp" +#line 8114 "MachineIndependent/glslang_tab.cpp" break; - case 271: /* type_specifier_nonarray: I16VEC2 */ -#line 2052 "MachineIndependent/glslang.y" + case 277: /* type_specifier_nonarray: I16VEC2 */ +#line 2075 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt16; (yyval.interm.type).setVector(2); } -#line 7988 "MachineIndependent/glslang_tab.cpp" +#line 8125 "MachineIndependent/glslang_tab.cpp" break; - case 272: /* type_specifier_nonarray: I16VEC3 */ -#line 2058 "MachineIndependent/glslang.y" + case 278: /* type_specifier_nonarray: I16VEC3 */ +#line 2081 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt16; (yyval.interm.type).setVector(3); } -#line 7999 "MachineIndependent/glslang_tab.cpp" +#line 8136 "MachineIndependent/glslang_tab.cpp" break; - case 273: /* type_specifier_nonarray: I16VEC4 */ -#line 2064 "MachineIndependent/glslang.y" + case 279: /* type_specifier_nonarray: I16VEC4 */ +#line 2087 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt16; (yyval.interm.type).setVector(4); } -#line 8010 "MachineIndependent/glslang_tab.cpp" +#line 8147 "MachineIndependent/glslang_tab.cpp" break; - case 274: /* type_specifier_nonarray: I32VEC2 */ -#line 2070 "MachineIndependent/glslang.y" + case 280: /* type_specifier_nonarray: I32VEC2 */ +#line 2093 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(2); } -#line 8021 "MachineIndependent/glslang_tab.cpp" +#line 8158 "MachineIndependent/glslang_tab.cpp" break; - case 275: /* type_specifier_nonarray: I32VEC3 */ -#line 2076 "MachineIndependent/glslang.y" + case 281: /* type_specifier_nonarray: I32VEC3 */ +#line 2099 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(3); } -#line 8032 "MachineIndependent/glslang_tab.cpp" +#line 8169 "MachineIndependent/glslang_tab.cpp" break; - case 276: /* type_specifier_nonarray: I32VEC4 */ -#line 2082 "MachineIndependent/glslang.y" + case 282: /* type_specifier_nonarray: I32VEC4 */ +#line 2105 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit signed integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; (yyval.interm.type).setVector(4); } -#line 8043 "MachineIndependent/glslang_tab.cpp" +#line 8180 "MachineIndependent/glslang_tab.cpp" break; - case 277: /* type_specifier_nonarray: I64VEC2 */ -#line 2088 "MachineIndependent/glslang.y" + case 283: /* type_specifier_nonarray: I64VEC2 */ +#line 2111 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; (yyval.interm.type).setVector(2); } -#line 8054 "MachineIndependent/glslang_tab.cpp" +#line 8191 "MachineIndependent/glslang_tab.cpp" break; - case 278: /* type_specifier_nonarray: I64VEC3 */ -#line 2094 "MachineIndependent/glslang.y" + case 284: /* type_specifier_nonarray: I64VEC3 */ +#line 2117 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; (yyval.interm.type).setVector(3); } -#line 8065 "MachineIndependent/glslang_tab.cpp" +#line 8202 "MachineIndependent/glslang_tab.cpp" break; - case 279: /* type_specifier_nonarray: I64VEC4 */ -#line 2100 "MachineIndependent/glslang.y" + case 285: /* type_specifier_nonarray: I64VEC4 */ +#line 2123 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt64; (yyval.interm.type).setVector(4); } -#line 8076 "MachineIndependent/glslang_tab.cpp" +#line 8213 "MachineIndependent/glslang_tab.cpp" break; - case 280: /* type_specifier_nonarray: U8VEC2 */ -#line 2106 "MachineIndependent/glslang.y" + case 286: /* type_specifier_nonarray: U8VEC2 */ +#line 2129 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint8; (yyval.interm.type).setVector(2); } -#line 8087 "MachineIndependent/glslang_tab.cpp" +#line 8224 "MachineIndependent/glslang_tab.cpp" break; - case 281: /* type_specifier_nonarray: U8VEC3 */ -#line 2112 "MachineIndependent/glslang.y" + case 287: /* type_specifier_nonarray: U8VEC3 */ +#line 2135 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint8; (yyval.interm.type).setVector(3); } -#line 8098 "MachineIndependent/glslang_tab.cpp" +#line 8235 "MachineIndependent/glslang_tab.cpp" break; - case 282: /* type_specifier_nonarray: U8VEC4 */ -#line 2118 "MachineIndependent/glslang.y" + case 288: /* type_specifier_nonarray: U8VEC4 */ +#line 2141 "MachineIndependent/glslang.y" { parseContext.int8ScalarVectorCheck((yyvsp[0].lex).loc, "8-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint8; (yyval.interm.type).setVector(4); } -#line 8109 "MachineIndependent/glslang_tab.cpp" +#line 8246 "MachineIndependent/glslang_tab.cpp" break; - case 283: /* type_specifier_nonarray: U16VEC2 */ -#line 2124 "MachineIndependent/glslang.y" + case 289: /* type_specifier_nonarray: U16VEC2 */ +#line 2147 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint16; (yyval.interm.type).setVector(2); } -#line 8120 "MachineIndependent/glslang_tab.cpp" +#line 8257 "MachineIndependent/glslang_tab.cpp" break; - case 284: /* type_specifier_nonarray: U16VEC3 */ -#line 2130 "MachineIndependent/glslang.y" + case 290: /* type_specifier_nonarray: U16VEC3 */ +#line 2153 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint16; (yyval.interm.type).setVector(3); } -#line 8131 "MachineIndependent/glslang_tab.cpp" +#line 8268 "MachineIndependent/glslang_tab.cpp" break; - case 285: /* type_specifier_nonarray: U16VEC4 */ -#line 2136 "MachineIndependent/glslang.y" + case 291: /* type_specifier_nonarray: U16VEC4 */ +#line 2159 "MachineIndependent/glslang.y" { parseContext.int16ScalarVectorCheck((yyvsp[0].lex).loc, "16-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint16; (yyval.interm.type).setVector(4); } -#line 8142 "MachineIndependent/glslang_tab.cpp" +#line 8279 "MachineIndependent/glslang_tab.cpp" break; - case 286: /* type_specifier_nonarray: U32VEC2 */ -#line 2142 "MachineIndependent/glslang.y" + case 292: /* type_specifier_nonarray: U32VEC2 */ +#line 2165 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(2); } -#line 8153 "MachineIndependent/glslang_tab.cpp" +#line 8290 "MachineIndependent/glslang_tab.cpp" break; - case 287: /* type_specifier_nonarray: U32VEC3 */ -#line 2148 "MachineIndependent/glslang.y" + case 293: /* type_specifier_nonarray: U32VEC3 */ +#line 2171 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(3); } -#line 8164 "MachineIndependent/glslang_tab.cpp" +#line 8301 "MachineIndependent/glslang_tab.cpp" break; - case 288: /* type_specifier_nonarray: U32VEC4 */ -#line 2154 "MachineIndependent/glslang.y" + case 294: /* type_specifier_nonarray: U32VEC4 */ +#line 2177 "MachineIndependent/glslang.y" { parseContext.explicitInt32Check((yyvsp[0].lex).loc, "32-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; (yyval.interm.type).setVector(4); } -#line 8175 "MachineIndependent/glslang_tab.cpp" +#line 8312 "MachineIndependent/glslang_tab.cpp" break; - case 289: /* type_specifier_nonarray: U64VEC2 */ -#line 2160 "MachineIndependent/glslang.y" + case 295: /* type_specifier_nonarray: U64VEC2 */ +#line 2183 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; (yyval.interm.type).setVector(2); } -#line 8186 "MachineIndependent/glslang_tab.cpp" +#line 8323 "MachineIndependent/glslang_tab.cpp" break; - case 290: /* type_specifier_nonarray: U64VEC3 */ -#line 2166 "MachineIndependent/glslang.y" + case 296: /* type_specifier_nonarray: U64VEC3 */ +#line 2189 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; (yyval.interm.type).setVector(3); } -#line 8197 "MachineIndependent/glslang_tab.cpp" +#line 8334 "MachineIndependent/glslang_tab.cpp" break; - case 291: /* type_specifier_nonarray: U64VEC4 */ -#line 2172 "MachineIndependent/glslang.y" + case 297: /* type_specifier_nonarray: U64VEC4 */ +#line 2195 "MachineIndependent/glslang.y" { parseContext.int64Check((yyvsp[0].lex).loc, "64-bit unsigned integer vector", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint64; (yyval.interm.type).setVector(4); } -#line 8208 "MachineIndependent/glslang_tab.cpp" +#line 8345 "MachineIndependent/glslang_tab.cpp" break; - case 292: /* type_specifier_nonarray: DMAT2 */ -#line 2178 "MachineIndependent/glslang.y" + case 298: /* type_specifier_nonarray: DMAT2 */ +#line 2201 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8217,11 +8354,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 8221 "MachineIndependent/glslang_tab.cpp" +#line 8358 "MachineIndependent/glslang_tab.cpp" break; - case 293: /* type_specifier_nonarray: DMAT3 */ -#line 2186 "MachineIndependent/glslang.y" + case 299: /* type_specifier_nonarray: DMAT3 */ +#line 2209 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8230,11 +8367,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 8234 "MachineIndependent/glslang_tab.cpp" +#line 8371 "MachineIndependent/glslang_tab.cpp" break; - case 294: /* type_specifier_nonarray: DMAT4 */ -#line 2194 "MachineIndependent/glslang.y" + case 300: /* type_specifier_nonarray: DMAT4 */ +#line 2217 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8243,11 +8380,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 8247 "MachineIndependent/glslang_tab.cpp" +#line 8384 "MachineIndependent/glslang_tab.cpp" break; - case 295: /* type_specifier_nonarray: DMAT2X2 */ -#line 2202 "MachineIndependent/glslang.y" + case 301: /* type_specifier_nonarray: DMAT2X2 */ +#line 2225 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8256,11 +8393,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 8260 "MachineIndependent/glslang_tab.cpp" +#line 8397 "MachineIndependent/glslang_tab.cpp" break; - case 296: /* type_specifier_nonarray: DMAT2X3 */ -#line 2210 "MachineIndependent/glslang.y" + case 302: /* type_specifier_nonarray: DMAT2X3 */ +#line 2233 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8269,11 +8406,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 3); } -#line 8273 "MachineIndependent/glslang_tab.cpp" +#line 8410 "MachineIndependent/glslang_tab.cpp" break; - case 297: /* type_specifier_nonarray: DMAT2X4 */ -#line 2218 "MachineIndependent/glslang.y" + case 303: /* type_specifier_nonarray: DMAT2X4 */ +#line 2241 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8282,11 +8419,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 4); } -#line 8286 "MachineIndependent/glslang_tab.cpp" +#line 8423 "MachineIndependent/glslang_tab.cpp" break; - case 298: /* type_specifier_nonarray: DMAT3X2 */ -#line 2226 "MachineIndependent/glslang.y" + case 304: /* type_specifier_nonarray: DMAT3X2 */ +#line 2249 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8295,11 +8432,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 2); } -#line 8299 "MachineIndependent/glslang_tab.cpp" +#line 8436 "MachineIndependent/glslang_tab.cpp" break; - case 299: /* type_specifier_nonarray: DMAT3X3 */ -#line 2234 "MachineIndependent/glslang.y" + case 305: /* type_specifier_nonarray: DMAT3X3 */ +#line 2257 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8308,11 +8445,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 8312 "MachineIndependent/glslang_tab.cpp" +#line 8449 "MachineIndependent/glslang_tab.cpp" break; - case 300: /* type_specifier_nonarray: DMAT3X4 */ -#line 2242 "MachineIndependent/glslang.y" + case 306: /* type_specifier_nonarray: DMAT3X4 */ +#line 2265 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8321,11 +8458,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 4); } -#line 8325 "MachineIndependent/glslang_tab.cpp" +#line 8462 "MachineIndependent/glslang_tab.cpp" break; - case 301: /* type_specifier_nonarray: DMAT4X2 */ -#line 2250 "MachineIndependent/glslang.y" + case 307: /* type_specifier_nonarray: DMAT4X2 */ +#line 2273 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8334,11 +8471,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 2); } -#line 8338 "MachineIndependent/glslang_tab.cpp" +#line 8475 "MachineIndependent/glslang_tab.cpp" break; - case 302: /* type_specifier_nonarray: DMAT4X3 */ -#line 2258 "MachineIndependent/glslang.y" + case 308: /* type_specifier_nonarray: DMAT4X3 */ +#line 2281 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8347,11 +8484,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 3); } -#line 8351 "MachineIndependent/glslang_tab.cpp" +#line 8488 "MachineIndependent/glslang_tab.cpp" break; - case 303: /* type_specifier_nonarray: DMAT4X4 */ -#line 2266 "MachineIndependent/glslang.y" + case 309: /* type_specifier_nonarray: DMAT4X4 */ +#line 2289 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ECoreProfile | ECompatibilityProfile, "double matrix"); if (! parseContext.symbolTable.atBuiltInLevel()) @@ -8360,2228 +8497,2261 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 8364 "MachineIndependent/glslang_tab.cpp" +#line 8501 "MachineIndependent/glslang_tab.cpp" break; - case 304: /* type_specifier_nonarray: F16MAT2 */ -#line 2274 "MachineIndependent/glslang.y" + case 310: /* type_specifier_nonarray: F16MAT2 */ +#line 2297 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(2, 2); } -#line 8375 "MachineIndependent/glslang_tab.cpp" +#line 8512 "MachineIndependent/glslang_tab.cpp" break; - case 305: /* type_specifier_nonarray: F16MAT3 */ -#line 2280 "MachineIndependent/glslang.y" + case 311: /* type_specifier_nonarray: F16MAT3 */ +#line 2303 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(3, 3); } -#line 8386 "MachineIndependent/glslang_tab.cpp" +#line 8523 "MachineIndependent/glslang_tab.cpp" break; - case 306: /* type_specifier_nonarray: F16MAT4 */ -#line 2286 "MachineIndependent/glslang.y" + case 312: /* type_specifier_nonarray: F16MAT4 */ +#line 2309 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(4, 4); } -#line 8397 "MachineIndependent/glslang_tab.cpp" +#line 8534 "MachineIndependent/glslang_tab.cpp" break; - case 307: /* type_specifier_nonarray: F16MAT2X2 */ -#line 2292 "MachineIndependent/glslang.y" + case 313: /* type_specifier_nonarray: F16MAT2X2 */ +#line 2315 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(2, 2); } -#line 8408 "MachineIndependent/glslang_tab.cpp" +#line 8545 "MachineIndependent/glslang_tab.cpp" break; - case 308: /* type_specifier_nonarray: F16MAT2X3 */ -#line 2298 "MachineIndependent/glslang.y" + case 314: /* type_specifier_nonarray: F16MAT2X3 */ +#line 2321 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(2, 3); } -#line 8419 "MachineIndependent/glslang_tab.cpp" +#line 8556 "MachineIndependent/glslang_tab.cpp" break; - case 309: /* type_specifier_nonarray: F16MAT2X4 */ -#line 2304 "MachineIndependent/glslang.y" + case 315: /* type_specifier_nonarray: F16MAT2X4 */ +#line 2327 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(2, 4); } -#line 8430 "MachineIndependent/glslang_tab.cpp" +#line 8567 "MachineIndependent/glslang_tab.cpp" break; - case 310: /* type_specifier_nonarray: F16MAT3X2 */ -#line 2310 "MachineIndependent/glslang.y" + case 316: /* type_specifier_nonarray: F16MAT3X2 */ +#line 2333 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(3, 2); } -#line 8441 "MachineIndependent/glslang_tab.cpp" +#line 8578 "MachineIndependent/glslang_tab.cpp" break; - case 311: /* type_specifier_nonarray: F16MAT3X3 */ -#line 2316 "MachineIndependent/glslang.y" + case 317: /* type_specifier_nonarray: F16MAT3X3 */ +#line 2339 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(3, 3); } -#line 8452 "MachineIndependent/glslang_tab.cpp" +#line 8589 "MachineIndependent/glslang_tab.cpp" break; - case 312: /* type_specifier_nonarray: F16MAT3X4 */ -#line 2322 "MachineIndependent/glslang.y" + case 318: /* type_specifier_nonarray: F16MAT3X4 */ +#line 2345 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(3, 4); } -#line 8463 "MachineIndependent/glslang_tab.cpp" +#line 8600 "MachineIndependent/glslang_tab.cpp" break; - case 313: /* type_specifier_nonarray: F16MAT4X2 */ -#line 2328 "MachineIndependent/glslang.y" + case 319: /* type_specifier_nonarray: F16MAT4X2 */ +#line 2351 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(4, 2); } -#line 8474 "MachineIndependent/glslang_tab.cpp" +#line 8611 "MachineIndependent/glslang_tab.cpp" break; - case 314: /* type_specifier_nonarray: F16MAT4X3 */ -#line 2334 "MachineIndependent/glslang.y" + case 320: /* type_specifier_nonarray: F16MAT4X3 */ +#line 2357 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(4, 3); } -#line 8485 "MachineIndependent/glslang_tab.cpp" +#line 8622 "MachineIndependent/glslang_tab.cpp" break; - case 315: /* type_specifier_nonarray: F16MAT4X4 */ -#line 2340 "MachineIndependent/glslang.y" + case 321: /* type_specifier_nonarray: F16MAT4X4 */ +#line 2363 "MachineIndependent/glslang.y" { parseContext.float16Check((yyvsp[0].lex).loc, "half float matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat16; (yyval.interm.type).setMatrix(4, 4); } -#line 8496 "MachineIndependent/glslang_tab.cpp" +#line 8633 "MachineIndependent/glslang_tab.cpp" break; - case 316: /* type_specifier_nonarray: F32MAT2 */ -#line 2346 "MachineIndependent/glslang.y" + case 322: /* type_specifier_nonarray: F32MAT2 */ +#line 2369 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 8507 "MachineIndependent/glslang_tab.cpp" +#line 8644 "MachineIndependent/glslang_tab.cpp" break; - case 317: /* type_specifier_nonarray: F32MAT3 */ -#line 2352 "MachineIndependent/glslang.y" + case 323: /* type_specifier_nonarray: F32MAT3 */ +#line 2375 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 8518 "MachineIndependent/glslang_tab.cpp" +#line 8655 "MachineIndependent/glslang_tab.cpp" break; - case 318: /* type_specifier_nonarray: F32MAT4 */ -#line 2358 "MachineIndependent/glslang.y" + case 324: /* type_specifier_nonarray: F32MAT4 */ +#line 2381 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 8529 "MachineIndependent/glslang_tab.cpp" +#line 8666 "MachineIndependent/glslang_tab.cpp" break; - case 319: /* type_specifier_nonarray: F32MAT2X2 */ -#line 2364 "MachineIndependent/glslang.y" + case 325: /* type_specifier_nonarray: F32MAT2X2 */ +#line 2387 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 2); } -#line 8540 "MachineIndependent/glslang_tab.cpp" +#line 8677 "MachineIndependent/glslang_tab.cpp" break; - case 320: /* type_specifier_nonarray: F32MAT2X3 */ -#line 2370 "MachineIndependent/glslang.y" + case 326: /* type_specifier_nonarray: F32MAT2X3 */ +#line 2393 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 3); } -#line 8551 "MachineIndependent/glslang_tab.cpp" +#line 8688 "MachineIndependent/glslang_tab.cpp" break; - case 321: /* type_specifier_nonarray: F32MAT2X4 */ -#line 2376 "MachineIndependent/glslang.y" + case 327: /* type_specifier_nonarray: F32MAT2X4 */ +#line 2399 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(2, 4); } -#line 8562 "MachineIndependent/glslang_tab.cpp" +#line 8699 "MachineIndependent/glslang_tab.cpp" break; - case 322: /* type_specifier_nonarray: F32MAT3X2 */ -#line 2382 "MachineIndependent/glslang.y" + case 328: /* type_specifier_nonarray: F32MAT3X2 */ +#line 2405 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 2); } -#line 8573 "MachineIndependent/glslang_tab.cpp" +#line 8710 "MachineIndependent/glslang_tab.cpp" break; - case 323: /* type_specifier_nonarray: F32MAT3X3 */ -#line 2388 "MachineIndependent/glslang.y" + case 329: /* type_specifier_nonarray: F32MAT3X3 */ +#line 2411 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 3); } -#line 8584 "MachineIndependent/glslang_tab.cpp" +#line 8721 "MachineIndependent/glslang_tab.cpp" break; - case 324: /* type_specifier_nonarray: F32MAT3X4 */ -#line 2394 "MachineIndependent/glslang.y" + case 330: /* type_specifier_nonarray: F32MAT3X4 */ +#line 2417 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(3, 4); } -#line 8595 "MachineIndependent/glslang_tab.cpp" +#line 8732 "MachineIndependent/glslang_tab.cpp" break; - case 325: /* type_specifier_nonarray: F32MAT4X2 */ -#line 2400 "MachineIndependent/glslang.y" + case 331: /* type_specifier_nonarray: F32MAT4X2 */ +#line 2423 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 2); } -#line 8606 "MachineIndependent/glslang_tab.cpp" +#line 8743 "MachineIndependent/glslang_tab.cpp" break; - case 326: /* type_specifier_nonarray: F32MAT4X3 */ -#line 2406 "MachineIndependent/glslang.y" + case 332: /* type_specifier_nonarray: F32MAT4X3 */ +#line 2429 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 3); } -#line 8617 "MachineIndependent/glslang_tab.cpp" +#line 8754 "MachineIndependent/glslang_tab.cpp" break; - case 327: /* type_specifier_nonarray: F32MAT4X4 */ -#line 2412 "MachineIndependent/glslang.y" + case 333: /* type_specifier_nonarray: F32MAT4X4 */ +#line 2435 "MachineIndependent/glslang.y" { parseContext.explicitFloat32Check((yyvsp[0].lex).loc, "float32_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; (yyval.interm.type).setMatrix(4, 4); } -#line 8628 "MachineIndependent/glslang_tab.cpp" +#line 8765 "MachineIndependent/glslang_tab.cpp" break; - case 328: /* type_specifier_nonarray: F64MAT2 */ -#line 2418 "MachineIndependent/glslang.y" + case 334: /* type_specifier_nonarray: F64MAT2 */ +#line 2441 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 8639 "MachineIndependent/glslang_tab.cpp" +#line 8776 "MachineIndependent/glslang_tab.cpp" break; - case 329: /* type_specifier_nonarray: F64MAT3 */ -#line 2424 "MachineIndependent/glslang.y" + case 335: /* type_specifier_nonarray: F64MAT3 */ +#line 2447 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 8650 "MachineIndependent/glslang_tab.cpp" +#line 8787 "MachineIndependent/glslang_tab.cpp" break; - case 330: /* type_specifier_nonarray: F64MAT4 */ -#line 2430 "MachineIndependent/glslang.y" + case 336: /* type_specifier_nonarray: F64MAT4 */ +#line 2453 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 8661 "MachineIndependent/glslang_tab.cpp" +#line 8798 "MachineIndependent/glslang_tab.cpp" break; - case 331: /* type_specifier_nonarray: F64MAT2X2 */ -#line 2436 "MachineIndependent/glslang.y" + case 337: /* type_specifier_nonarray: F64MAT2X2 */ +#line 2459 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 2); } -#line 8672 "MachineIndependent/glslang_tab.cpp" +#line 8809 "MachineIndependent/glslang_tab.cpp" break; - case 332: /* type_specifier_nonarray: F64MAT2X3 */ -#line 2442 "MachineIndependent/glslang.y" + case 338: /* type_specifier_nonarray: F64MAT2X3 */ +#line 2465 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 3); } -#line 8683 "MachineIndependent/glslang_tab.cpp" +#line 8820 "MachineIndependent/glslang_tab.cpp" break; - case 333: /* type_specifier_nonarray: F64MAT2X4 */ -#line 2448 "MachineIndependent/glslang.y" + case 339: /* type_specifier_nonarray: F64MAT2X4 */ +#line 2471 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(2, 4); } -#line 8694 "MachineIndependent/glslang_tab.cpp" +#line 8831 "MachineIndependent/glslang_tab.cpp" break; - case 334: /* type_specifier_nonarray: F64MAT3X2 */ -#line 2454 "MachineIndependent/glslang.y" + case 340: /* type_specifier_nonarray: F64MAT3X2 */ +#line 2477 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 2); } -#line 8705 "MachineIndependent/glslang_tab.cpp" +#line 8842 "MachineIndependent/glslang_tab.cpp" break; - case 335: /* type_specifier_nonarray: F64MAT3X3 */ -#line 2460 "MachineIndependent/glslang.y" + case 341: /* type_specifier_nonarray: F64MAT3X3 */ +#line 2483 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 3); } -#line 8716 "MachineIndependent/glslang_tab.cpp" +#line 8853 "MachineIndependent/glslang_tab.cpp" break; - case 336: /* type_specifier_nonarray: F64MAT3X4 */ -#line 2466 "MachineIndependent/glslang.y" + case 342: /* type_specifier_nonarray: F64MAT3X4 */ +#line 2489 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(3, 4); } -#line 8727 "MachineIndependent/glslang_tab.cpp" +#line 8864 "MachineIndependent/glslang_tab.cpp" break; - case 337: /* type_specifier_nonarray: F64MAT4X2 */ -#line 2472 "MachineIndependent/glslang.y" + case 343: /* type_specifier_nonarray: F64MAT4X2 */ +#line 2495 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 2); } -#line 8738 "MachineIndependent/glslang_tab.cpp" +#line 8875 "MachineIndependent/glslang_tab.cpp" break; - case 338: /* type_specifier_nonarray: F64MAT4X3 */ -#line 2478 "MachineIndependent/glslang.y" + case 344: /* type_specifier_nonarray: F64MAT4X3 */ +#line 2501 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 3); } -#line 8749 "MachineIndependent/glslang_tab.cpp" +#line 8886 "MachineIndependent/glslang_tab.cpp" break; - case 339: /* type_specifier_nonarray: F64MAT4X4 */ -#line 2484 "MachineIndependent/glslang.y" + case 345: /* type_specifier_nonarray: F64MAT4X4 */ +#line 2507 "MachineIndependent/glslang.y" { parseContext.explicitFloat64Check((yyvsp[0].lex).loc, "float64_t matrix", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtDouble; (yyval.interm.type).setMatrix(4, 4); } -#line 8760 "MachineIndependent/glslang_tab.cpp" +#line 8897 "MachineIndependent/glslang_tab.cpp" break; - case 340: /* type_specifier_nonarray: ACCSTRUCTNV */ -#line 2490 "MachineIndependent/glslang.y" + case 346: /* type_specifier_nonarray: ACCSTRUCTNV */ +#line 2513 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtAccStruct; } -#line 8769 "MachineIndependent/glslang_tab.cpp" +#line 8906 "MachineIndependent/glslang_tab.cpp" break; - case 341: /* type_specifier_nonarray: ACCSTRUCTEXT */ -#line 2494 "MachineIndependent/glslang.y" + case 347: /* type_specifier_nonarray: ACCSTRUCTEXT */ +#line 2517 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtAccStruct; } -#line 8778 "MachineIndependent/glslang_tab.cpp" +#line 8915 "MachineIndependent/glslang_tab.cpp" break; - case 342: /* type_specifier_nonarray: RAYQUERYEXT */ -#line 2498 "MachineIndependent/glslang.y" + case 348: /* type_specifier_nonarray: RAYQUERYEXT */ +#line 2521 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtRayQuery; } -#line 8787 "MachineIndependent/glslang_tab.cpp" +#line 8924 "MachineIndependent/glslang_tab.cpp" break; - case 343: /* type_specifier_nonarray: ATOMIC_UINT */ -#line 2502 "MachineIndependent/glslang.y" + case 349: /* type_specifier_nonarray: ATOMIC_UINT */ +#line 2525 "MachineIndependent/glslang.y" { parseContext.vulkanRemoved((yyvsp[0].lex).loc, "atomic counter types"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtAtomicUint; } -#line 8797 "MachineIndependent/glslang_tab.cpp" +#line 8934 "MachineIndependent/glslang_tab.cpp" break; - case 344: /* type_specifier_nonarray: SAMPLER1D */ -#line 2507 "MachineIndependent/glslang.y" + case 350: /* type_specifier_nonarray: SAMPLER1D */ +#line 2530 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd1D); } -#line 8807 "MachineIndependent/glslang_tab.cpp" +#line 8944 "MachineIndependent/glslang_tab.cpp" break; - case 345: /* type_specifier_nonarray: SAMPLER2D */ -#line 2513 "MachineIndependent/glslang.y" + case 351: /* type_specifier_nonarray: SAMPLER2D */ +#line 2535 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D); } -#line 8817 "MachineIndependent/glslang_tab.cpp" +#line 8954 "MachineIndependent/glslang_tab.cpp" break; - case 346: /* type_specifier_nonarray: SAMPLER3D */ -#line 2518 "MachineIndependent/glslang.y" + case 352: /* type_specifier_nonarray: SAMPLER3D */ +#line 2540 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd3D); } -#line 8827 "MachineIndependent/glslang_tab.cpp" +#line 8964 "MachineIndependent/glslang_tab.cpp" break; - case 347: /* type_specifier_nonarray: SAMPLERCUBE */ -#line 2523 "MachineIndependent/glslang.y" + case 353: /* type_specifier_nonarray: SAMPLERCUBE */ +#line 2545 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube); } -#line 8837 "MachineIndependent/glslang_tab.cpp" +#line 8974 "MachineIndependent/glslang_tab.cpp" break; - case 348: /* type_specifier_nonarray: SAMPLER2DSHADOW */ -#line 2528 "MachineIndependent/glslang.y" + case 354: /* type_specifier_nonarray: SAMPLER2DSHADOW */ +#line 2550 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, true); } -#line 8847 "MachineIndependent/glslang_tab.cpp" +#line 8984 "MachineIndependent/glslang_tab.cpp" break; - case 349: /* type_specifier_nonarray: SAMPLERCUBESHADOW */ -#line 2533 "MachineIndependent/glslang.y" + case 355: /* type_specifier_nonarray: SAMPLERCUBESHADOW */ +#line 2555 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube, false, true); } -#line 8857 "MachineIndependent/glslang_tab.cpp" +#line 8994 "MachineIndependent/glslang_tab.cpp" break; - case 350: /* type_specifier_nonarray: SAMPLER2DARRAY */ -#line 2538 "MachineIndependent/glslang.y" + case 356: /* type_specifier_nonarray: SAMPLER2DARRAY */ +#line 2560 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true); } -#line 8867 "MachineIndependent/glslang_tab.cpp" +#line 9004 "MachineIndependent/glslang_tab.cpp" break; - case 351: /* type_specifier_nonarray: SAMPLER2DARRAYSHADOW */ -#line 2543 "MachineIndependent/glslang.y" + case 357: /* type_specifier_nonarray: SAMPLER2DARRAYSHADOW */ +#line 2565 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, true); } -#line 8877 "MachineIndependent/glslang_tab.cpp" +#line 9014 "MachineIndependent/glslang_tab.cpp" break; - case 352: /* type_specifier_nonarray: SAMPLER1DSHADOW */ -#line 2549 "MachineIndependent/glslang.y" + case 358: /* type_specifier_nonarray: SAMPLER1DSHADOW */ +#line 2570 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd1D, false, true); } -#line 8887 "MachineIndependent/glslang_tab.cpp" +#line 9024 "MachineIndependent/glslang_tab.cpp" break; - case 353: /* type_specifier_nonarray: SAMPLER1DARRAY */ -#line 2554 "MachineIndependent/glslang.y" + case 359: /* type_specifier_nonarray: SAMPLER1DARRAY */ +#line 2575 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true); } -#line 8897 "MachineIndependent/glslang_tab.cpp" +#line 9034 "MachineIndependent/glslang_tab.cpp" break; - case 354: /* type_specifier_nonarray: SAMPLER1DARRAYSHADOW */ -#line 2559 "MachineIndependent/glslang.y" + case 360: /* type_specifier_nonarray: SAMPLER1DARRAYSHADOW */ +#line 2580 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd1D, true, true); } -#line 8907 "MachineIndependent/glslang_tab.cpp" +#line 9044 "MachineIndependent/glslang_tab.cpp" break; - case 355: /* type_specifier_nonarray: SAMPLERCUBEARRAY */ -#line 2564 "MachineIndependent/glslang.y" + case 361: /* type_specifier_nonarray: SAMPLERCUBEARRAY */ +#line 2585 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true); } -#line 8917 "MachineIndependent/glslang_tab.cpp" +#line 9054 "MachineIndependent/glslang_tab.cpp" break; - case 356: /* type_specifier_nonarray: SAMPLERCUBEARRAYSHADOW */ -#line 2569 "MachineIndependent/glslang.y" + case 362: /* type_specifier_nonarray: SAMPLERCUBEARRAYSHADOW */ +#line 2590 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdCube, true, true); } -#line 8927 "MachineIndependent/glslang_tab.cpp" +#line 9064 "MachineIndependent/glslang_tab.cpp" break; - case 357: /* type_specifier_nonarray: F16SAMPLER1D */ -#line 2574 "MachineIndependent/glslang.y" + case 363: /* type_specifier_nonarray: F16SAMPLER1D */ +#line 2595 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D); } -#line 8938 "MachineIndependent/glslang_tab.cpp" +#line 9075 "MachineIndependent/glslang_tab.cpp" break; - case 358: /* type_specifier_nonarray: F16SAMPLER2D */ -#line 2580 "MachineIndependent/glslang.y" + case 364: /* type_specifier_nonarray: F16SAMPLER2D */ +#line 2601 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D); } -#line 8949 "MachineIndependent/glslang_tab.cpp" +#line 9086 "MachineIndependent/glslang_tab.cpp" break; - case 359: /* type_specifier_nonarray: F16SAMPLER3D */ -#line 2586 "MachineIndependent/glslang.y" + case 365: /* type_specifier_nonarray: F16SAMPLER3D */ +#line 2607 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd3D); } -#line 8960 "MachineIndependent/glslang_tab.cpp" +#line 9097 "MachineIndependent/glslang_tab.cpp" break; - case 360: /* type_specifier_nonarray: F16SAMPLERCUBE */ -#line 2592 "MachineIndependent/glslang.y" + case 366: /* type_specifier_nonarray: F16SAMPLERCUBE */ +#line 2613 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube); } -#line 8971 "MachineIndependent/glslang_tab.cpp" +#line 9108 "MachineIndependent/glslang_tab.cpp" break; - case 361: /* type_specifier_nonarray: F16SAMPLER1DSHADOW */ -#line 2598 "MachineIndependent/glslang.y" + case 367: /* type_specifier_nonarray: F16SAMPLER1DSHADOW */ +#line 2619 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, false, true); } -#line 8982 "MachineIndependent/glslang_tab.cpp" +#line 9119 "MachineIndependent/glslang_tab.cpp" break; - case 362: /* type_specifier_nonarray: F16SAMPLER2DSHADOW */ -#line 2604 "MachineIndependent/glslang.y" + case 368: /* type_specifier_nonarray: F16SAMPLER2DSHADOW */ +#line 2625 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, false, true); } -#line 8993 "MachineIndependent/glslang_tab.cpp" +#line 9130 "MachineIndependent/glslang_tab.cpp" break; - case 363: /* type_specifier_nonarray: F16SAMPLERCUBESHADOW */ -#line 2610 "MachineIndependent/glslang.y" + case 369: /* type_specifier_nonarray: F16SAMPLERCUBESHADOW */ +#line 2631 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, false, true); } -#line 9004 "MachineIndependent/glslang_tab.cpp" +#line 9141 "MachineIndependent/glslang_tab.cpp" break; - case 364: /* type_specifier_nonarray: F16SAMPLER1DARRAY */ -#line 2616 "MachineIndependent/glslang.y" + case 370: /* type_specifier_nonarray: F16SAMPLER1DARRAY */ +#line 2637 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, true); } -#line 9015 "MachineIndependent/glslang_tab.cpp" +#line 9152 "MachineIndependent/glslang_tab.cpp" break; - case 365: /* type_specifier_nonarray: F16SAMPLER2DARRAY */ -#line 2622 "MachineIndependent/glslang.y" + case 371: /* type_specifier_nonarray: F16SAMPLER2DARRAY */ +#line 2643 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true); } -#line 9026 "MachineIndependent/glslang_tab.cpp" +#line 9163 "MachineIndependent/glslang_tab.cpp" break; - case 366: /* type_specifier_nonarray: F16SAMPLER1DARRAYSHADOW */ -#line 2628 "MachineIndependent/glslang.y" + case 372: /* type_specifier_nonarray: F16SAMPLER1DARRAYSHADOW */ +#line 2649 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd1D, true, true); } -#line 9037 "MachineIndependent/glslang_tab.cpp" +#line 9174 "MachineIndependent/glslang_tab.cpp" break; - case 367: /* type_specifier_nonarray: F16SAMPLER2DARRAYSHADOW */ -#line 2634 "MachineIndependent/glslang.y" + case 373: /* type_specifier_nonarray: F16SAMPLER2DARRAYSHADOW */ +#line 2655 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true, true); } -#line 9048 "MachineIndependent/glslang_tab.cpp" +#line 9185 "MachineIndependent/glslang_tab.cpp" break; - case 368: /* type_specifier_nonarray: F16SAMPLERCUBEARRAY */ -#line 2640 "MachineIndependent/glslang.y" + case 374: /* type_specifier_nonarray: F16SAMPLERCUBEARRAY */ +#line 2661 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, true); } -#line 9059 "MachineIndependent/glslang_tab.cpp" +#line 9196 "MachineIndependent/glslang_tab.cpp" break; - case 369: /* type_specifier_nonarray: F16SAMPLERCUBEARRAYSHADOW */ -#line 2646 "MachineIndependent/glslang.y" + case 375: /* type_specifier_nonarray: F16SAMPLERCUBEARRAYSHADOW */ +#line 2667 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdCube, true, true); } -#line 9070 "MachineIndependent/glslang_tab.cpp" +#line 9207 "MachineIndependent/glslang_tab.cpp" break; - case 370: /* type_specifier_nonarray: ISAMPLER1D */ -#line 2652 "MachineIndependent/glslang.y" + case 376: /* type_specifier_nonarray: ISAMPLER1D */ +#line 2673 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd1D); } -#line 9080 "MachineIndependent/glslang_tab.cpp" +#line 9217 "MachineIndependent/glslang_tab.cpp" break; - case 371: /* type_specifier_nonarray: ISAMPLER2D */ -#line 2658 "MachineIndependent/glslang.y" + case 377: /* type_specifier_nonarray: ISAMPLER2D */ +#line 2678 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D); } -#line 9090 "MachineIndependent/glslang_tab.cpp" +#line 9227 "MachineIndependent/glslang_tab.cpp" break; - case 372: /* type_specifier_nonarray: ISAMPLER3D */ -#line 2663 "MachineIndependent/glslang.y" + case 378: /* type_specifier_nonarray: ISAMPLER3D */ +#line 2683 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd3D); } -#line 9100 "MachineIndependent/glslang_tab.cpp" +#line 9237 "MachineIndependent/glslang_tab.cpp" break; - case 373: /* type_specifier_nonarray: ISAMPLERCUBE */ -#line 2668 "MachineIndependent/glslang.y" + case 379: /* type_specifier_nonarray: ISAMPLERCUBE */ +#line 2688 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, EsdCube); } -#line 9110 "MachineIndependent/glslang_tab.cpp" +#line 9247 "MachineIndependent/glslang_tab.cpp" break; - case 374: /* type_specifier_nonarray: ISAMPLER2DARRAY */ -#line 2673 "MachineIndependent/glslang.y" + case 380: /* type_specifier_nonarray: ISAMPLER2DARRAY */ +#line 2693 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D, true); } -#line 9120 "MachineIndependent/glslang_tab.cpp" +#line 9257 "MachineIndependent/glslang_tab.cpp" break; - case 375: /* type_specifier_nonarray: USAMPLER2D */ -#line 2678 "MachineIndependent/glslang.y" + case 381: /* type_specifier_nonarray: USAMPLER2D */ +#line 2698 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd2D); } -#line 9130 "MachineIndependent/glslang_tab.cpp" +#line 9267 "MachineIndependent/glslang_tab.cpp" break; - case 376: /* type_specifier_nonarray: USAMPLER3D */ -#line 2683 "MachineIndependent/glslang.y" + case 382: /* type_specifier_nonarray: USAMPLER3D */ +#line 2703 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd3D); } -#line 9140 "MachineIndependent/glslang_tab.cpp" +#line 9277 "MachineIndependent/glslang_tab.cpp" break; - case 377: /* type_specifier_nonarray: USAMPLERCUBE */ -#line 2688 "MachineIndependent/glslang.y" + case 383: /* type_specifier_nonarray: USAMPLERCUBE */ +#line 2708 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdCube); } -#line 9150 "MachineIndependent/glslang_tab.cpp" +#line 9287 "MachineIndependent/glslang_tab.cpp" break; - case 378: /* type_specifier_nonarray: ISAMPLER1DARRAY */ -#line 2694 "MachineIndependent/glslang.y" + case 384: /* type_specifier_nonarray: ISAMPLER1DARRAY */ +#line 2713 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd1D, true); } -#line 9160 "MachineIndependent/glslang_tab.cpp" +#line 9297 "MachineIndependent/glslang_tab.cpp" break; - case 379: /* type_specifier_nonarray: ISAMPLERCUBEARRAY */ -#line 2699 "MachineIndependent/glslang.y" + case 385: /* type_specifier_nonarray: ISAMPLERCUBEARRAY */ +#line 2718 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, EsdCube, true); } -#line 9170 "MachineIndependent/glslang_tab.cpp" +#line 9307 "MachineIndependent/glslang_tab.cpp" break; - case 380: /* type_specifier_nonarray: USAMPLER1D */ -#line 2704 "MachineIndependent/glslang.y" + case 386: /* type_specifier_nonarray: USAMPLER1D */ +#line 2723 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd1D); } -#line 9180 "MachineIndependent/glslang_tab.cpp" +#line 9317 "MachineIndependent/glslang_tab.cpp" break; - case 381: /* type_specifier_nonarray: USAMPLER1DARRAY */ -#line 2709 "MachineIndependent/glslang.y" + case 387: /* type_specifier_nonarray: USAMPLER1DARRAY */ +#line 2728 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd1D, true); } -#line 9190 "MachineIndependent/glslang_tab.cpp" +#line 9327 "MachineIndependent/glslang_tab.cpp" break; - case 382: /* type_specifier_nonarray: USAMPLERCUBEARRAY */ -#line 2714 "MachineIndependent/glslang.y" + case 388: /* type_specifier_nonarray: USAMPLERCUBEARRAY */ +#line 2733 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdCube, true); } -#line 9200 "MachineIndependent/glslang_tab.cpp" +#line 9337 "MachineIndependent/glslang_tab.cpp" break; - case 383: /* type_specifier_nonarray: TEXTURECUBEARRAY */ -#line 2719 "MachineIndependent/glslang.y" + case 389: /* type_specifier_nonarray: TEXTURECUBEARRAY */ +#line 2738 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube, true); } -#line 9210 "MachineIndependent/glslang_tab.cpp" +#line 9347 "MachineIndependent/glslang_tab.cpp" break; - case 384: /* type_specifier_nonarray: ITEXTURECUBEARRAY */ -#line 2724 "MachineIndependent/glslang.y" + case 390: /* type_specifier_nonarray: ITEXTURECUBEARRAY */ +#line 2743 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdCube, true); } -#line 9220 "MachineIndependent/glslang_tab.cpp" +#line 9357 "MachineIndependent/glslang_tab.cpp" break; - case 385: /* type_specifier_nonarray: UTEXTURECUBEARRAY */ -#line 2729 "MachineIndependent/glslang.y" + case 391: /* type_specifier_nonarray: UTEXTURECUBEARRAY */ +#line 2748 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdCube, true); } -#line 9230 "MachineIndependent/glslang_tab.cpp" +#line 9367 "MachineIndependent/glslang_tab.cpp" break; - case 386: /* type_specifier_nonarray: USAMPLER2DARRAY */ -#line 2735 "MachineIndependent/glslang.y" + case 392: /* type_specifier_nonarray: USAMPLER2DARRAY */ +#line 2753 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd2D, true); } -#line 9240 "MachineIndependent/glslang_tab.cpp" +#line 9377 "MachineIndependent/glslang_tab.cpp" break; - case 387: /* type_specifier_nonarray: TEXTURE2D */ -#line 2740 "MachineIndependent/glslang.y" + case 393: /* type_specifier_nonarray: TEXTURE2D */ +#line 2758 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D); } -#line 9250 "MachineIndependent/glslang_tab.cpp" +#line 9387 "MachineIndependent/glslang_tab.cpp" break; - case 388: /* type_specifier_nonarray: TEXTURE3D */ -#line 2745 "MachineIndependent/glslang.y" + case 394: /* type_specifier_nonarray: TEXTURE3D */ +#line 2763 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd3D); } -#line 9260 "MachineIndependent/glslang_tab.cpp" +#line 9397 "MachineIndependent/glslang_tab.cpp" break; - case 389: /* type_specifier_nonarray: TEXTURE2DARRAY */ -#line 2750 "MachineIndependent/glslang.y" + case 395: /* type_specifier_nonarray: TEXTURE2DARRAY */ +#line 2768 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true); } -#line 9270 "MachineIndependent/glslang_tab.cpp" +#line 9407 "MachineIndependent/glslang_tab.cpp" break; - case 390: /* type_specifier_nonarray: TEXTURECUBE */ -#line 2755 "MachineIndependent/glslang.y" + case 396: /* type_specifier_nonarray: TEXTURECUBE */ +#line 2773 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdCube); } -#line 9280 "MachineIndependent/glslang_tab.cpp" +#line 9417 "MachineIndependent/glslang_tab.cpp" break; - case 391: /* type_specifier_nonarray: ITEXTURE2D */ -#line 2760 "MachineIndependent/glslang.y" + case 397: /* type_specifier_nonarray: ITEXTURE2D */ +#line 2778 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D); } -#line 9290 "MachineIndependent/glslang_tab.cpp" +#line 9427 "MachineIndependent/glslang_tab.cpp" break; - case 392: /* type_specifier_nonarray: ITEXTURE3D */ -#line 2765 "MachineIndependent/glslang.y" + case 398: /* type_specifier_nonarray: ITEXTURE3D */ +#line 2783 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd3D); } -#line 9300 "MachineIndependent/glslang_tab.cpp" +#line 9437 "MachineIndependent/glslang_tab.cpp" break; - case 393: /* type_specifier_nonarray: ITEXTURECUBE */ -#line 2770 "MachineIndependent/glslang.y" + case 399: /* type_specifier_nonarray: ITEXTURECUBE */ +#line 2788 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdCube); } -#line 9310 "MachineIndependent/glslang_tab.cpp" +#line 9447 "MachineIndependent/glslang_tab.cpp" break; - case 394: /* type_specifier_nonarray: ITEXTURE2DARRAY */ -#line 2775 "MachineIndependent/glslang.y" + case 400: /* type_specifier_nonarray: ITEXTURE2DARRAY */ +#line 2793 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, true); } -#line 9320 "MachineIndependent/glslang_tab.cpp" +#line 9457 "MachineIndependent/glslang_tab.cpp" break; - case 395: /* type_specifier_nonarray: UTEXTURE2D */ -#line 2780 "MachineIndependent/glslang.y" + case 401: /* type_specifier_nonarray: UTEXTURE2D */ +#line 2798 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D); } -#line 9330 "MachineIndependent/glslang_tab.cpp" +#line 9467 "MachineIndependent/glslang_tab.cpp" break; - case 396: /* type_specifier_nonarray: UTEXTURE3D */ -#line 2785 "MachineIndependent/glslang.y" + case 402: /* type_specifier_nonarray: UTEXTURE3D */ +#line 2803 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd3D); } -#line 9340 "MachineIndependent/glslang_tab.cpp" +#line 9477 "MachineIndependent/glslang_tab.cpp" break; - case 397: /* type_specifier_nonarray: UTEXTURECUBE */ -#line 2790 "MachineIndependent/glslang.y" + case 403: /* type_specifier_nonarray: UTEXTURECUBE */ +#line 2808 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdCube); } -#line 9350 "MachineIndependent/glslang_tab.cpp" +#line 9487 "MachineIndependent/glslang_tab.cpp" break; - case 398: /* type_specifier_nonarray: UTEXTURE2DARRAY */ -#line 2795 "MachineIndependent/glslang.y" + case 404: /* type_specifier_nonarray: UTEXTURE2DARRAY */ +#line 2813 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, true); } -#line 9360 "MachineIndependent/glslang_tab.cpp" +#line 9497 "MachineIndependent/glslang_tab.cpp" break; - case 399: /* type_specifier_nonarray: SAMPLER */ -#line 2800 "MachineIndependent/glslang.y" + case 405: /* type_specifier_nonarray: SAMPLER */ +#line 2818 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setPureSampler(false); } -#line 9370 "MachineIndependent/glslang_tab.cpp" +#line 9507 "MachineIndependent/glslang_tab.cpp" break; - case 400: /* type_specifier_nonarray: SAMPLERSHADOW */ -#line 2805 "MachineIndependent/glslang.y" + case 406: /* type_specifier_nonarray: SAMPLERSHADOW */ +#line 2823 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setPureSampler(true); } -#line 9380 "MachineIndependent/glslang_tab.cpp" +#line 9517 "MachineIndependent/glslang_tab.cpp" break; - case 401: /* type_specifier_nonarray: SAMPLER2DRECT */ -#line 2811 "MachineIndependent/glslang.y" + case 407: /* type_specifier_nonarray: SAMPLER2DRECT */ +#line 2828 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdRect); } -#line 9390 "MachineIndependent/glslang_tab.cpp" +#line 9527 "MachineIndependent/glslang_tab.cpp" break; - case 402: /* type_specifier_nonarray: SAMPLER2DRECTSHADOW */ -#line 2816 "MachineIndependent/glslang.y" + case 408: /* type_specifier_nonarray: SAMPLER2DRECTSHADOW */ +#line 2833 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdRect, false, true); } -#line 9400 "MachineIndependent/glslang_tab.cpp" +#line 9537 "MachineIndependent/glslang_tab.cpp" break; - case 403: /* type_specifier_nonarray: F16SAMPLER2DRECT */ -#line 2821 "MachineIndependent/glslang.y" + case 409: /* type_specifier_nonarray: F16SAMPLER2DRECT */ +#line 2838 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdRect); } -#line 9411 "MachineIndependent/glslang_tab.cpp" +#line 9548 "MachineIndependent/glslang_tab.cpp" break; - case 404: /* type_specifier_nonarray: F16SAMPLER2DRECTSHADOW */ -#line 2827 "MachineIndependent/glslang.y" + case 410: /* type_specifier_nonarray: F16SAMPLER2DRECTSHADOW */ +#line 2844 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdRect, false, true); } -#line 9422 "MachineIndependent/glslang_tab.cpp" +#line 9559 "MachineIndependent/glslang_tab.cpp" break; - case 405: /* type_specifier_nonarray: ISAMPLER2DRECT */ -#line 2833 "MachineIndependent/glslang.y" + case 411: /* type_specifier_nonarray: ISAMPLER2DRECT */ +#line 2850 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, EsdRect); } -#line 9432 "MachineIndependent/glslang_tab.cpp" +#line 9569 "MachineIndependent/glslang_tab.cpp" break; - case 406: /* type_specifier_nonarray: USAMPLER2DRECT */ -#line 2838 "MachineIndependent/glslang.y" + case 412: /* type_specifier_nonarray: USAMPLER2DRECT */ +#line 2855 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdRect); } -#line 9442 "MachineIndependent/glslang_tab.cpp" +#line 9579 "MachineIndependent/glslang_tab.cpp" break; - case 407: /* type_specifier_nonarray: SAMPLERBUFFER */ -#line 2843 "MachineIndependent/glslang.y" + case 413: /* type_specifier_nonarray: SAMPLERBUFFER */ +#line 2860 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, EsdBuffer); } -#line 9452 "MachineIndependent/glslang_tab.cpp" +#line 9589 "MachineIndependent/glslang_tab.cpp" break; - case 408: /* type_specifier_nonarray: F16SAMPLERBUFFER */ -#line 2848 "MachineIndependent/glslang.y" + case 414: /* type_specifier_nonarray: F16SAMPLERBUFFER */ +#line 2865 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, EsdBuffer); } -#line 9463 "MachineIndependent/glslang_tab.cpp" +#line 9600 "MachineIndependent/glslang_tab.cpp" break; - case 409: /* type_specifier_nonarray: ISAMPLERBUFFER */ -#line 2854 "MachineIndependent/glslang.y" + case 415: /* type_specifier_nonarray: ISAMPLERBUFFER */ +#line 2871 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, EsdBuffer); } -#line 9473 "MachineIndependent/glslang_tab.cpp" +#line 9610 "MachineIndependent/glslang_tab.cpp" break; - case 410: /* type_specifier_nonarray: USAMPLERBUFFER */ -#line 2859 "MachineIndependent/glslang.y" + case 416: /* type_specifier_nonarray: USAMPLERBUFFER */ +#line 2876 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, EsdBuffer); } -#line 9483 "MachineIndependent/glslang_tab.cpp" +#line 9620 "MachineIndependent/glslang_tab.cpp" break; - case 411: /* type_specifier_nonarray: SAMPLER2DMS */ -#line 2864 "MachineIndependent/glslang.y" + case 417: /* type_specifier_nonarray: SAMPLER2DMS */ +#line 2881 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, false, false, true); } -#line 9493 "MachineIndependent/glslang_tab.cpp" +#line 9630 "MachineIndependent/glslang_tab.cpp" break; - case 412: /* type_specifier_nonarray: F16SAMPLER2DMS */ -#line 2869 "MachineIndependent/glslang.y" + case 418: /* type_specifier_nonarray: F16SAMPLER2DMS */ +#line 2886 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, false, false, true); } -#line 9504 "MachineIndependent/glslang_tab.cpp" +#line 9641 "MachineIndependent/glslang_tab.cpp" break; - case 413: /* type_specifier_nonarray: ISAMPLER2DMS */ -#line 2875 "MachineIndependent/glslang.y" + case 419: /* type_specifier_nonarray: ISAMPLER2DMS */ +#line 2892 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D, false, false, true); } -#line 9514 "MachineIndependent/glslang_tab.cpp" +#line 9651 "MachineIndependent/glslang_tab.cpp" break; - case 414: /* type_specifier_nonarray: USAMPLER2DMS */ -#line 2880 "MachineIndependent/glslang.y" + case 420: /* type_specifier_nonarray: USAMPLER2DMS */ +#line 2897 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd2D, false, false, true); } -#line 9524 "MachineIndependent/glslang_tab.cpp" +#line 9661 "MachineIndependent/glslang_tab.cpp" break; - case 415: /* type_specifier_nonarray: SAMPLER2DMSARRAY */ -#line 2885 "MachineIndependent/glslang.y" + case 421: /* type_specifier_nonarray: SAMPLER2DMSARRAY */ +#line 2902 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D, true, false, true); } -#line 9534 "MachineIndependent/glslang_tab.cpp" +#line 9671 "MachineIndependent/glslang_tab.cpp" break; - case 416: /* type_specifier_nonarray: F16SAMPLER2DMSARRAY */ -#line 2890 "MachineIndependent/glslang.y" + case 422: /* type_specifier_nonarray: F16SAMPLER2DMSARRAY */ +#line 2907 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float sampler", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat16, Esd2D, true, false, true); } -#line 9545 "MachineIndependent/glslang_tab.cpp" +#line 9682 "MachineIndependent/glslang_tab.cpp" break; - case 417: /* type_specifier_nonarray: ISAMPLER2DMSARRAY */ -#line 2896 "MachineIndependent/glslang.y" + case 423: /* type_specifier_nonarray: ISAMPLER2DMSARRAY */ +#line 2913 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtInt, Esd2D, true, false, true); } -#line 9555 "MachineIndependent/glslang_tab.cpp" +#line 9692 "MachineIndependent/glslang_tab.cpp" break; - case 418: /* type_specifier_nonarray: USAMPLER2DMSARRAY */ -#line 2901 "MachineIndependent/glslang.y" + case 424: /* type_specifier_nonarray: USAMPLER2DMSARRAY */ +#line 2918 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtUint, Esd2D, true, false, true); } -#line 9565 "MachineIndependent/glslang_tab.cpp" +#line 9702 "MachineIndependent/glslang_tab.cpp" break; - case 419: /* type_specifier_nonarray: TEXTURE1D */ -#line 2906 "MachineIndependent/glslang.y" + case 425: /* type_specifier_nonarray: TEXTURE1D */ +#line 2923 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D); } -#line 9575 "MachineIndependent/glslang_tab.cpp" +#line 9712 "MachineIndependent/glslang_tab.cpp" break; - case 420: /* type_specifier_nonarray: F16TEXTURE1D */ -#line 2911 "MachineIndependent/glslang.y" + case 426: /* type_specifier_nonarray: F16TEXTURE1D */ +#line 2928 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd1D); } -#line 9586 "MachineIndependent/glslang_tab.cpp" +#line 9723 "MachineIndependent/glslang_tab.cpp" break; - case 421: /* type_specifier_nonarray: F16TEXTURE2D */ -#line 2917 "MachineIndependent/glslang.y" + case 427: /* type_specifier_nonarray: F16TEXTURE2D */ +#line 2934 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D); } -#line 9597 "MachineIndependent/glslang_tab.cpp" +#line 9734 "MachineIndependent/glslang_tab.cpp" break; - case 422: /* type_specifier_nonarray: F16TEXTURE3D */ -#line 2923 "MachineIndependent/glslang.y" + case 428: /* type_specifier_nonarray: F16TEXTURE3D */ +#line 2940 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd3D); } -#line 9608 "MachineIndependent/glslang_tab.cpp" +#line 9745 "MachineIndependent/glslang_tab.cpp" break; - case 423: /* type_specifier_nonarray: F16TEXTURECUBE */ -#line 2929 "MachineIndependent/glslang.y" + case 429: /* type_specifier_nonarray: F16TEXTURECUBE */ +#line 2946 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdCube); } -#line 9619 "MachineIndependent/glslang_tab.cpp" +#line 9756 "MachineIndependent/glslang_tab.cpp" break; - case 424: /* type_specifier_nonarray: TEXTURE1DARRAY */ -#line 2935 "MachineIndependent/glslang.y" + case 430: /* type_specifier_nonarray: TEXTURE1DARRAY */ +#line 2952 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd1D, true); } -#line 9629 "MachineIndependent/glslang_tab.cpp" +#line 9766 "MachineIndependent/glslang_tab.cpp" break; - case 425: /* type_specifier_nonarray: F16TEXTURE1DARRAY */ -#line 2940 "MachineIndependent/glslang.y" + case 431: /* type_specifier_nonarray: F16TEXTURE1DARRAY */ +#line 2957 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd1D, true); } -#line 9640 "MachineIndependent/glslang_tab.cpp" +#line 9777 "MachineIndependent/glslang_tab.cpp" break; - case 426: /* type_specifier_nonarray: F16TEXTURE2DARRAY */ -#line 2946 "MachineIndependent/glslang.y" + case 432: /* type_specifier_nonarray: F16TEXTURE2DARRAY */ +#line 2963 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, true); } -#line 9651 "MachineIndependent/glslang_tab.cpp" +#line 9788 "MachineIndependent/glslang_tab.cpp" break; - case 427: /* type_specifier_nonarray: F16TEXTURECUBEARRAY */ -#line 2952 "MachineIndependent/glslang.y" + case 433: /* type_specifier_nonarray: F16TEXTURECUBEARRAY */ +#line 2969 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdCube, true); } -#line 9662 "MachineIndependent/glslang_tab.cpp" +#line 9799 "MachineIndependent/glslang_tab.cpp" break; - case 428: /* type_specifier_nonarray: ITEXTURE1D */ -#line 2958 "MachineIndependent/glslang.y" + case 434: /* type_specifier_nonarray: ITEXTURE1D */ +#line 2975 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D); } -#line 9672 "MachineIndependent/glslang_tab.cpp" +#line 9809 "MachineIndependent/glslang_tab.cpp" break; - case 429: /* type_specifier_nonarray: ITEXTURE1DARRAY */ -#line 2963 "MachineIndependent/glslang.y" + case 435: /* type_specifier_nonarray: ITEXTURE1DARRAY */ +#line 2980 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd1D, true); } -#line 9682 "MachineIndependent/glslang_tab.cpp" +#line 9819 "MachineIndependent/glslang_tab.cpp" break; - case 430: /* type_specifier_nonarray: UTEXTURE1D */ -#line 2968 "MachineIndependent/glslang.y" + case 436: /* type_specifier_nonarray: UTEXTURE1D */ +#line 2985 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D); } -#line 9692 "MachineIndependent/glslang_tab.cpp" +#line 9829 "MachineIndependent/glslang_tab.cpp" break; - case 431: /* type_specifier_nonarray: UTEXTURE1DARRAY */ -#line 2973 "MachineIndependent/glslang.y" + case 437: /* type_specifier_nonarray: UTEXTURE1DARRAY */ +#line 2990 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd1D, true); } -#line 9702 "MachineIndependent/glslang_tab.cpp" +#line 9839 "MachineIndependent/glslang_tab.cpp" break; - case 432: /* type_specifier_nonarray: TEXTURE2DRECT */ -#line 2978 "MachineIndependent/glslang.y" + case 438: /* type_specifier_nonarray: TEXTURE2DRECT */ +#line 2995 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdRect); } -#line 9712 "MachineIndependent/glslang_tab.cpp" +#line 9849 "MachineIndependent/glslang_tab.cpp" break; - case 433: /* type_specifier_nonarray: F16TEXTURE2DRECT */ -#line 2983 "MachineIndependent/glslang.y" + case 439: /* type_specifier_nonarray: F16TEXTURE2DRECT */ +#line 3000 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdRect); } -#line 9723 "MachineIndependent/glslang_tab.cpp" +#line 9860 "MachineIndependent/glslang_tab.cpp" break; - case 434: /* type_specifier_nonarray: ITEXTURE2DRECT */ -#line 2989 "MachineIndependent/glslang.y" + case 440: /* type_specifier_nonarray: ITEXTURE2DRECT */ +#line 3006 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdRect); } -#line 9733 "MachineIndependent/glslang_tab.cpp" +#line 9870 "MachineIndependent/glslang_tab.cpp" break; - case 435: /* type_specifier_nonarray: UTEXTURE2DRECT */ -#line 2994 "MachineIndependent/glslang.y" + case 441: /* type_specifier_nonarray: UTEXTURE2DRECT */ +#line 3011 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdRect); } -#line 9743 "MachineIndependent/glslang_tab.cpp" +#line 9880 "MachineIndependent/glslang_tab.cpp" break; - case 436: /* type_specifier_nonarray: TEXTUREBUFFER */ -#line 2999 "MachineIndependent/glslang.y" + case 442: /* type_specifier_nonarray: TEXTUREBUFFER */ +#line 3016 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, EsdBuffer); } -#line 9753 "MachineIndependent/glslang_tab.cpp" +#line 9890 "MachineIndependent/glslang_tab.cpp" break; - case 437: /* type_specifier_nonarray: F16TEXTUREBUFFER */ -#line 3004 "MachineIndependent/glslang.y" + case 443: /* type_specifier_nonarray: F16TEXTUREBUFFER */ +#line 3021 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, EsdBuffer); } -#line 9764 "MachineIndependent/glslang_tab.cpp" +#line 9901 "MachineIndependent/glslang_tab.cpp" break; - case 438: /* type_specifier_nonarray: ITEXTUREBUFFER */ -#line 3010 "MachineIndependent/glslang.y" + case 444: /* type_specifier_nonarray: ITEXTUREBUFFER */ +#line 3027 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, EsdBuffer); } -#line 9774 "MachineIndependent/glslang_tab.cpp" +#line 9911 "MachineIndependent/glslang_tab.cpp" break; - case 439: /* type_specifier_nonarray: UTEXTUREBUFFER */ -#line 3015 "MachineIndependent/glslang.y" + case 445: /* type_specifier_nonarray: UTEXTUREBUFFER */ +#line 3032 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, EsdBuffer); } -#line 9784 "MachineIndependent/glslang_tab.cpp" +#line 9921 "MachineIndependent/glslang_tab.cpp" break; - case 440: /* type_specifier_nonarray: TEXTURE2DMS */ -#line 3020 "MachineIndependent/glslang.y" + case 446: /* type_specifier_nonarray: TEXTURE2DMS */ +#line 3037 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, false, false, true); } -#line 9794 "MachineIndependent/glslang_tab.cpp" +#line 9931 "MachineIndependent/glslang_tab.cpp" break; - case 441: /* type_specifier_nonarray: F16TEXTURE2DMS */ -#line 3025 "MachineIndependent/glslang.y" + case 447: /* type_specifier_nonarray: F16TEXTURE2DMS */ +#line 3042 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, false, false, true); } -#line 9805 "MachineIndependent/glslang_tab.cpp" +#line 9942 "MachineIndependent/glslang_tab.cpp" break; - case 442: /* type_specifier_nonarray: ITEXTURE2DMS */ -#line 3031 "MachineIndependent/glslang.y" + case 448: /* type_specifier_nonarray: ITEXTURE2DMS */ +#line 3048 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, false, false, true); } -#line 9815 "MachineIndependent/glslang_tab.cpp" +#line 9952 "MachineIndependent/glslang_tab.cpp" break; - case 443: /* type_specifier_nonarray: UTEXTURE2DMS */ -#line 3036 "MachineIndependent/glslang.y" + case 449: /* type_specifier_nonarray: UTEXTURE2DMS */ +#line 3053 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, false, false, true); } -#line 9825 "MachineIndependent/glslang_tab.cpp" +#line 9962 "MachineIndependent/glslang_tab.cpp" break; - case 444: /* type_specifier_nonarray: TEXTURE2DMSARRAY */ -#line 3041 "MachineIndependent/glslang.y" + case 450: /* type_specifier_nonarray: TEXTURE2DMSARRAY */ +#line 3058 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat, Esd2D, true, false, true); } -#line 9835 "MachineIndependent/glslang_tab.cpp" +#line 9972 "MachineIndependent/glslang_tab.cpp" break; - case 445: /* type_specifier_nonarray: F16TEXTURE2DMSARRAY */ -#line 3046 "MachineIndependent/glslang.y" + case 451: /* type_specifier_nonarray: F16TEXTURE2DMSARRAY */ +#line 3063 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float texture", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtFloat16, Esd2D, true, false, true); } -#line 9846 "MachineIndependent/glslang_tab.cpp" +#line 9983 "MachineIndependent/glslang_tab.cpp" break; - case 446: /* type_specifier_nonarray: ITEXTURE2DMSARRAY */ -#line 3052 "MachineIndependent/glslang.y" + case 452: /* type_specifier_nonarray: ITEXTURE2DMSARRAY */ +#line 3069 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtInt, Esd2D, true, false, true); } -#line 9856 "MachineIndependent/glslang_tab.cpp" +#line 9993 "MachineIndependent/glslang_tab.cpp" break; - case 447: /* type_specifier_nonarray: UTEXTURE2DMSARRAY */ -#line 3057 "MachineIndependent/glslang.y" + case 453: /* type_specifier_nonarray: UTEXTURE2DMSARRAY */ +#line 3074 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setTexture(EbtUint, Esd2D, true, false, true); } -#line 9866 "MachineIndependent/glslang_tab.cpp" +#line 10003 "MachineIndependent/glslang_tab.cpp" break; - case 448: /* type_specifier_nonarray: IMAGE1D */ -#line 3062 "MachineIndependent/glslang.y" + case 454: /* type_specifier_nonarray: IMAGE1D */ +#line 3079 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd1D); } -#line 9876 "MachineIndependent/glslang_tab.cpp" +#line 10013 "MachineIndependent/glslang_tab.cpp" break; - case 449: /* type_specifier_nonarray: F16IMAGE1D */ -#line 3067 "MachineIndependent/glslang.y" + case 455: /* type_specifier_nonarray: F16IMAGE1D */ +#line 3084 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd1D); } -#line 9887 "MachineIndependent/glslang_tab.cpp" +#line 10024 "MachineIndependent/glslang_tab.cpp" break; - case 450: /* type_specifier_nonarray: IIMAGE1D */ -#line 3073 "MachineIndependent/glslang.y" + case 456: /* type_specifier_nonarray: IIMAGE1D */ +#line 3090 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd1D); } -#line 9897 "MachineIndependent/glslang_tab.cpp" +#line 10034 "MachineIndependent/glslang_tab.cpp" break; - case 451: /* type_specifier_nonarray: UIMAGE1D */ -#line 3078 "MachineIndependent/glslang.y" + case 457: /* type_specifier_nonarray: UIMAGE1D */ +#line 3095 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd1D); } -#line 9907 "MachineIndependent/glslang_tab.cpp" +#line 10044 "MachineIndependent/glslang_tab.cpp" break; - case 452: /* type_specifier_nonarray: IMAGE2D */ -#line 3083 "MachineIndependent/glslang.y" + case 458: /* type_specifier_nonarray: IMAGE2D */ +#line 3100 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D); } -#line 9917 "MachineIndependent/glslang_tab.cpp" +#line 10054 "MachineIndependent/glslang_tab.cpp" break; - case 453: /* type_specifier_nonarray: F16IMAGE2D */ -#line 3088 "MachineIndependent/glslang.y" + case 459: /* type_specifier_nonarray: F16IMAGE2D */ +#line 3105 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D); } -#line 9928 "MachineIndependent/glslang_tab.cpp" +#line 10065 "MachineIndependent/glslang_tab.cpp" break; - case 454: /* type_specifier_nonarray: IIMAGE2D */ -#line 3094 "MachineIndependent/glslang.y" + case 460: /* type_specifier_nonarray: IIMAGE2D */ +#line 3111 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D); } -#line 9938 "MachineIndependent/glslang_tab.cpp" +#line 10075 "MachineIndependent/glslang_tab.cpp" break; - case 455: /* type_specifier_nonarray: UIMAGE2D */ -#line 3099 "MachineIndependent/glslang.y" + case 461: /* type_specifier_nonarray: UIMAGE2D */ +#line 3116 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D); } -#line 9948 "MachineIndependent/glslang_tab.cpp" +#line 10085 "MachineIndependent/glslang_tab.cpp" break; - case 456: /* type_specifier_nonarray: IMAGE3D */ -#line 3104 "MachineIndependent/glslang.y" + case 462: /* type_specifier_nonarray: IMAGE3D */ +#line 3121 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd3D); } -#line 9958 "MachineIndependent/glslang_tab.cpp" +#line 10095 "MachineIndependent/glslang_tab.cpp" break; - case 457: /* type_specifier_nonarray: F16IMAGE3D */ -#line 3109 "MachineIndependent/glslang.y" + case 463: /* type_specifier_nonarray: F16IMAGE3D */ +#line 3126 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd3D); } -#line 9969 "MachineIndependent/glslang_tab.cpp" +#line 10106 "MachineIndependent/glslang_tab.cpp" break; - case 458: /* type_specifier_nonarray: IIMAGE3D */ -#line 3115 "MachineIndependent/glslang.y" + case 464: /* type_specifier_nonarray: IIMAGE3D */ +#line 3132 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd3D); } -#line 9979 "MachineIndependent/glslang_tab.cpp" +#line 10116 "MachineIndependent/glslang_tab.cpp" break; - case 459: /* type_specifier_nonarray: UIMAGE3D */ -#line 3120 "MachineIndependent/glslang.y" + case 465: /* type_specifier_nonarray: UIMAGE3D */ +#line 3137 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd3D); } -#line 9989 "MachineIndependent/glslang_tab.cpp" +#line 10126 "MachineIndependent/glslang_tab.cpp" break; - case 460: /* type_specifier_nonarray: IMAGE2DRECT */ -#line 3125 "MachineIndependent/glslang.y" + case 466: /* type_specifier_nonarray: IMAGE2DRECT */ +#line 3142 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdRect); } -#line 9999 "MachineIndependent/glslang_tab.cpp" +#line 10136 "MachineIndependent/glslang_tab.cpp" break; - case 461: /* type_specifier_nonarray: F16IMAGE2DRECT */ -#line 3130 "MachineIndependent/glslang.y" + case 467: /* type_specifier_nonarray: F16IMAGE2DRECT */ +#line 3147 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdRect); } -#line 10010 "MachineIndependent/glslang_tab.cpp" +#line 10147 "MachineIndependent/glslang_tab.cpp" break; - case 462: /* type_specifier_nonarray: IIMAGE2DRECT */ -#line 3136 "MachineIndependent/glslang.y" + case 468: /* type_specifier_nonarray: IIMAGE2DRECT */ +#line 3153 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdRect); } -#line 10020 "MachineIndependent/glslang_tab.cpp" +#line 10157 "MachineIndependent/glslang_tab.cpp" break; - case 463: /* type_specifier_nonarray: UIMAGE2DRECT */ -#line 3141 "MachineIndependent/glslang.y" + case 469: /* type_specifier_nonarray: UIMAGE2DRECT */ +#line 3158 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdRect); } -#line 10030 "MachineIndependent/glslang_tab.cpp" +#line 10167 "MachineIndependent/glslang_tab.cpp" break; - case 464: /* type_specifier_nonarray: IMAGECUBE */ -#line 3146 "MachineIndependent/glslang.y" + case 470: /* type_specifier_nonarray: IMAGECUBE */ +#line 3163 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdCube); } -#line 10040 "MachineIndependent/glslang_tab.cpp" +#line 10177 "MachineIndependent/glslang_tab.cpp" break; - case 465: /* type_specifier_nonarray: F16IMAGECUBE */ -#line 3151 "MachineIndependent/glslang.y" + case 471: /* type_specifier_nonarray: F16IMAGECUBE */ +#line 3168 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdCube); } -#line 10051 "MachineIndependent/glslang_tab.cpp" +#line 10188 "MachineIndependent/glslang_tab.cpp" break; - case 466: /* type_specifier_nonarray: IIMAGECUBE */ -#line 3157 "MachineIndependent/glslang.y" + case 472: /* type_specifier_nonarray: IIMAGECUBE */ +#line 3174 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdCube); } -#line 10061 "MachineIndependent/glslang_tab.cpp" +#line 10198 "MachineIndependent/glslang_tab.cpp" break; - case 467: /* type_specifier_nonarray: UIMAGECUBE */ -#line 3162 "MachineIndependent/glslang.y" + case 473: /* type_specifier_nonarray: UIMAGECUBE */ +#line 3179 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdCube); } -#line 10071 "MachineIndependent/glslang_tab.cpp" +#line 10208 "MachineIndependent/glslang_tab.cpp" break; - case 468: /* type_specifier_nonarray: IMAGEBUFFER */ -#line 3167 "MachineIndependent/glslang.y" + case 474: /* type_specifier_nonarray: IMAGEBUFFER */ +#line 3184 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdBuffer); } -#line 10081 "MachineIndependent/glslang_tab.cpp" +#line 10218 "MachineIndependent/glslang_tab.cpp" break; - case 469: /* type_specifier_nonarray: F16IMAGEBUFFER */ -#line 3172 "MachineIndependent/glslang.y" + case 475: /* type_specifier_nonarray: F16IMAGEBUFFER */ +#line 3189 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdBuffer); } -#line 10092 "MachineIndependent/glslang_tab.cpp" +#line 10229 "MachineIndependent/glslang_tab.cpp" break; - case 470: /* type_specifier_nonarray: IIMAGEBUFFER */ -#line 3178 "MachineIndependent/glslang.y" + case 476: /* type_specifier_nonarray: IIMAGEBUFFER */ +#line 3195 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdBuffer); } -#line 10102 "MachineIndependent/glslang_tab.cpp" +#line 10239 "MachineIndependent/glslang_tab.cpp" break; - case 471: /* type_specifier_nonarray: UIMAGEBUFFER */ -#line 3183 "MachineIndependent/glslang.y" + case 477: /* type_specifier_nonarray: UIMAGEBUFFER */ +#line 3200 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdBuffer); } -#line 10112 "MachineIndependent/glslang_tab.cpp" +#line 10249 "MachineIndependent/glslang_tab.cpp" break; - case 472: /* type_specifier_nonarray: IMAGE1DARRAY */ -#line 3188 "MachineIndependent/glslang.y" + case 478: /* type_specifier_nonarray: IMAGE1DARRAY */ +#line 3205 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd1D, true); } -#line 10122 "MachineIndependent/glslang_tab.cpp" +#line 10259 "MachineIndependent/glslang_tab.cpp" break; - case 473: /* type_specifier_nonarray: F16IMAGE1DARRAY */ -#line 3193 "MachineIndependent/glslang.y" + case 479: /* type_specifier_nonarray: F16IMAGE1DARRAY */ +#line 3210 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd1D, true); } -#line 10133 "MachineIndependent/glslang_tab.cpp" +#line 10270 "MachineIndependent/glslang_tab.cpp" break; - case 474: /* type_specifier_nonarray: IIMAGE1DARRAY */ -#line 3199 "MachineIndependent/glslang.y" + case 480: /* type_specifier_nonarray: IIMAGE1DARRAY */ +#line 3216 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd1D, true); } -#line 10143 "MachineIndependent/glslang_tab.cpp" +#line 10280 "MachineIndependent/glslang_tab.cpp" break; - case 475: /* type_specifier_nonarray: UIMAGE1DARRAY */ -#line 3204 "MachineIndependent/glslang.y" + case 481: /* type_specifier_nonarray: UIMAGE1DARRAY */ +#line 3221 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd1D, true); } -#line 10153 "MachineIndependent/glslang_tab.cpp" +#line 10290 "MachineIndependent/glslang_tab.cpp" break; - case 476: /* type_specifier_nonarray: IMAGE2DARRAY */ -#line 3209 "MachineIndependent/glslang.y" + case 482: /* type_specifier_nonarray: IMAGE2DARRAY */ +#line 3226 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, true); } -#line 10163 "MachineIndependent/glslang_tab.cpp" +#line 10300 "MachineIndependent/glslang_tab.cpp" break; - case 477: /* type_specifier_nonarray: F16IMAGE2DARRAY */ -#line 3214 "MachineIndependent/glslang.y" + case 483: /* type_specifier_nonarray: F16IMAGE2DARRAY */ +#line 3231 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, true); } -#line 10174 "MachineIndependent/glslang_tab.cpp" +#line 10311 "MachineIndependent/glslang_tab.cpp" break; - case 478: /* type_specifier_nonarray: IIMAGE2DARRAY */ -#line 3220 "MachineIndependent/glslang.y" + case 484: /* type_specifier_nonarray: IIMAGE2DARRAY */ +#line 3237 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, true); } -#line 10184 "MachineIndependent/glslang_tab.cpp" +#line 10321 "MachineIndependent/glslang_tab.cpp" break; - case 479: /* type_specifier_nonarray: UIMAGE2DARRAY */ -#line 3225 "MachineIndependent/glslang.y" + case 485: /* type_specifier_nonarray: UIMAGE2DARRAY */ +#line 3242 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, true); } -#line 10194 "MachineIndependent/glslang_tab.cpp" +#line 10331 "MachineIndependent/glslang_tab.cpp" break; - case 480: /* type_specifier_nonarray: IMAGECUBEARRAY */ -#line 3230 "MachineIndependent/glslang.y" + case 486: /* type_specifier_nonarray: IMAGECUBEARRAY */ +#line 3247 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, EsdCube, true); } -#line 10204 "MachineIndependent/glslang_tab.cpp" +#line 10341 "MachineIndependent/glslang_tab.cpp" break; - case 481: /* type_specifier_nonarray: F16IMAGECUBEARRAY */ -#line 3235 "MachineIndependent/glslang.y" + case 487: /* type_specifier_nonarray: F16IMAGECUBEARRAY */ +#line 3252 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, EsdCube, true); } -#line 10215 "MachineIndependent/glslang_tab.cpp" +#line 10352 "MachineIndependent/glslang_tab.cpp" break; - case 482: /* type_specifier_nonarray: IIMAGECUBEARRAY */ -#line 3241 "MachineIndependent/glslang.y" + case 488: /* type_specifier_nonarray: IIMAGECUBEARRAY */ +#line 3258 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, EsdCube, true); } -#line 10225 "MachineIndependent/glslang_tab.cpp" +#line 10362 "MachineIndependent/glslang_tab.cpp" break; - case 483: /* type_specifier_nonarray: UIMAGECUBEARRAY */ -#line 3246 "MachineIndependent/glslang.y" + case 489: /* type_specifier_nonarray: UIMAGECUBEARRAY */ +#line 3263 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, EsdCube, true); } -#line 10235 "MachineIndependent/glslang_tab.cpp" +#line 10372 "MachineIndependent/glslang_tab.cpp" break; - case 484: /* type_specifier_nonarray: IMAGE2DMS */ -#line 3251 "MachineIndependent/glslang.y" + case 490: /* type_specifier_nonarray: IMAGE2DMS */ +#line 3268 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, false, false, true); } -#line 10245 "MachineIndependent/glslang_tab.cpp" +#line 10382 "MachineIndependent/glslang_tab.cpp" break; - case 485: /* type_specifier_nonarray: F16IMAGE2DMS */ -#line 3256 "MachineIndependent/glslang.y" + case 491: /* type_specifier_nonarray: F16IMAGE2DMS */ +#line 3273 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, false, false, true); } -#line 10256 "MachineIndependent/glslang_tab.cpp" +#line 10393 "MachineIndependent/glslang_tab.cpp" break; - case 486: /* type_specifier_nonarray: IIMAGE2DMS */ -#line 3262 "MachineIndependent/glslang.y" + case 492: /* type_specifier_nonarray: IIMAGE2DMS */ +#line 3279 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, false, false, true); } -#line 10266 "MachineIndependent/glslang_tab.cpp" +#line 10403 "MachineIndependent/glslang_tab.cpp" break; - case 487: /* type_specifier_nonarray: UIMAGE2DMS */ -#line 3267 "MachineIndependent/glslang.y" + case 493: /* type_specifier_nonarray: UIMAGE2DMS */ +#line 3284 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, false, false, true); } -#line 10276 "MachineIndependent/glslang_tab.cpp" +#line 10413 "MachineIndependent/glslang_tab.cpp" break; - case 488: /* type_specifier_nonarray: IMAGE2DMSARRAY */ -#line 3272 "MachineIndependent/glslang.y" + case 494: /* type_specifier_nonarray: IMAGE2DMSARRAY */ +#line 3289 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat, Esd2D, true, false, true); } -#line 10286 "MachineIndependent/glslang_tab.cpp" +#line 10423 "MachineIndependent/glslang_tab.cpp" break; - case 489: /* type_specifier_nonarray: F16IMAGE2DMSARRAY */ -#line 3277 "MachineIndependent/glslang.y" + case 495: /* type_specifier_nonarray: F16IMAGE2DMSARRAY */ +#line 3294 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float image", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtFloat16, Esd2D, true, false, true); } -#line 10297 "MachineIndependent/glslang_tab.cpp" +#line 10434 "MachineIndependent/glslang_tab.cpp" break; - case 490: /* type_specifier_nonarray: IIMAGE2DMSARRAY */ -#line 3283 "MachineIndependent/glslang.y" + case 496: /* type_specifier_nonarray: IIMAGE2DMSARRAY */ +#line 3300 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt, Esd2D, true, false, true); } -#line 10307 "MachineIndependent/glslang_tab.cpp" +#line 10444 "MachineIndependent/glslang_tab.cpp" break; - case 491: /* type_specifier_nonarray: UIMAGE2DMSARRAY */ -#line 3288 "MachineIndependent/glslang.y" + case 497: /* type_specifier_nonarray: UIMAGE2DMSARRAY */ +#line 3305 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint, Esd2D, true, false, true); } -#line 10317 "MachineIndependent/glslang_tab.cpp" +#line 10454 "MachineIndependent/glslang_tab.cpp" break; - case 492: /* type_specifier_nonarray: I64IMAGE1D */ -#line 3293 "MachineIndependent/glslang.y" + case 498: /* type_specifier_nonarray: I64IMAGE1D */ +#line 3310 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd1D); } -#line 10327 "MachineIndependent/glslang_tab.cpp" +#line 10464 "MachineIndependent/glslang_tab.cpp" break; - case 493: /* type_specifier_nonarray: U64IMAGE1D */ -#line 3298 "MachineIndependent/glslang.y" + case 499: /* type_specifier_nonarray: U64IMAGE1D */ +#line 3315 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd1D); } -#line 10337 "MachineIndependent/glslang_tab.cpp" +#line 10474 "MachineIndependent/glslang_tab.cpp" break; - case 494: /* type_specifier_nonarray: I64IMAGE2D */ -#line 3303 "MachineIndependent/glslang.y" + case 500: /* type_specifier_nonarray: I64IMAGE2D */ +#line 3320 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd2D); } -#line 10347 "MachineIndependent/glslang_tab.cpp" +#line 10484 "MachineIndependent/glslang_tab.cpp" break; - case 495: /* type_specifier_nonarray: U64IMAGE2D */ -#line 3308 "MachineIndependent/glslang.y" + case 501: /* type_specifier_nonarray: U64IMAGE2D */ +#line 3325 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd2D); } -#line 10357 "MachineIndependent/glslang_tab.cpp" +#line 10494 "MachineIndependent/glslang_tab.cpp" break; - case 496: /* type_specifier_nonarray: I64IMAGE3D */ -#line 3313 "MachineIndependent/glslang.y" + case 502: /* type_specifier_nonarray: I64IMAGE3D */ +#line 3330 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd3D); } -#line 10367 "MachineIndependent/glslang_tab.cpp" +#line 10504 "MachineIndependent/glslang_tab.cpp" break; - case 497: /* type_specifier_nonarray: U64IMAGE3D */ -#line 3318 "MachineIndependent/glslang.y" + case 503: /* type_specifier_nonarray: U64IMAGE3D */ +#line 3335 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd3D); } -#line 10377 "MachineIndependent/glslang_tab.cpp" +#line 10514 "MachineIndependent/glslang_tab.cpp" break; - case 498: /* type_specifier_nonarray: I64IMAGE2DRECT */ -#line 3323 "MachineIndependent/glslang.y" + case 504: /* type_specifier_nonarray: I64IMAGE2DRECT */ +#line 3340 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, EsdRect); } -#line 10387 "MachineIndependent/glslang_tab.cpp" +#line 10524 "MachineIndependent/glslang_tab.cpp" break; - case 499: /* type_specifier_nonarray: U64IMAGE2DRECT */ -#line 3328 "MachineIndependent/glslang.y" + case 505: /* type_specifier_nonarray: U64IMAGE2DRECT */ +#line 3345 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, EsdRect); } -#line 10397 "MachineIndependent/glslang_tab.cpp" +#line 10534 "MachineIndependent/glslang_tab.cpp" break; - case 500: /* type_specifier_nonarray: I64IMAGECUBE */ -#line 3333 "MachineIndependent/glslang.y" + case 506: /* type_specifier_nonarray: I64IMAGECUBE */ +#line 3350 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, EsdCube); } -#line 10407 "MachineIndependent/glslang_tab.cpp" +#line 10544 "MachineIndependent/glslang_tab.cpp" break; - case 501: /* type_specifier_nonarray: U64IMAGECUBE */ -#line 3338 "MachineIndependent/glslang.y" + case 507: /* type_specifier_nonarray: U64IMAGECUBE */ +#line 3355 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, EsdCube); } -#line 10417 "MachineIndependent/glslang_tab.cpp" +#line 10554 "MachineIndependent/glslang_tab.cpp" break; - case 502: /* type_specifier_nonarray: I64IMAGEBUFFER */ -#line 3343 "MachineIndependent/glslang.y" + case 508: /* type_specifier_nonarray: I64IMAGEBUFFER */ +#line 3360 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, EsdBuffer); } -#line 10427 "MachineIndependent/glslang_tab.cpp" +#line 10564 "MachineIndependent/glslang_tab.cpp" break; - case 503: /* type_specifier_nonarray: U64IMAGEBUFFER */ -#line 3348 "MachineIndependent/glslang.y" + case 509: /* type_specifier_nonarray: U64IMAGEBUFFER */ +#line 3365 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, EsdBuffer); } -#line 10437 "MachineIndependent/glslang_tab.cpp" +#line 10574 "MachineIndependent/glslang_tab.cpp" break; - case 504: /* type_specifier_nonarray: I64IMAGE1DARRAY */ -#line 3353 "MachineIndependent/glslang.y" + case 510: /* type_specifier_nonarray: I64IMAGE1DARRAY */ +#line 3370 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd1D, true); } -#line 10447 "MachineIndependent/glslang_tab.cpp" +#line 10584 "MachineIndependent/glslang_tab.cpp" break; - case 505: /* type_specifier_nonarray: U64IMAGE1DARRAY */ -#line 3358 "MachineIndependent/glslang.y" + case 511: /* type_specifier_nonarray: U64IMAGE1DARRAY */ +#line 3375 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd1D, true); } -#line 10457 "MachineIndependent/glslang_tab.cpp" +#line 10594 "MachineIndependent/glslang_tab.cpp" break; - case 506: /* type_specifier_nonarray: I64IMAGE2DARRAY */ -#line 3363 "MachineIndependent/glslang.y" + case 512: /* type_specifier_nonarray: I64IMAGE2DARRAY */ +#line 3380 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd2D, true); } -#line 10467 "MachineIndependent/glslang_tab.cpp" +#line 10604 "MachineIndependent/glslang_tab.cpp" break; - case 507: /* type_specifier_nonarray: U64IMAGE2DARRAY */ -#line 3368 "MachineIndependent/glslang.y" + case 513: /* type_specifier_nonarray: U64IMAGE2DARRAY */ +#line 3385 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd2D, true); } -#line 10477 "MachineIndependent/glslang_tab.cpp" +#line 10614 "MachineIndependent/glslang_tab.cpp" break; - case 508: /* type_specifier_nonarray: I64IMAGECUBEARRAY */ -#line 3373 "MachineIndependent/glslang.y" + case 514: /* type_specifier_nonarray: I64IMAGECUBEARRAY */ +#line 3390 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, EsdCube, true); } -#line 10487 "MachineIndependent/glslang_tab.cpp" +#line 10624 "MachineIndependent/glslang_tab.cpp" break; - case 509: /* type_specifier_nonarray: U64IMAGECUBEARRAY */ -#line 3378 "MachineIndependent/glslang.y" + case 515: /* type_specifier_nonarray: U64IMAGECUBEARRAY */ +#line 3395 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, EsdCube, true); } -#line 10497 "MachineIndependent/glslang_tab.cpp" +#line 10634 "MachineIndependent/glslang_tab.cpp" break; - case 510: /* type_specifier_nonarray: I64IMAGE2DMS */ -#line 3383 "MachineIndependent/glslang.y" + case 516: /* type_specifier_nonarray: I64IMAGE2DMS */ +#line 3400 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd2D, false, false, true); } -#line 10507 "MachineIndependent/glslang_tab.cpp" +#line 10644 "MachineIndependent/glslang_tab.cpp" break; - case 511: /* type_specifier_nonarray: U64IMAGE2DMS */ -#line 3388 "MachineIndependent/glslang.y" + case 517: /* type_specifier_nonarray: U64IMAGE2DMS */ +#line 3405 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd2D, false, false, true); } -#line 10517 "MachineIndependent/glslang_tab.cpp" +#line 10654 "MachineIndependent/glslang_tab.cpp" break; - case 512: /* type_specifier_nonarray: I64IMAGE2DMSARRAY */ -#line 3393 "MachineIndependent/glslang.y" + case 518: /* type_specifier_nonarray: I64IMAGE2DMSARRAY */ +#line 3410 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtInt64, Esd2D, true, false, true); } -#line 10527 "MachineIndependent/glslang_tab.cpp" +#line 10664 "MachineIndependent/glslang_tab.cpp" break; - case 513: /* type_specifier_nonarray: U64IMAGE2DMSARRAY */ -#line 3398 "MachineIndependent/glslang.y" + case 519: /* type_specifier_nonarray: U64IMAGE2DMSARRAY */ +#line 3415 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setImage(EbtUint64, Esd2D, true, false, true); } -#line 10537 "MachineIndependent/glslang_tab.cpp" +#line 10674 "MachineIndependent/glslang_tab.cpp" break; - case 514: /* type_specifier_nonarray: SAMPLEREXTERNALOES */ -#line 3403 "MachineIndependent/glslang.y" + case 520: /* type_specifier_nonarray: SAMPLEREXTERNALOES */ +#line 3420 "MachineIndependent/glslang.y" { // GL_OES_EGL_image_external (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D); (yyval.interm.type).sampler.external = true; } -#line 10548 "MachineIndependent/glslang_tab.cpp" +#line 10685 "MachineIndependent/glslang_tab.cpp" break; - case 515: /* type_specifier_nonarray: SAMPLEREXTERNAL2DY2YEXT */ -#line 3409 "MachineIndependent/glslang.y" + case 521: /* type_specifier_nonarray: SAMPLEREXTERNAL2DY2YEXT */ +#line 3426 "MachineIndependent/glslang.y" { // GL_EXT_YUV_target (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.set(EbtFloat, Esd2D); (yyval.interm.type).sampler.yuv = true; } -#line 10559 "MachineIndependent/glslang_tab.cpp" +#line 10696 "MachineIndependent/glslang_tab.cpp" break; - case 516: /* type_specifier_nonarray: SUBPASSINPUT */ -#line 3415 "MachineIndependent/glslang.y" + case 522: /* type_specifier_nonarray: ATTACHMENTEXT */ +#line 3432 "MachineIndependent/glslang.y" + { + parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "attachmentEXT input"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setAttachmentEXT(EbtFloat); + } +#line 10707 "MachineIndependent/glslang_tab.cpp" + break; + + case 523: /* type_specifier_nonarray: IATTACHMENTEXT */ +#line 3438 "MachineIndependent/glslang.y" + { + parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "attachmentEXT input"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setAttachmentEXT(EbtInt); + } +#line 10718 "MachineIndependent/glslang_tab.cpp" + break; + + case 524: /* type_specifier_nonarray: UATTACHMENTEXT */ +#line 3444 "MachineIndependent/glslang.y" + { + parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "attachmentEXT input"); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtSampler; + (yyval.interm.type).sampler.setAttachmentEXT(EbtUint); + } +#line 10729 "MachineIndependent/glslang_tab.cpp" + break; + + case 525: /* type_specifier_nonarray: SUBPASSINPUT */ +#line 3450 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat); } -#line 10570 "MachineIndependent/glslang_tab.cpp" +#line 10740 "MachineIndependent/glslang_tab.cpp" break; - case 517: /* type_specifier_nonarray: SUBPASSINPUTMS */ -#line 3421 "MachineIndependent/glslang.y" + case 526: /* type_specifier_nonarray: SUBPASSINPUTMS */ +#line 3456 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat, true); } -#line 10581 "MachineIndependent/glslang_tab.cpp" +#line 10751 "MachineIndependent/glslang_tab.cpp" break; - case 518: /* type_specifier_nonarray: F16SUBPASSINPUT */ -#line 3427 "MachineIndependent/glslang.y" + case 527: /* type_specifier_nonarray: F16SUBPASSINPUT */ +#line 3462 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); @@ -10589,11 +10759,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat16); } -#line 10593 "MachineIndependent/glslang_tab.cpp" +#line 10763 "MachineIndependent/glslang_tab.cpp" break; - case 519: /* type_specifier_nonarray: F16SUBPASSINPUTMS */ -#line 3434 "MachineIndependent/glslang.y" + case 528: /* type_specifier_nonarray: F16SUBPASSINPUTMS */ +#line 3469 "MachineIndependent/glslang.y" { parseContext.float16OpaqueCheck((yyvsp[0].lex).loc, "half float subpass input", parseContext.symbolTable.atBuiltInLevel()); parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); @@ -10601,107 +10771,131 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtFloat16, true); } -#line 10605 "MachineIndependent/glslang_tab.cpp" +#line 10775 "MachineIndependent/glslang_tab.cpp" break; - case 520: /* type_specifier_nonarray: ISUBPASSINPUT */ -#line 3441 "MachineIndependent/glslang.y" + case 529: /* type_specifier_nonarray: ISUBPASSINPUT */ +#line 3476 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtInt); } -#line 10616 "MachineIndependent/glslang_tab.cpp" +#line 10786 "MachineIndependent/glslang_tab.cpp" break; - case 521: /* type_specifier_nonarray: ISUBPASSINPUTMS */ -#line 3447 "MachineIndependent/glslang.y" + case 530: /* type_specifier_nonarray: ISUBPASSINPUTMS */ +#line 3482 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtInt, true); } -#line 10627 "MachineIndependent/glslang_tab.cpp" +#line 10797 "MachineIndependent/glslang_tab.cpp" break; - case 522: /* type_specifier_nonarray: USUBPASSINPUT */ -#line 3453 "MachineIndependent/glslang.y" + case 531: /* type_specifier_nonarray: USUBPASSINPUT */ +#line 3488 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtUint); } -#line 10638 "MachineIndependent/glslang_tab.cpp" +#line 10808 "MachineIndependent/glslang_tab.cpp" break; - case 523: /* type_specifier_nonarray: USUBPASSINPUTMS */ -#line 3459 "MachineIndependent/glslang.y" + case 532: /* type_specifier_nonarray: USUBPASSINPUTMS */ +#line 3494 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[0].lex).loc, EShLangFragment, "subpass input"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtSampler; (yyval.interm.type).sampler.setSubpass(EbtUint, true); } -#line 10649 "MachineIndependent/glslang_tab.cpp" +#line 10819 "MachineIndependent/glslang_tab.cpp" break; - case 524: /* type_specifier_nonarray: FCOOPMATNV */ -#line 3465 "MachineIndependent/glslang.y" + case 533: /* type_specifier_nonarray: FCOOPMATNV */ +#line 3500 "MachineIndependent/glslang.y" { - parseContext.fcoopmatCheck((yyvsp[0].lex).loc, "fcoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + parseContext.fcoopmatCheckNV((yyvsp[0].lex).loc, "fcoopmatNV", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtFloat; - (yyval.interm.type).coopmat = true; + (yyval.interm.type).coopmatNV = true; + (yyval.interm.type).coopmatKHR = false; } -#line 10660 "MachineIndependent/glslang_tab.cpp" +#line 10831 "MachineIndependent/glslang_tab.cpp" break; - case 525: /* type_specifier_nonarray: ICOOPMATNV */ -#line 3471 "MachineIndependent/glslang.y" + case 534: /* type_specifier_nonarray: ICOOPMATNV */ +#line 3507 "MachineIndependent/glslang.y" { - parseContext.intcoopmatCheck((yyvsp[0].lex).loc, "icoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + parseContext.intcoopmatCheckNV((yyvsp[0].lex).loc, "icoopmatNV", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtInt; - (yyval.interm.type).coopmat = true; + (yyval.interm.type).coopmatNV = true; + (yyval.interm.type).coopmatKHR = false; } -#line 10671 "MachineIndependent/glslang_tab.cpp" +#line 10843 "MachineIndependent/glslang_tab.cpp" break; - case 526: /* type_specifier_nonarray: UCOOPMATNV */ -#line 3477 "MachineIndependent/glslang.y" + case 535: /* type_specifier_nonarray: UCOOPMATNV */ +#line 3514 "MachineIndependent/glslang.y" { - parseContext.intcoopmatCheck((yyvsp[0].lex).loc, "ucoopmatNV", parseContext.symbolTable.atBuiltInLevel()); + parseContext.intcoopmatCheckNV((yyvsp[0].lex).loc, "ucoopmatNV", parseContext.symbolTable.atBuiltInLevel()); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).basicType = EbtUint; - (yyval.interm.type).coopmat = true; + (yyval.interm.type).coopmatNV = true; + (yyval.interm.type).coopmatKHR = false; + } +#line 10855 "MachineIndependent/glslang_tab.cpp" + break; + + case 536: /* type_specifier_nonarray: COOPMAT */ +#line 3521 "MachineIndependent/glslang.y" + { + parseContext.coopmatCheck((yyvsp[0].lex).loc, "coopmat", parseContext.symbolTable.atBuiltInLevel()); + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtCoopmat; + (yyval.interm.type).coopmatNV = false; + (yyval.interm.type).coopmatKHR = true; } -#line 10682 "MachineIndependent/glslang_tab.cpp" +#line 10867 "MachineIndependent/glslang_tab.cpp" break; - case 527: /* type_specifier_nonarray: spirv_type_specifier */ -#line 3483 "MachineIndependent/glslang.y" + case 537: /* type_specifier_nonarray: spirv_type_specifier */ +#line 3528 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[0].interm.type).loc, 1, &E_GL_EXT_spirv_intrinsics, "SPIR-V type specifier"); (yyval.interm.type) = (yyvsp[0].interm.type); } -#line 10691 "MachineIndependent/glslang_tab.cpp" +#line 10876 "MachineIndependent/glslang_tab.cpp" break; - case 528: /* type_specifier_nonarray: struct_specifier */ -#line 3488 "MachineIndependent/glslang.y" + case 538: /* type_specifier_nonarray: HITOBJECTNV */ +#line 3532 "MachineIndependent/glslang.y" + { + (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); + (yyval.interm.type).basicType = EbtHitObjectNV; + } +#line 10885 "MachineIndependent/glslang_tab.cpp" + break; + + case 539: /* type_specifier_nonarray: struct_specifier */ +#line 3536 "MachineIndependent/glslang.y" { (yyval.interm.type) = (yyvsp[0].interm.type); (yyval.interm.type).qualifier.storage = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; parseContext.structTypeCheck((yyval.interm.type).loc, (yyval.interm.type)); } -#line 10701 "MachineIndependent/glslang_tab.cpp" +#line 10895 "MachineIndependent/glslang_tab.cpp" break; - case 529: /* type_specifier_nonarray: TYPE_NAME */ -#line 3493 "MachineIndependent/glslang.y" + case 540: /* type_specifier_nonarray: TYPE_NAME */ +#line 3541 "MachineIndependent/glslang.y" { // // This is for user defined type names. The lexical phase looked up the @@ -10715,69 +10909,75 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } else parseContext.error((yyvsp[0].lex).loc, "expected type name", (yyvsp[0].lex).string->c_str(), ""); } -#line 10719 "MachineIndependent/glslang_tab.cpp" +#line 10913 "MachineIndependent/glslang_tab.cpp" break; - case 530: /* precision_qualifier: HIGH_PRECISION */ -#line 3509 "MachineIndependent/glslang.y" + case 541: /* precision_qualifier: HIGH_PRECISION */ +#line 3557 "MachineIndependent/glslang.y" { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "highp precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqHigh); } -#line 10729 "MachineIndependent/glslang_tab.cpp" +#line 10923 "MachineIndependent/glslang_tab.cpp" break; - case 531: /* precision_qualifier: MEDIUM_PRECISION */ -#line 3514 "MachineIndependent/glslang.y" + case 542: /* precision_qualifier: MEDIUM_PRECISION */ +#line 3562 "MachineIndependent/glslang.y" { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "mediump precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqMedium); } -#line 10739 "MachineIndependent/glslang_tab.cpp" +#line 10933 "MachineIndependent/glslang_tab.cpp" break; - case 532: /* precision_qualifier: LOW_PRECISION */ -#line 3519 "MachineIndependent/glslang.y" + case 543: /* precision_qualifier: LOW_PRECISION */ +#line 3567 "MachineIndependent/glslang.y" { parseContext.profileRequires((yyvsp[0].lex).loc, ENoProfile, 130, 0, "lowp precision qualifier"); (yyval.interm.type).init((yyvsp[0].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.handlePrecisionQualifier((yyvsp[0].lex).loc, (yyval.interm.type).qualifier, EpqLow); } -#line 10749 "MachineIndependent/glslang_tab.cpp" +#line 10943 "MachineIndependent/glslang_tab.cpp" break; - case 533: /* $@3: %empty */ -#line 3527 "MachineIndependent/glslang.y" + case 544: /* $@3: %empty */ +#line 3575 "MachineIndependent/glslang.y" { parseContext.nestedStructCheck((yyvsp[-2].lex).loc); } -#line 10755 "MachineIndependent/glslang_tab.cpp" +#line 10949 "MachineIndependent/glslang_tab.cpp" break; - case 534: /* struct_specifier: STRUCT IDENTIFIER LEFT_BRACE $@3 struct_declaration_list RIGHT_BRACE */ -#line 3527 "MachineIndependent/glslang.y" + case 545: /* struct_specifier: STRUCT IDENTIFIER LEFT_BRACE $@3 struct_declaration_list RIGHT_BRACE */ +#line 3575 "MachineIndependent/glslang.y" { + TType* structure = new TType((yyvsp[-1].interm.typeList), *(yyvsp[-4].lex).string); parseContext.structArrayCheck((yyvsp[-4].lex).loc, *structure); + TVariable* userTypeDef = new TVariable((yyvsp[-4].lex).string, *structure, true); if (! parseContext.symbolTable.insert(*userTypeDef)) parseContext.error((yyvsp[-4].lex).loc, "redefinition", (yyvsp[-4].lex).string->c_str(), "struct"); + else if (parseContext.spvVersion.vulkanRelaxed + && structure->containsOpaque()) + parseContext.relaxedSymbols.push_back(structure->getTypeName()); + (yyval.interm.type).init((yyvsp[-5].lex).loc); (yyval.interm.type).basicType = EbtStruct; (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 10771 "MachineIndependent/glslang_tab.cpp" +#line 10971 "MachineIndependent/glslang_tab.cpp" break; - case 535: /* $@4: %empty */ -#line 3538 "MachineIndependent/glslang.y" + case 546: /* $@4: %empty */ +#line 3592 "MachineIndependent/glslang.y" { parseContext.nestedStructCheck((yyvsp[-1].lex).loc); } -#line 10777 "MachineIndependent/glslang_tab.cpp" +#line 10977 "MachineIndependent/glslang_tab.cpp" break; - case 536: /* struct_specifier: STRUCT LEFT_BRACE $@4 struct_declaration_list RIGHT_BRACE */ -#line 3538 "MachineIndependent/glslang.y" + case 547: /* struct_specifier: STRUCT LEFT_BRACE $@4 struct_declaration_list RIGHT_BRACE */ +#line 3592 "MachineIndependent/glslang.y" { TType* structure = new TType((yyvsp[-1].interm.typeList), TString("")); (yyval.interm.type).init((yyvsp[-4].lex).loc); @@ -10785,19 +10985,19 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.type).userDef = structure; --parseContext.structNestingLevel; } -#line 10789 "MachineIndependent/glslang_tab.cpp" +#line 10989 "MachineIndependent/glslang_tab.cpp" break; - case 537: /* struct_declaration_list: struct_declaration */ -#line 3548 "MachineIndependent/glslang.y" + case 548: /* struct_declaration_list: struct_declaration */ +#line 3602 "MachineIndependent/glslang.y" { (yyval.interm.typeList) = (yyvsp[0].interm.typeList); } -#line 10797 "MachineIndependent/glslang_tab.cpp" +#line 10997 "MachineIndependent/glslang_tab.cpp" break; - case 538: /* struct_declaration_list: struct_declaration_list struct_declaration */ -#line 3551 "MachineIndependent/glslang.y" + case 549: /* struct_declaration_list: struct_declaration_list struct_declaration */ +#line 3605 "MachineIndependent/glslang.y" { (yyval.interm.typeList) = (yyvsp[-1].interm.typeList); for (unsigned int i = 0; i < (yyvsp[0].interm.typeList)->size(); ++i) { @@ -10808,11 +11008,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.typeList)->push_back((*(yyvsp[0].interm.typeList))[i]); } } -#line 10812 "MachineIndependent/glslang_tab.cpp" +#line 11012 "MachineIndependent/glslang_tab.cpp" break; - case 539: /* struct_declaration: type_specifier struct_declarator_list SEMICOLON */ -#line 3564 "MachineIndependent/glslang.y" + case 550: /* struct_declaration: type_specifier struct_declarator_list SEMICOLON */ +#line 3618 "MachineIndependent/glslang.y" { if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); @@ -10824,7 +11024,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.typeList) = (yyvsp[-1].interm.typeList); parseContext.voidErrorCheck((yyvsp[-2].interm.type).loc, (*(yyvsp[-1].interm.typeList))[0].type->getFieldName(), (yyvsp[-2].interm.type).basicType); - parseContext.precisionQualifierCheck((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).basicType, (yyvsp[-2].interm.type).qualifier); + parseContext.precisionQualifierCheck((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).basicType, (yyvsp[-2].interm.type).qualifier, (yyvsp[-2].interm.type).isCoopmat()); for (unsigned int i = 0; i < (yyval.interm.typeList)->size(); ++i) { TType type((yyvsp[-2].interm.type)); @@ -10835,11 +11035,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 10839 "MachineIndependent/glslang_tab.cpp" +#line 11039 "MachineIndependent/glslang_tab.cpp" break; - case 540: /* struct_declaration: type_qualifier type_specifier struct_declarator_list SEMICOLON */ -#line 3586 "MachineIndependent/glslang.y" + case 551: /* struct_declaration: type_qualifier type_specifier struct_declarator_list SEMICOLON */ +#line 3640 "MachineIndependent/glslang.y" { if ((yyvsp[-2].interm.type).arraySizes) { parseContext.profileRequires((yyvsp[-2].interm.type).loc, ENoProfile, 120, E_GL_3DL_array_objects, "arrayed type"); @@ -10853,7 +11053,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.memberQualifierCheck((yyvsp[-3].interm.type)); parseContext.voidErrorCheck((yyvsp[-2].interm.type).loc, (*(yyvsp[-1].interm.typeList))[0].type->getFieldName(), (yyvsp[-2].interm.type).basicType); parseContext.mergeQualifiers((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).qualifier, (yyvsp[-3].interm.type).qualifier, true); - parseContext.precisionQualifierCheck((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).basicType, (yyvsp[-2].interm.type).qualifier); + parseContext.precisionQualifierCheck((yyvsp[-2].interm.type).loc, (yyvsp[-2].interm.type).basicType, (yyvsp[-2].interm.type).qualifier, (yyvsp[-2].interm.type).isCoopmat()); for (unsigned int i = 0; i < (yyval.interm.typeList)->size(); ++i) { TType type((yyvsp[-2].interm.type)); @@ -10864,38 +11064,38 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (*(yyval.interm.typeList))[i].type->shallowCopy(type); } } -#line 10868 "MachineIndependent/glslang_tab.cpp" +#line 11068 "MachineIndependent/glslang_tab.cpp" break; - case 541: /* struct_declarator_list: struct_declarator */ -#line 3613 "MachineIndependent/glslang.y" + case 552: /* struct_declarator_list: struct_declarator */ +#line 3667 "MachineIndependent/glslang.y" { (yyval.interm.typeList) = new TTypeList; (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 10877 "MachineIndependent/glslang_tab.cpp" +#line 11077 "MachineIndependent/glslang_tab.cpp" break; - case 542: /* struct_declarator_list: struct_declarator_list COMMA struct_declarator */ -#line 3617 "MachineIndependent/glslang.y" + case 553: /* struct_declarator_list: struct_declarator_list COMMA struct_declarator */ +#line 3671 "MachineIndependent/glslang.y" { (yyval.interm.typeList)->push_back((yyvsp[0].interm.typeLine)); } -#line 10885 "MachineIndependent/glslang_tab.cpp" +#line 11085 "MachineIndependent/glslang_tab.cpp" break; - case 543: /* struct_declarator: IDENTIFIER */ -#line 3623 "MachineIndependent/glslang.y" + case 554: /* struct_declarator: IDENTIFIER */ +#line 3677 "MachineIndependent/glslang.y" { (yyval.interm.typeLine).type = new TType(EbtVoid); (yyval.interm.typeLine).loc = (yyvsp[0].lex).loc; (yyval.interm.typeLine).type->setFieldName(*(yyvsp[0].lex).string); } -#line 10895 "MachineIndependent/glslang_tab.cpp" +#line 11095 "MachineIndependent/glslang_tab.cpp" break; - case 544: /* struct_declarator: IDENTIFIER array_specifier */ -#line 3628 "MachineIndependent/glslang.y" + case 555: /* struct_declarator: IDENTIFIER array_specifier */ +#line 3682 "MachineIndependent/glslang.y" { parseContext.arrayOfArrayVersionCheck((yyvsp[-1].lex).loc, (yyvsp[0].interm).arraySizes); @@ -10904,246 +11104,246 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.typeLine).type->setFieldName(*(yyvsp[-1].lex).string); (yyval.interm.typeLine).type->transferArraySizes((yyvsp[0].interm).arraySizes); } -#line 10908 "MachineIndependent/glslang_tab.cpp" +#line 11108 "MachineIndependent/glslang_tab.cpp" break; - case 545: /* initializer: assignment_expression */ -#line 3639 "MachineIndependent/glslang.y" + case 556: /* initializer: assignment_expression */ +#line 3693 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 10916 "MachineIndependent/glslang_tab.cpp" +#line 11116 "MachineIndependent/glslang_tab.cpp" break; - case 546: /* initializer: LEFT_BRACE initializer_list RIGHT_BRACE */ -#line 3643 "MachineIndependent/glslang.y" + case 557: /* initializer: LEFT_BRACE initializer_list RIGHT_BRACE */ +#line 3696 "MachineIndependent/glslang.y" { const char* initFeature = "{ } style initializers"; parseContext.requireProfile((yyvsp[-2].lex).loc, ~EEsProfile, initFeature); parseContext.profileRequires((yyvsp[-2].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); (yyval.interm.intermTypedNode) = (yyvsp[-1].interm.intermTypedNode); } -#line 10927 "MachineIndependent/glslang_tab.cpp" +#line 11127 "MachineIndependent/glslang_tab.cpp" break; - case 547: /* initializer: LEFT_BRACE initializer_list COMMA RIGHT_BRACE */ -#line 3649 "MachineIndependent/glslang.y" + case 558: /* initializer: LEFT_BRACE initializer_list COMMA RIGHT_BRACE */ +#line 3702 "MachineIndependent/glslang.y" { const char* initFeature = "{ } style initializers"; parseContext.requireProfile((yyvsp[-3].lex).loc, ~EEsProfile, initFeature); parseContext.profileRequires((yyvsp[-3].lex).loc, ~EEsProfile, 420, E_GL_ARB_shading_language_420pack, initFeature); (yyval.interm.intermTypedNode) = (yyvsp[-2].interm.intermTypedNode); } -#line 10938 "MachineIndependent/glslang_tab.cpp" +#line 11138 "MachineIndependent/glslang_tab.cpp" break; - case 548: /* initializer: LEFT_BRACE RIGHT_BRACE */ -#line 3655 "MachineIndependent/glslang.y" + case 559: /* initializer: LEFT_BRACE RIGHT_BRACE */ +#line 3708 "MachineIndependent/glslang.y" { const char* initFeature = "empty { } initializer"; parseContext.profileRequires((yyvsp[-1].lex).loc, EEsProfile, 0, E_GL_EXT_null_initializer, initFeature); parseContext.profileRequires((yyvsp[-1].lex).loc, ~EEsProfile, 0, E_GL_EXT_null_initializer, initFeature); (yyval.interm.intermTypedNode) = parseContext.intermediate.makeAggregate((yyvsp[-1].lex).loc); } -#line 10949 "MachineIndependent/glslang_tab.cpp" +#line 11149 "MachineIndependent/glslang_tab.cpp" break; - case 549: /* initializer_list: initializer */ -#line 3666 "MachineIndependent/glslang.y" + case 560: /* initializer_list: initializer */ +#line 3717 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate(0, (yyvsp[0].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)->getLoc()); } -#line 10957 "MachineIndependent/glslang_tab.cpp" +#line 11157 "MachineIndependent/glslang_tab.cpp" break; - case 550: /* initializer_list: initializer_list COMMA initializer */ -#line 3669 "MachineIndependent/glslang.y" + case 561: /* initializer_list: initializer_list COMMA initializer */ +#line 3720 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.intermTypedNode)); } -#line 10965 "MachineIndependent/glslang_tab.cpp" +#line 11165 "MachineIndependent/glslang_tab.cpp" break; - case 551: /* declaration_statement: declaration */ -#line 3676 "MachineIndependent/glslang.y" + case 562: /* declaration_statement: declaration */ +#line 3726 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10971 "MachineIndependent/glslang_tab.cpp" +#line 11171 "MachineIndependent/glslang_tab.cpp" break; - case 552: /* statement: compound_statement */ -#line 3680 "MachineIndependent/glslang.y" + case 563: /* statement: compound_statement */ +#line 3730 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10977 "MachineIndependent/glslang_tab.cpp" +#line 11177 "MachineIndependent/glslang_tab.cpp" break; - case 553: /* statement: simple_statement */ -#line 3681 "MachineIndependent/glslang.y" + case 564: /* statement: simple_statement */ +#line 3731 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10983 "MachineIndependent/glslang_tab.cpp" +#line 11183 "MachineIndependent/glslang_tab.cpp" break; - case 554: /* simple_statement: declaration_statement */ -#line 3687 "MachineIndependent/glslang.y" + case 565: /* simple_statement: declaration_statement */ +#line 3737 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10989 "MachineIndependent/glslang_tab.cpp" +#line 11189 "MachineIndependent/glslang_tab.cpp" break; - case 555: /* simple_statement: expression_statement */ -#line 3688 "MachineIndependent/glslang.y" + case 566: /* simple_statement: expression_statement */ +#line 3738 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 10995 "MachineIndependent/glslang_tab.cpp" +#line 11195 "MachineIndependent/glslang_tab.cpp" break; - case 556: /* simple_statement: selection_statement */ -#line 3689 "MachineIndependent/glslang.y" + case 567: /* simple_statement: selection_statement */ +#line 3739 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11001 "MachineIndependent/glslang_tab.cpp" +#line 11201 "MachineIndependent/glslang_tab.cpp" break; - case 557: /* simple_statement: switch_statement */ -#line 3690 "MachineIndependent/glslang.y" + case 568: /* simple_statement: switch_statement */ +#line 3740 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11007 "MachineIndependent/glslang_tab.cpp" +#line 11207 "MachineIndependent/glslang_tab.cpp" break; - case 558: /* simple_statement: case_label */ -#line 3691 "MachineIndependent/glslang.y" + case 569: /* simple_statement: case_label */ +#line 3741 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11013 "MachineIndependent/glslang_tab.cpp" +#line 11213 "MachineIndependent/glslang_tab.cpp" break; - case 559: /* simple_statement: iteration_statement */ -#line 3692 "MachineIndependent/glslang.y" + case 570: /* simple_statement: iteration_statement */ +#line 3742 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11019 "MachineIndependent/glslang_tab.cpp" +#line 11219 "MachineIndependent/glslang_tab.cpp" break; - case 560: /* simple_statement: jump_statement */ -#line 3693 "MachineIndependent/glslang.y" + case 571: /* simple_statement: jump_statement */ +#line 3743 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11025 "MachineIndependent/glslang_tab.cpp" +#line 11225 "MachineIndependent/glslang_tab.cpp" break; - case 561: /* simple_statement: demote_statement */ -#line 3695 "MachineIndependent/glslang.y" + case 572: /* simple_statement: demote_statement */ +#line 3744 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11031 "MachineIndependent/glslang_tab.cpp" +#line 11231 "MachineIndependent/glslang_tab.cpp" break; - case 562: /* demote_statement: DEMOTE SEMICOLON */ -#line 3701 "MachineIndependent/glslang.y" + case 573: /* demote_statement: DEMOTE SEMICOLON */ +#line 3748 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "demote"); parseContext.requireExtensions((yyvsp[-1].lex).loc, 1, &E_GL_EXT_demote_to_helper_invocation, "demote"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDemote, (yyvsp[-1].lex).loc); } -#line 11041 "MachineIndependent/glslang_tab.cpp" +#line 11241 "MachineIndependent/glslang_tab.cpp" break; - case 563: /* compound_statement: LEFT_BRACE RIGHT_BRACE */ -#line 3710 "MachineIndependent/glslang.y" + case 574: /* compound_statement: LEFT_BRACE RIGHT_BRACE */ +#line 3756 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = 0; } -#line 11047 "MachineIndependent/glslang_tab.cpp" +#line 11247 "MachineIndependent/glslang_tab.cpp" break; - case 564: /* $@5: %empty */ -#line 3711 "MachineIndependent/glslang.y" + case 575: /* $@5: %empty */ +#line 3757 "MachineIndependent/glslang.y" { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; } -#line 11056 "MachineIndependent/glslang_tab.cpp" +#line 11256 "MachineIndependent/glslang_tab.cpp" break; - case 565: /* $@6: %empty */ -#line 3715 "MachineIndependent/glslang.y" + case 576: /* $@6: %empty */ +#line 3761 "MachineIndependent/glslang.y" { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); --parseContext.statementNestingLevel; } -#line 11065 "MachineIndependent/glslang_tab.cpp" +#line 11265 "MachineIndependent/glslang_tab.cpp" break; - case 566: /* compound_statement: LEFT_BRACE $@5 statement_list $@6 RIGHT_BRACE */ -#line 3719 "MachineIndependent/glslang.y" + case 577: /* compound_statement: LEFT_BRACE $@5 statement_list $@6 RIGHT_BRACE */ +#line 3765 "MachineIndependent/glslang.y" { if ((yyvsp[-2].interm.intermNode) && (yyvsp[-2].interm.intermNode)->getAsAggregate()) - (yyvsp[-2].interm.intermNode)->getAsAggregate()->setOperator(EOpSequence); + (yyvsp[-2].interm.intermNode)->getAsAggregate()->setOperator(parseContext.intermediate.getDebugInfo() ? EOpScope : EOpSequence); (yyval.interm.intermNode) = (yyvsp[-2].interm.intermNode); } -#line 11075 "MachineIndependent/glslang_tab.cpp" +#line 11275 "MachineIndependent/glslang_tab.cpp" break; - case 567: /* statement_no_new_scope: compound_statement_no_new_scope */ -#line 3727 "MachineIndependent/glslang.y" + case 578: /* statement_no_new_scope: compound_statement_no_new_scope */ +#line 3773 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11081 "MachineIndependent/glslang_tab.cpp" +#line 11281 "MachineIndependent/glslang_tab.cpp" break; - case 568: /* statement_no_new_scope: simple_statement */ -#line 3728 "MachineIndependent/glslang.y" + case 579: /* statement_no_new_scope: simple_statement */ +#line 3774 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11087 "MachineIndependent/glslang_tab.cpp" +#line 11287 "MachineIndependent/glslang_tab.cpp" break; - case 569: /* $@7: %empty */ -#line 3732 "MachineIndependent/glslang.y" + case 580: /* $@7: %empty */ +#line 3778 "MachineIndependent/glslang.y" { ++parseContext.controlFlowNestingLevel; } -#line 11095 "MachineIndependent/glslang_tab.cpp" +#line 11295 "MachineIndependent/glslang_tab.cpp" break; - case 570: /* statement_scoped: $@7 compound_statement */ -#line 3735 "MachineIndependent/glslang.y" + case 581: /* statement_scoped: $@7 compound_statement */ +#line 3781 "MachineIndependent/glslang.y" { --parseContext.controlFlowNestingLevel; (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11104 "MachineIndependent/glslang_tab.cpp" +#line 11304 "MachineIndependent/glslang_tab.cpp" break; - case 571: /* $@8: %empty */ -#line 3739 "MachineIndependent/glslang.y" + case 582: /* $@8: %empty */ +#line 3785 "MachineIndependent/glslang.y" { parseContext.symbolTable.push(); ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 11114 "MachineIndependent/glslang_tab.cpp" +#line 11314 "MachineIndependent/glslang_tab.cpp" break; - case 572: /* statement_scoped: $@8 simple_statement */ -#line 3744 "MachineIndependent/glslang.y" + case 583: /* statement_scoped: $@8 simple_statement */ +#line 3790 "MachineIndependent/glslang.y" { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11125 "MachineIndependent/glslang_tab.cpp" +#line 11325 "MachineIndependent/glslang_tab.cpp" break; - case 573: /* compound_statement_no_new_scope: LEFT_BRACE RIGHT_BRACE */ -#line 3753 "MachineIndependent/glslang.y" + case 584: /* compound_statement_no_new_scope: LEFT_BRACE RIGHT_BRACE */ +#line 3799 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = 0; } -#line 11133 "MachineIndependent/glslang_tab.cpp" +#line 11333 "MachineIndependent/glslang_tab.cpp" break; - case 574: /* compound_statement_no_new_scope: LEFT_BRACE statement_list RIGHT_BRACE */ -#line 3756 "MachineIndependent/glslang.y" + case 585: /* compound_statement_no_new_scope: LEFT_BRACE statement_list RIGHT_BRACE */ +#line 3802 "MachineIndependent/glslang.y" { if ((yyvsp[-1].interm.intermNode) && (yyvsp[-1].interm.intermNode)->getAsAggregate()) (yyvsp[-1].interm.intermNode)->getAsAggregate()->setOperator(EOpSequence); (yyval.interm.intermNode) = (yyvsp[-1].interm.intermNode); } -#line 11143 "MachineIndependent/glslang_tab.cpp" +#line 11343 "MachineIndependent/glslang_tab.cpp" break; - case 575: /* statement_list: statement */ -#line 3764 "MachineIndependent/glslang.y" + case 586: /* statement_list: statement */ +#line 3810 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase || @@ -11152,11 +11352,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.intermNode) = 0; // start a fresh subsequence for what's after this case } } -#line 11156 "MachineIndependent/glslang_tab.cpp" +#line 11356 "MachineIndependent/glslang_tab.cpp" break; - case 576: /* statement_list: statement_list statement */ -#line 3772 "MachineIndependent/glslang.y" + case 587: /* statement_list: statement_list statement */ +#line 3818 "MachineIndependent/glslang.y" { if ((yyvsp[0].interm.intermNode) && (yyvsp[0].interm.intermNode)->getAsBranchNode() && ((yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpCase || (yyvsp[0].interm.intermNode)->getAsBranchNode()->getFlowOp() == EOpDefault)) { @@ -11165,77 +11365,77 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } else (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode)); } -#line 11169 "MachineIndependent/glslang_tab.cpp" +#line 11369 "MachineIndependent/glslang_tab.cpp" break; - case 577: /* expression_statement: SEMICOLON */ -#line 3783 "MachineIndependent/glslang.y" + case 588: /* expression_statement: SEMICOLON */ +#line 3829 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = 0; } -#line 11175 "MachineIndependent/glslang_tab.cpp" +#line 11375 "MachineIndependent/glslang_tab.cpp" break; - case 578: /* expression_statement: expression SEMICOLON */ -#line 3784 "MachineIndependent/glslang.y" + case 589: /* expression_statement: expression SEMICOLON */ +#line 3830 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = static_cast((yyvsp[-1].interm.intermTypedNode)); } -#line 11181 "MachineIndependent/glslang_tab.cpp" +#line 11381 "MachineIndependent/glslang_tab.cpp" break; - case 579: /* selection_statement: selection_statement_nonattributed */ -#line 3788 "MachineIndependent/glslang.y" + case 590: /* selection_statement: selection_statement_nonattributed */ +#line 3834 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11189 "MachineIndependent/glslang_tab.cpp" +#line 11389 "MachineIndependent/glslang_tab.cpp" break; - case 580: /* selection_statement: attribute selection_statement_nonattributed */ -#line 3792 "MachineIndependent/glslang.y" + case 591: /* selection_statement: attribute selection_statement_nonattributed */ +#line 3837 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[0].interm.intermNode)->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); parseContext.handleSelectionAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11199 "MachineIndependent/glslang_tab.cpp" +#line 11399 "MachineIndependent/glslang_tab.cpp" break; - case 581: /* selection_statement_nonattributed: IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement */ -#line 3800 "MachineIndependent/glslang.y" + case 592: /* selection_statement_nonattributed: IF LEFT_PAREN expression RIGHT_PAREN selection_rest_statement */ +#line 3844 "MachineIndependent/glslang.y" { parseContext.boolCheck((yyvsp[-4].lex).loc, (yyvsp[-2].interm.intermTypedNode)); (yyval.interm.intermNode) = parseContext.intermediate.addSelection((yyvsp[-2].interm.intermTypedNode), (yyvsp[0].interm.nodePair), (yyvsp[-4].lex).loc); } -#line 11208 "MachineIndependent/glslang_tab.cpp" +#line 11408 "MachineIndependent/glslang_tab.cpp" break; - case 582: /* selection_rest_statement: statement_scoped ELSE statement_scoped */ -#line 3807 "MachineIndependent/glslang.y" + case 593: /* selection_rest_statement: statement_scoped ELSE statement_scoped */ +#line 3851 "MachineIndependent/glslang.y" { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermNode); (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermNode); } -#line 11217 "MachineIndependent/glslang_tab.cpp" +#line 11417 "MachineIndependent/glslang_tab.cpp" break; - case 583: /* selection_rest_statement: statement_scoped */ -#line 3811 "MachineIndependent/glslang.y" + case 594: /* selection_rest_statement: statement_scoped */ +#line 3855 "MachineIndependent/glslang.y" { (yyval.interm.nodePair).node1 = (yyvsp[0].interm.intermNode); (yyval.interm.nodePair).node2 = 0; } -#line 11226 "MachineIndependent/glslang_tab.cpp" +#line 11426 "MachineIndependent/glslang_tab.cpp" break; - case 584: /* condition: expression */ -#line 3819 "MachineIndependent/glslang.y" + case 595: /* condition: expression */ +#line 3863 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); parseContext.boolCheck((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode)); } -#line 11235 "MachineIndependent/glslang_tab.cpp" +#line 11435 "MachineIndependent/glslang_tab.cpp" break; - case 585: /* condition: fully_specified_type IDENTIFIER EQUAL initializer */ -#line 3823 "MachineIndependent/glslang.y" + case 596: /* condition: fully_specified_type IDENTIFIER EQUAL initializer */ +#line 3867 "MachineIndependent/glslang.y" { parseContext.boolCheck((yyvsp[-2].lex).loc, (yyvsp[-3].interm.type)); @@ -11246,29 +11446,29 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); else (yyval.interm.intermTypedNode) = 0; } -#line 11250 "MachineIndependent/glslang_tab.cpp" +#line 11450 "MachineIndependent/glslang_tab.cpp" break; - case 586: /* switch_statement: switch_statement_nonattributed */ -#line 3836 "MachineIndependent/glslang.y" + case 597: /* switch_statement: switch_statement_nonattributed */ +#line 3880 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11258 "MachineIndependent/glslang_tab.cpp" +#line 11458 "MachineIndependent/glslang_tab.cpp" break; - case 587: /* switch_statement: attribute switch_statement_nonattributed */ -#line 3840 "MachineIndependent/glslang.y" + case 598: /* switch_statement: attribute switch_statement_nonattributed */ +#line 3883 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[0].interm.intermNode)->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); parseContext.handleSwitchAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11268 "MachineIndependent/glslang_tab.cpp" +#line 11468 "MachineIndependent/glslang_tab.cpp" break; - case 588: /* $@9: %empty */ -#line 3848 "MachineIndependent/glslang.y" + case 599: /* $@9: %empty */ +#line 3890 "MachineIndependent/glslang.y" { // start new switch sequence on the switch stack ++parseContext.controlFlowNestingLevel; @@ -11277,11 +11477,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.switchLevel.push_back(parseContext.statementNestingLevel); parseContext.symbolTable.push(); } -#line 11281 "MachineIndependent/glslang_tab.cpp" +#line 11481 "MachineIndependent/glslang_tab.cpp" break; - case 589: /* switch_statement_nonattributed: SWITCH LEFT_PAREN expression RIGHT_PAREN $@9 LEFT_BRACE switch_statement_list RIGHT_BRACE */ -#line 3856 "MachineIndependent/glslang.y" + case 600: /* switch_statement_nonattributed: SWITCH LEFT_PAREN expression RIGHT_PAREN $@9 LEFT_BRACE switch_statement_list RIGHT_BRACE */ +#line 3898 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.addSwitch((yyvsp[-7].lex).loc, (yyvsp[-5].interm.intermTypedNode), (yyvsp[-1].interm.intermNode) ? (yyvsp[-1].interm.intermNode)->getAsAggregate() : 0); delete parseContext.switchSequenceStack.back(); @@ -11291,27 +11491,27 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 11295 "MachineIndependent/glslang_tab.cpp" +#line 11495 "MachineIndependent/glslang_tab.cpp" break; - case 590: /* switch_statement_list: %empty */ -#line 3868 "MachineIndependent/glslang.y" + case 601: /* switch_statement_list: %empty */ +#line 3910 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = 0; } -#line 11303 "MachineIndependent/glslang_tab.cpp" +#line 11503 "MachineIndependent/glslang_tab.cpp" break; - case 591: /* switch_statement_list: statement_list */ -#line 3871 "MachineIndependent/glslang.y" + case 602: /* switch_statement_list: statement_list */ +#line 3913 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11311 "MachineIndependent/glslang_tab.cpp" +#line 11511 "MachineIndependent/glslang_tab.cpp" break; - case 592: /* case_label: CASE expression COLON */ -#line 3877 "MachineIndependent/glslang.y" + case 603: /* case_label: CASE expression COLON */ +#line 3919 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) @@ -11324,11 +11524,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpCase, (yyvsp[-1].interm.intermTypedNode), (yyvsp[-2].lex).loc); } } -#line 11328 "MachineIndependent/glslang_tab.cpp" +#line 11528 "MachineIndependent/glslang_tab.cpp" break; - case 593: /* case_label: DEFAULT COLON */ -#line 3889 "MachineIndependent/glslang.y" + case 604: /* case_label: DEFAULT COLON */ +#line 3931 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = 0; if (parseContext.switchLevel.size() == 0) @@ -11338,29 +11538,29 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); else (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpDefault, (yyvsp[-1].lex).loc); } -#line 11342 "MachineIndependent/glslang_tab.cpp" +#line 11542 "MachineIndependent/glslang_tab.cpp" break; - case 594: /* iteration_statement: iteration_statement_nonattributed */ -#line 3901 "MachineIndependent/glslang.y" + case 605: /* iteration_statement: iteration_statement_nonattributed */ +#line 3943 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11350 "MachineIndependent/glslang_tab.cpp" +#line 11550 "MachineIndependent/glslang_tab.cpp" break; - case 595: /* iteration_statement: attribute iteration_statement_nonattributed */ -#line 3905 "MachineIndependent/glslang.y" + case 606: /* iteration_statement: attribute iteration_statement_nonattributed */ +#line 3946 "MachineIndependent/glslang.y" { parseContext.requireExtensions((yyvsp[0].interm.intermNode)->getLoc(), 1, &E_GL_EXT_control_flow_attributes, "attribute"); parseContext.handleLoopAttributes(*(yyvsp[-1].interm.attributes), (yyvsp[0].interm.intermNode)); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11360 "MachineIndependent/glslang_tab.cpp" +#line 11560 "MachineIndependent/glslang_tab.cpp" break; - case 596: /* $@10: %empty */ -#line 3913 "MachineIndependent/glslang.y" + case 607: /* $@10: %empty */ +#line 3953 "MachineIndependent/glslang.y" { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-1].lex).loc, "while loops not available", "limitation", ""); @@ -11369,11 +11569,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 11373 "MachineIndependent/glslang_tab.cpp" +#line 11573 "MachineIndependent/glslang_tab.cpp" break; - case 597: /* iteration_statement_nonattributed: WHILE LEFT_PAREN $@10 condition RIGHT_PAREN statement_no_new_scope */ -#line 3921 "MachineIndependent/glslang.y" + case 608: /* iteration_statement_nonattributed: WHILE LEFT_PAREN $@10 condition RIGHT_PAREN statement_no_new_scope */ +#line 3961 "MachineIndependent/glslang.y" { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); (yyval.interm.intermNode) = parseContext.intermediate.addLoop((yyvsp[0].interm.intermNode), (yyvsp[-2].interm.intermTypedNode), 0, true, (yyvsp[-5].lex).loc); @@ -11381,22 +11581,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 11385 "MachineIndependent/glslang_tab.cpp" +#line 11585 "MachineIndependent/glslang_tab.cpp" break; - case 598: /* $@11: %empty */ -#line 3928 "MachineIndependent/glslang.y" + case 609: /* $@11: %empty */ +#line 3968 "MachineIndependent/glslang.y" { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 11396 "MachineIndependent/glslang_tab.cpp" +#line 11596 "MachineIndependent/glslang_tab.cpp" break; - case 599: /* iteration_statement_nonattributed: DO $@11 statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON */ -#line 3934 "MachineIndependent/glslang.y" + case 610: /* iteration_statement_nonattributed: DO $@11 statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON */ +#line 3974 "MachineIndependent/glslang.y" { if (! parseContext.limits.whileLoops) parseContext.error((yyvsp[-7].lex).loc, "do-while loops not available", "limitation", ""); @@ -11409,22 +11609,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 11413 "MachineIndependent/glslang_tab.cpp" +#line 11613 "MachineIndependent/glslang_tab.cpp" break; - case 600: /* $@12: %empty */ -#line 3946 "MachineIndependent/glslang.y" + case 611: /* $@12: %empty */ +#line 3986 "MachineIndependent/glslang.y" { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; ++parseContext.statementNestingLevel; ++parseContext.controlFlowNestingLevel; } -#line 11424 "MachineIndependent/glslang_tab.cpp" +#line 11624 "MachineIndependent/glslang_tab.cpp" break; - case 601: /* iteration_statement_nonattributed: FOR LEFT_PAREN $@12 for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope */ -#line 3952 "MachineIndependent/glslang.y" + case 612: /* iteration_statement_nonattributed: FOR LEFT_PAREN $@12 for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope */ +#line 3992 "MachineIndependent/glslang.y" { parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[-3].interm.intermNode), (yyvsp[-5].lex).loc); @@ -11437,81 +11637,81 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); --parseContext.statementNestingLevel; --parseContext.controlFlowNestingLevel; } -#line 11441 "MachineIndependent/glslang_tab.cpp" +#line 11641 "MachineIndependent/glslang_tab.cpp" break; - case 602: /* for_init_statement: expression_statement */ -#line 3967 "MachineIndependent/glslang.y" + case 613: /* for_init_statement: expression_statement */ +#line 4007 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11449 "MachineIndependent/glslang_tab.cpp" +#line 11649 "MachineIndependent/glslang_tab.cpp" break; - case 603: /* for_init_statement: declaration_statement */ -#line 3970 "MachineIndependent/glslang.y" + case 614: /* for_init_statement: declaration_statement */ +#line 4010 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11457 "MachineIndependent/glslang_tab.cpp" +#line 11657 "MachineIndependent/glslang_tab.cpp" break; - case 604: /* conditionopt: condition */ -#line 3976 "MachineIndependent/glslang.y" + case 615: /* conditionopt: condition */ +#line 4016 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = (yyvsp[0].interm.intermTypedNode); } -#line 11465 "MachineIndependent/glslang_tab.cpp" +#line 11665 "MachineIndependent/glslang_tab.cpp" break; - case 605: /* conditionopt: %empty */ -#line 3979 "MachineIndependent/glslang.y" + case 616: /* conditionopt: %empty */ +#line 4019 "MachineIndependent/glslang.y" { (yyval.interm.intermTypedNode) = 0; } -#line 11473 "MachineIndependent/glslang_tab.cpp" +#line 11673 "MachineIndependent/glslang_tab.cpp" break; - case 606: /* for_rest_statement: conditionopt SEMICOLON */ -#line 3985 "MachineIndependent/glslang.y" + case 617: /* for_rest_statement: conditionopt SEMICOLON */ +#line 4025 "MachineIndependent/glslang.y" { (yyval.interm.nodePair).node1 = (yyvsp[-1].interm.intermTypedNode); (yyval.interm.nodePair).node2 = 0; } -#line 11482 "MachineIndependent/glslang_tab.cpp" +#line 11682 "MachineIndependent/glslang_tab.cpp" break; - case 607: /* for_rest_statement: conditionopt SEMICOLON expression */ -#line 3989 "MachineIndependent/glslang.y" + case 618: /* for_rest_statement: conditionopt SEMICOLON expression */ +#line 4029 "MachineIndependent/glslang.y" { (yyval.interm.nodePair).node1 = (yyvsp[-2].interm.intermTypedNode); (yyval.interm.nodePair).node2 = (yyvsp[0].interm.intermTypedNode); } -#line 11491 "MachineIndependent/glslang_tab.cpp" +#line 11691 "MachineIndependent/glslang_tab.cpp" break; - case 608: /* jump_statement: CONTINUE SEMICOLON */ -#line 3996 "MachineIndependent/glslang.y" + case 619: /* jump_statement: CONTINUE SEMICOLON */ +#line 4036 "MachineIndependent/glslang.y" { if (parseContext.loopNestingLevel <= 0) parseContext.error((yyvsp[-1].lex).loc, "continue statement only allowed in loops", "", ""); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpContinue, (yyvsp[-1].lex).loc); } -#line 11501 "MachineIndependent/glslang_tab.cpp" +#line 11701 "MachineIndependent/glslang_tab.cpp" break; - case 609: /* jump_statement: BREAK SEMICOLON */ -#line 4001 "MachineIndependent/glslang.y" + case 620: /* jump_statement: BREAK SEMICOLON */ +#line 4041 "MachineIndependent/glslang.y" { if (parseContext.loopNestingLevel + parseContext.switchSequenceStack.size() <= 0) parseContext.error((yyvsp[-1].lex).loc, "break statement only allowed in switch and loops", "", ""); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpBreak, (yyvsp[-1].lex).loc); } -#line 11511 "MachineIndependent/glslang_tab.cpp" +#line 11711 "MachineIndependent/glslang_tab.cpp" break; - case 610: /* jump_statement: RETURN SEMICOLON */ -#line 4006 "MachineIndependent/glslang.y" + case 621: /* jump_statement: RETURN SEMICOLON */ +#line 4046 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpReturn, (yyvsp[-1].lex).loc); if (parseContext.currentFunctionType->getBasicType() != EbtVoid) @@ -11519,101 +11719,101 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); if (parseContext.inMain) parseContext.postEntryPointReturn = true; } -#line 11523 "MachineIndependent/glslang_tab.cpp" +#line 11723 "MachineIndependent/glslang_tab.cpp" break; - case 611: /* jump_statement: RETURN expression SEMICOLON */ -#line 4013 "MachineIndependent/glslang.y" + case 622: /* jump_statement: RETURN expression SEMICOLON */ +#line 4053 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.handleReturnValue((yyvsp[-2].lex).loc, (yyvsp[-1].interm.intermTypedNode)); } -#line 11531 "MachineIndependent/glslang_tab.cpp" +#line 11731 "MachineIndependent/glslang_tab.cpp" break; - case 612: /* jump_statement: DISCARD SEMICOLON */ -#line 4016 "MachineIndependent/glslang.y" + case 623: /* jump_statement: DISCARD SEMICOLON */ +#line 4056 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "discard"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpKill, (yyvsp[-1].lex).loc); } -#line 11540 "MachineIndependent/glslang_tab.cpp" +#line 11740 "MachineIndependent/glslang_tab.cpp" break; - case 613: /* jump_statement: TERMINATE_INVOCATION SEMICOLON */ -#line 4020 "MachineIndependent/glslang.y" + case 624: /* jump_statement: TERMINATE_INVOCATION SEMICOLON */ +#line 4060 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangFragment, "terminateInvocation"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpTerminateInvocation, (yyvsp[-1].lex).loc); } -#line 11549 "MachineIndependent/glslang_tab.cpp" +#line 11749 "MachineIndependent/glslang_tab.cpp" break; - case 614: /* jump_statement: TERMINATE_RAY SEMICOLON */ -#line 4025 "MachineIndependent/glslang.y" + case 625: /* jump_statement: TERMINATE_RAY SEMICOLON */ +#line 4064 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangAnyHit, "terminateRayEXT"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpTerminateRayKHR, (yyvsp[-1].lex).loc); } -#line 11558 "MachineIndependent/glslang_tab.cpp" +#line 11758 "MachineIndependent/glslang_tab.cpp" break; - case 615: /* jump_statement: IGNORE_INTERSECTION SEMICOLON */ -#line 4029 "MachineIndependent/glslang.y" + case 626: /* jump_statement: IGNORE_INTERSECTION SEMICOLON */ +#line 4068 "MachineIndependent/glslang.y" { parseContext.requireStage((yyvsp[-1].lex).loc, EShLangAnyHit, "ignoreIntersectionEXT"); (yyval.interm.intermNode) = parseContext.intermediate.addBranch(EOpIgnoreIntersectionKHR, (yyvsp[-1].lex).loc); } -#line 11567 "MachineIndependent/glslang_tab.cpp" +#line 11767 "MachineIndependent/glslang_tab.cpp" break; - case 616: /* translation_unit: external_declaration */ -#line 4039 "MachineIndependent/glslang.y" + case 627: /* translation_unit: external_declaration */ +#line 4077 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); parseContext.intermediate.setTreeRoot((yyval.interm.intermNode)); } -#line 11576 "MachineIndependent/glslang_tab.cpp" +#line 11776 "MachineIndependent/glslang_tab.cpp" break; - case 617: /* translation_unit: translation_unit external_declaration */ -#line 4043 "MachineIndependent/glslang.y" + case 628: /* translation_unit: translation_unit external_declaration */ +#line 4081 "MachineIndependent/glslang.y" { if ((yyvsp[0].interm.intermNode) != nullptr) { (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-1].interm.intermNode), (yyvsp[0].interm.intermNode)); parseContext.intermediate.setTreeRoot((yyval.interm.intermNode)); } } -#line 11587 "MachineIndependent/glslang_tab.cpp" +#line 11787 "MachineIndependent/glslang_tab.cpp" break; - case 618: /* external_declaration: function_definition */ -#line 4052 "MachineIndependent/glslang.y" + case 629: /* external_declaration: function_definition */ +#line 4090 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11595 "MachineIndependent/glslang_tab.cpp" +#line 11795 "MachineIndependent/glslang_tab.cpp" break; - case 619: /* external_declaration: declaration */ -#line 4055 "MachineIndependent/glslang.y" + case 630: /* external_declaration: declaration */ +#line 4093 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } -#line 11603 "MachineIndependent/glslang_tab.cpp" +#line 11803 "MachineIndependent/glslang_tab.cpp" break; - case 620: /* external_declaration: SEMICOLON */ -#line 4059 "MachineIndependent/glslang.y" + case 631: /* external_declaration: SEMICOLON */ +#line 4096 "MachineIndependent/glslang.y" { parseContext.requireProfile((yyvsp[0].lex).loc, ~EEsProfile, "extraneous semicolon"); parseContext.profileRequires((yyvsp[0].lex).loc, ~EEsProfile, 460, nullptr, "extraneous semicolon"); (yyval.interm.intermNode) = nullptr; } -#line 11613 "MachineIndependent/glslang_tab.cpp" +#line 11813 "MachineIndependent/glslang_tab.cpp" break; - case 621: /* $@13: %empty */ -#line 4068 "MachineIndependent/glslang.y" + case 632: /* $@13: %empty */ +#line 4104 "MachineIndependent/glslang.y" { (yyvsp[0].interm).function = parseContext.handleFunctionDeclarator((yyvsp[0].interm).loc, *(yyvsp[0].interm).function, false /* not prototype */); (yyvsp[0].interm).intermNode = parseContext.handleFunctionDefinition((yyvsp[0].interm).loc, *(yyvsp[0].interm).function); @@ -11626,17 +11826,18 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); ++parseContext.statementNestingLevel; } } -#line 11630 "MachineIndependent/glslang_tab.cpp" +#line 11830 "MachineIndependent/glslang_tab.cpp" break; - case 622: /* function_definition: function_prototype $@13 compound_statement_no_new_scope */ -#line 4080 "MachineIndependent/glslang.y" + case 633: /* function_definition: function_prototype $@13 compound_statement_no_new_scope */ +#line 4116 "MachineIndependent/glslang.y" { // May be best done as post process phase on intermediate code if (parseContext.currentFunctionType->getBasicType() != EbtVoid && ! parseContext.functionReturnsValue) parseContext.error((yyvsp[-2].interm).loc, "function does not return a value:", "", (yyvsp[-2].interm).function->getName().c_str()); parseContext.symbolTable.pop(&parseContext.defaultPrecision[0]); (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm).intermNode, (yyvsp[0].interm.intermNode)); + (yyval.interm.intermNode)->getAsAggregate()->setLinkType((yyvsp[-2].interm).function->getLinkType()); parseContext.intermediate.setAggregateOperator((yyval.interm.intermNode), EOpFunction, (yyvsp[-2].interm).function->getType(), (yyvsp[-2].interm).loc); (yyval.interm.intermNode)->getAsAggregate()->setName((yyvsp[-2].interm).function->getMangledName().c_str()); @@ -11657,228 +11858,228 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); --parseContext.statementNestingLevel; } } -#line 11661 "MachineIndependent/glslang_tab.cpp" +#line 11862 "MachineIndependent/glslang_tab.cpp" break; - case 623: /* attribute: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET */ -#line 4110 "MachineIndependent/glslang.y" + case 634: /* attribute: LEFT_BRACKET LEFT_BRACKET attribute_list RIGHT_BRACKET RIGHT_BRACKET */ +#line 4146 "MachineIndependent/glslang.y" { (yyval.interm.attributes) = (yyvsp[-2].interm.attributes); } -#line 11669 "MachineIndependent/glslang_tab.cpp" +#line 11870 "MachineIndependent/glslang_tab.cpp" break; - case 624: /* attribute_list: single_attribute */ -#line 4115 "MachineIndependent/glslang.y" + case 635: /* attribute_list: single_attribute */ +#line 4151 "MachineIndependent/glslang.y" { (yyval.interm.attributes) = (yyvsp[0].interm.attributes); } -#line 11677 "MachineIndependent/glslang_tab.cpp" +#line 11878 "MachineIndependent/glslang_tab.cpp" break; - case 625: /* attribute_list: attribute_list COMMA single_attribute */ -#line 4118 "MachineIndependent/glslang.y" + case 636: /* attribute_list: attribute_list COMMA single_attribute */ +#line 4154 "MachineIndependent/glslang.y" { (yyval.interm.attributes) = parseContext.mergeAttributes((yyvsp[-2].interm.attributes), (yyvsp[0].interm.attributes)); } -#line 11685 "MachineIndependent/glslang_tab.cpp" +#line 11886 "MachineIndependent/glslang_tab.cpp" break; - case 626: /* single_attribute: IDENTIFIER */ -#line 4123 "MachineIndependent/glslang.y" + case 637: /* single_attribute: IDENTIFIER */ +#line 4159 "MachineIndependent/glslang.y" { (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[0].lex).string); } -#line 11693 "MachineIndependent/glslang_tab.cpp" +#line 11894 "MachineIndependent/glslang_tab.cpp" break; - case 627: /* single_attribute: IDENTIFIER LEFT_PAREN constant_expression RIGHT_PAREN */ -#line 4126 "MachineIndependent/glslang.y" + case 638: /* single_attribute: IDENTIFIER LEFT_PAREN constant_expression RIGHT_PAREN */ +#line 4162 "MachineIndependent/glslang.y" { (yyval.interm.attributes) = parseContext.makeAttributes(*(yyvsp[-3].lex).string, (yyvsp[-1].interm.intermTypedNode)); } -#line 11701 "MachineIndependent/glslang_tab.cpp" +#line 11902 "MachineIndependent/glslang_tab.cpp" break; - case 628: /* spirv_requirements_list: spirv_requirements_parameter */ -#line 4133 "MachineIndependent/glslang.y" + case 639: /* spirv_requirements_list: spirv_requirements_parameter */ +#line 4167 "MachineIndependent/glslang.y" { (yyval.interm.spirvReq) = (yyvsp[0].interm.spirvReq); } -#line 11709 "MachineIndependent/glslang_tab.cpp" +#line 11910 "MachineIndependent/glslang_tab.cpp" break; - case 629: /* spirv_requirements_list: spirv_requirements_list COMMA spirv_requirements_parameter */ -#line 4136 "MachineIndependent/glslang.y" + case 640: /* spirv_requirements_list: spirv_requirements_list COMMA spirv_requirements_parameter */ +#line 4170 "MachineIndependent/glslang.y" { (yyval.interm.spirvReq) = parseContext.mergeSpirvRequirements((yyvsp[-1].lex).loc, (yyvsp[-2].interm.spirvReq), (yyvsp[0].interm.spirvReq)); } -#line 11717 "MachineIndependent/glslang_tab.cpp" +#line 11918 "MachineIndependent/glslang_tab.cpp" break; - case 630: /* spirv_requirements_parameter: IDENTIFIER EQUAL LEFT_BRACKET spirv_extension_list RIGHT_BRACKET */ -#line 4141 "MachineIndependent/glslang.y" + case 641: /* spirv_requirements_parameter: IDENTIFIER EQUAL LEFT_BRACKET spirv_extension_list RIGHT_BRACKET */ +#line 4175 "MachineIndependent/glslang.y" { (yyval.interm.spirvReq) = parseContext.makeSpirvRequirement((yyvsp[-3].lex).loc, *(yyvsp[-4].lex).string, (yyvsp[-1].interm.intermNode)->getAsAggregate(), nullptr); } -#line 11725 "MachineIndependent/glslang_tab.cpp" +#line 11926 "MachineIndependent/glslang_tab.cpp" break; - case 631: /* spirv_requirements_parameter: IDENTIFIER EQUAL LEFT_BRACKET spirv_capability_list RIGHT_BRACKET */ -#line 4144 "MachineIndependent/glslang.y" + case 642: /* spirv_requirements_parameter: IDENTIFIER EQUAL LEFT_BRACKET spirv_capability_list RIGHT_BRACKET */ +#line 4178 "MachineIndependent/glslang.y" { (yyval.interm.spirvReq) = parseContext.makeSpirvRequirement((yyvsp[-3].lex).loc, *(yyvsp[-4].lex).string, nullptr, (yyvsp[-1].interm.intermNode)->getAsAggregate()); } -#line 11733 "MachineIndependent/glslang_tab.cpp" +#line 11934 "MachineIndependent/glslang_tab.cpp" break; - case 632: /* spirv_extension_list: STRING_LITERAL */ -#line 4149 "MachineIndependent/glslang.y" + case 643: /* spirv_extension_list: STRING_LITERAL */ +#line 4183 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true)); } -#line 11741 "MachineIndependent/glslang_tab.cpp" +#line 11942 "MachineIndependent/glslang_tab.cpp" break; - case 633: /* spirv_extension_list: spirv_extension_list COMMA STRING_LITERAL */ -#line 4152 "MachineIndependent/glslang.y" + case 644: /* spirv_extension_list: spirv_extension_list COMMA STRING_LITERAL */ +#line 4186 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true)); } -#line 11749 "MachineIndependent/glslang_tab.cpp" +#line 11950 "MachineIndependent/glslang_tab.cpp" break; - case 634: /* spirv_capability_list: INTCONSTANT */ -#line 4157 "MachineIndependent/glslang.y" + case 645: /* spirv_capability_list: INTCONSTANT */ +#line 4191 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate(parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true)); } -#line 11757 "MachineIndependent/glslang_tab.cpp" +#line 11958 "MachineIndependent/glslang_tab.cpp" break; - case 635: /* spirv_capability_list: spirv_capability_list COMMA INTCONSTANT */ -#line 4160 "MachineIndependent/glslang.y" + case 646: /* spirv_capability_list: spirv_capability_list COMMA INTCONSTANT */ +#line 4194 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true)); } -#line 11765 "MachineIndependent/glslang_tab.cpp" +#line 11966 "MachineIndependent/glslang_tab.cpp" break; - case 636: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT RIGHT_PAREN */ -#line 4165 "MachineIndependent/glslang.y" + case 647: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT RIGHT_PAREN */ +#line 4199 "MachineIndependent/glslang.y" { parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-1].lex).i); (yyval.interm.intermNode) = 0; } -#line 11774 "MachineIndependent/glslang_tab.cpp" +#line 11975 "MachineIndependent/glslang_tab.cpp" break; - case 637: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */ -#line 4169 "MachineIndependent/glslang.y" + case 648: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */ +#line 4203 "MachineIndependent/glslang.y" { parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq)); parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-1].lex).i); (yyval.interm.intermNode) = 0; } -#line 11784 "MachineIndependent/glslang_tab.cpp" +#line 11985 "MachineIndependent/glslang_tab.cpp" break; - case 638: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN */ -#line 4174 "MachineIndependent/glslang.y" + case 649: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN */ +#line 4208 "MachineIndependent/glslang.y" { parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); (yyval.interm.intermNode) = 0; } -#line 11793 "MachineIndependent/glslang_tab.cpp" +#line 11994 "MachineIndependent/glslang_tab.cpp" break; - case 639: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN */ -#line 4178 "MachineIndependent/glslang.y" + case 650: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_parameter_list RIGHT_PAREN */ +#line 4212 "MachineIndependent/glslang.y" { parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq)); parseContext.intermediate.insertSpirvExecutionMode((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); (yyval.interm.intermNode) = 0; } -#line 11803 "MachineIndependent/glslang_tab.cpp" +#line 12004 "MachineIndependent/glslang_tab.cpp" break; - case 640: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE_ID LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN */ -#line 4183 "MachineIndependent/glslang.y" + case 651: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE_ID LEFT_PAREN INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN */ +#line 4217 "MachineIndependent/glslang.y" { parseContext.intermediate.insertSpirvExecutionModeId((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); (yyval.interm.intermNode) = 0; } -#line 11812 "MachineIndependent/glslang_tab.cpp" +#line 12013 "MachineIndependent/glslang_tab.cpp" break; - case 641: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN */ -#line 4187 "MachineIndependent/glslang.y" + case 652: /* spirv_execution_mode_qualifier: SPIRV_EXECUTION_MODE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_execution_mode_id_parameter_list RIGHT_PAREN */ +#line 4221 "MachineIndependent/glslang.y" { parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq)); parseContext.intermediate.insertSpirvExecutionModeId((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); (yyval.interm.intermNode) = 0; } -#line 11822 "MachineIndependent/glslang_tab.cpp" +#line 12023 "MachineIndependent/glslang_tab.cpp" break; - case 642: /* spirv_execution_mode_parameter_list: spirv_execution_mode_parameter */ -#line 4194 "MachineIndependent/glslang.y" + case 653: /* spirv_execution_mode_parameter_list: spirv_execution_mode_parameter */ +#line 4228 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); } -#line 11830 "MachineIndependent/glslang_tab.cpp" +#line 12031 "MachineIndependent/glslang_tab.cpp" break; - case 643: /* spirv_execution_mode_parameter_list: spirv_execution_mode_parameter_list COMMA spirv_execution_mode_parameter */ -#line 4197 "MachineIndependent/glslang.y" + case 654: /* spirv_execution_mode_parameter_list: spirv_execution_mode_parameter_list COMMA spirv_execution_mode_parameter */ +#line 4231 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermNode)); } -#line 11838 "MachineIndependent/glslang_tab.cpp" +#line 12039 "MachineIndependent/glslang_tab.cpp" break; - case 644: /* spirv_execution_mode_parameter: FLOATCONSTANT */ -#line 4202 "MachineIndependent/glslang.y" + case 655: /* spirv_execution_mode_parameter: FLOATCONSTANT */ +#line 4236 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); } -#line 11846 "MachineIndependent/glslang_tab.cpp" +#line 12047 "MachineIndependent/glslang_tab.cpp" break; - case 645: /* spirv_execution_mode_parameter: INTCONSTANT */ -#line 4205 "MachineIndependent/glslang.y" + case 656: /* spirv_execution_mode_parameter: INTCONSTANT */ +#line 4239 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); } -#line 11854 "MachineIndependent/glslang_tab.cpp" +#line 12055 "MachineIndependent/glslang_tab.cpp" break; - case 646: /* spirv_execution_mode_parameter: UINTCONSTANT */ -#line 4208 "MachineIndependent/glslang.y" + case 657: /* spirv_execution_mode_parameter: UINTCONSTANT */ +#line 4242 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); } -#line 11862 "MachineIndependent/glslang_tab.cpp" +#line 12063 "MachineIndependent/glslang_tab.cpp" break; - case 647: /* spirv_execution_mode_parameter: BOOLCONSTANT */ -#line 4211 "MachineIndependent/glslang.y" + case 658: /* spirv_execution_mode_parameter: BOOLCONSTANT */ +#line 4245 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); } -#line 11870 "MachineIndependent/glslang_tab.cpp" +#line 12071 "MachineIndependent/glslang_tab.cpp" break; - case 648: /* spirv_execution_mode_parameter: STRING_LITERAL */ -#line 4214 "MachineIndependent/glslang.y" + case 659: /* spirv_execution_mode_parameter: STRING_LITERAL */ +#line 4248 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true); } -#line 11878 "MachineIndependent/glslang_tab.cpp" +#line 12079 "MachineIndependent/glslang_tab.cpp" break; - case 649: /* spirv_execution_mode_id_parameter_list: constant_expression */ -#line 4219 "MachineIndependent/glslang.y" + case 660: /* spirv_execution_mode_id_parameter_list: constant_expression */ +#line 4253 "MachineIndependent/glslang.y" { if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat && (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt && @@ -11888,11 +12089,11 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "this type not allowed", (yyvsp[0].interm.intermTypedNode)->getType().getBasicString(), ""); (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermTypedNode)); } -#line 11892 "MachineIndependent/glslang_tab.cpp" +#line 12093 "MachineIndependent/glslang_tab.cpp" break; - case 650: /* spirv_execution_mode_id_parameter_list: spirv_execution_mode_id_parameter_list COMMA constant_expression */ -#line 4228 "MachineIndependent/glslang.y" + case 661: /* spirv_execution_mode_id_parameter_list: spirv_execution_mode_id_parameter_list COMMA constant_expression */ +#line 4262 "MachineIndependent/glslang.y" { if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat && (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt && @@ -11902,310 +12103,351 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "this type not allowed", (yyvsp[0].interm.intermTypedNode)->getType().getBasicString(), ""); (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermTypedNode)); } -#line 11906 "MachineIndependent/glslang_tab.cpp" +#line 12107 "MachineIndependent/glslang_tab.cpp" break; - case 651: /* spirv_storage_class_qualifier: SPIRV_STORAGE_CLASS LEFT_PAREN INTCONSTANT RIGHT_PAREN */ -#line 4239 "MachineIndependent/glslang.y" + case 662: /* spirv_storage_class_qualifier: SPIRV_STORAGE_CLASS LEFT_PAREN INTCONSTANT RIGHT_PAREN */ +#line 4273 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-3].lex).loc); (yyval.interm.type).qualifier.storage = EvqSpirvStorageClass; (yyval.interm.type).qualifier.spirvStorageClass = (yyvsp[-1].lex).i; } -#line 11916 "MachineIndependent/glslang_tab.cpp" +#line 12117 "MachineIndependent/glslang_tab.cpp" break; - case 652: /* spirv_storage_class_qualifier: SPIRV_STORAGE_CLASS LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */ -#line 4244 "MachineIndependent/glslang.y" + case 663: /* spirv_storage_class_qualifier: SPIRV_STORAGE_CLASS LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */ +#line 4278 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-5].lex).loc); parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq)); (yyval.interm.type).qualifier.storage = EvqSpirvStorageClass; (yyval.interm.type).qualifier.spirvStorageClass = (yyvsp[-1].lex).i; } -#line 11927 "MachineIndependent/glslang_tab.cpp" +#line 12128 "MachineIndependent/glslang_tab.cpp" break; - case 653: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN INTCONSTANT RIGHT_PAREN */ -#line 4252 "MachineIndependent/glslang.y" + case 664: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN INTCONSTANT RIGHT_PAREN */ +#line 4286 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-3].lex).loc); (yyval.interm.type).qualifier.setSpirvDecorate((yyvsp[-1].lex).i); } -#line 11936 "MachineIndependent/glslang_tab.cpp" +#line 12137 "MachineIndependent/glslang_tab.cpp" break; - case 654: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */ -#line 4256 "MachineIndependent/glslang.y" + case 665: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT RIGHT_PAREN */ +#line 4290 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-5].lex).loc); parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq)); (yyval.interm.type).qualifier.setSpirvDecorate((yyvsp[-1].lex).i); } -#line 11946 "MachineIndependent/glslang_tab.cpp" +#line 12147 "MachineIndependent/glslang_tab.cpp" break; - case 655: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN */ -#line 4261 "MachineIndependent/glslang.y" + case 666: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN */ +#line 4295 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-5].lex).loc); (yyval.interm.type).qualifier.setSpirvDecorate((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); } -#line 11955 "MachineIndependent/glslang_tab.cpp" +#line 12156 "MachineIndependent/glslang_tab.cpp" break; - case 656: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN */ -#line 4265 "MachineIndependent/glslang.y" + case 667: /* spirv_decorate_qualifier: SPIRV_DECORATE LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_parameter_list RIGHT_PAREN */ +#line 4299 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-7].lex).loc); parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq)); (yyval.interm.type).qualifier.setSpirvDecorate((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); } -#line 11965 "MachineIndependent/glslang_tab.cpp" +#line 12166 "MachineIndependent/glslang_tab.cpp" break; - case 657: /* spirv_decorate_qualifier: SPIRV_DECORATE_ID LEFT_PAREN INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN */ -#line 4270 "MachineIndependent/glslang.y" + case 668: /* spirv_decorate_qualifier: SPIRV_DECORATE_ID LEFT_PAREN INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN */ +#line 4304 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-5].lex).loc); (yyval.interm.type).qualifier.setSpirvDecorateId((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); } -#line 11974 "MachineIndependent/glslang_tab.cpp" +#line 12175 "MachineIndependent/glslang_tab.cpp" break; - case 658: /* spirv_decorate_qualifier: SPIRV_DECORATE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN */ -#line 4274 "MachineIndependent/glslang.y" + case 669: /* spirv_decorate_qualifier: SPIRV_DECORATE_ID LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_id_parameter_list RIGHT_PAREN */ +#line 4308 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-7].lex).loc); parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq)); (yyval.interm.type).qualifier.setSpirvDecorateId((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); } -#line 11984 "MachineIndependent/glslang_tab.cpp" +#line 12185 "MachineIndependent/glslang_tab.cpp" break; - case 659: /* spirv_decorate_qualifier: SPIRV_DECORATE_STRING LEFT_PAREN INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN */ -#line 4279 "MachineIndependent/glslang.y" + case 670: /* spirv_decorate_qualifier: SPIRV_DECORATE_STRING LEFT_PAREN INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN */ +#line 4313 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-5].lex).loc); (yyval.interm.type).qualifier.setSpirvDecorateString((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); } -#line 11993 "MachineIndependent/glslang_tab.cpp" +#line 12194 "MachineIndependent/glslang_tab.cpp" break; - case 660: /* spirv_decorate_qualifier: SPIRV_DECORATE_STRING LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN */ -#line 4283 "MachineIndependent/glslang.y" + case 671: /* spirv_decorate_qualifier: SPIRV_DECORATE_STRING LEFT_PAREN spirv_requirements_list COMMA INTCONSTANT COMMA spirv_decorate_string_parameter_list RIGHT_PAREN */ +#line 4317 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-7].lex).loc); parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq)); (yyval.interm.type).qualifier.setSpirvDecorateString((yyvsp[-3].lex).i, (yyvsp[-1].interm.intermNode)->getAsAggregate()); } -#line 12003 "MachineIndependent/glslang_tab.cpp" +#line 12204 "MachineIndependent/glslang_tab.cpp" break; - case 661: /* spirv_decorate_parameter_list: spirv_decorate_parameter */ -#line 4290 "MachineIndependent/glslang.y" + case 672: /* spirv_decorate_parameter_list: spirv_decorate_parameter */ +#line 4324 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); } -#line 12011 "MachineIndependent/glslang_tab.cpp" +#line 12212 "MachineIndependent/glslang_tab.cpp" break; - case 662: /* spirv_decorate_parameter_list: spirv_decorate_parameter_list COMMA spirv_decorate_parameter */ -#line 4293 "MachineIndependent/glslang.y" + case 673: /* spirv_decorate_parameter_list: spirv_decorate_parameter_list COMMA spirv_decorate_parameter */ +#line 4327 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermNode)); } -#line 12019 "MachineIndependent/glslang_tab.cpp" +#line 12220 "MachineIndependent/glslang_tab.cpp" break; - case 663: /* spirv_decorate_parameter: FLOATCONSTANT */ -#line 4298 "MachineIndependent/glslang.y" + case 674: /* spirv_decorate_parameter: FLOATCONSTANT */ +#line 4332 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); } -#line 12027 "MachineIndependent/glslang_tab.cpp" +#line 12228 "MachineIndependent/glslang_tab.cpp" break; - case 664: /* spirv_decorate_parameter: INTCONSTANT */ -#line 4301 "MachineIndependent/glslang.y" + case 675: /* spirv_decorate_parameter: INTCONSTANT */ +#line 4335 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); } -#line 12035 "MachineIndependent/glslang_tab.cpp" +#line 12236 "MachineIndependent/glslang_tab.cpp" break; - case 665: /* spirv_decorate_parameter: UINTCONSTANT */ -#line 4304 "MachineIndependent/glslang.y" + case 676: /* spirv_decorate_parameter: UINTCONSTANT */ +#line 4338 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); } -#line 12043 "MachineIndependent/glslang_tab.cpp" +#line 12244 "MachineIndependent/glslang_tab.cpp" break; - case 666: /* spirv_decorate_parameter: BOOLCONSTANT */ -#line 4307 "MachineIndependent/glslang.y" + case 677: /* spirv_decorate_parameter: BOOLCONSTANT */ +#line 4341 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); } -#line 12051 "MachineIndependent/glslang_tab.cpp" +#line 12252 "MachineIndependent/glslang_tab.cpp" + break; + + case 678: /* spirv_decorate_id_parameter_list: spirv_decorate_id_parameter */ +#line 4346 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermNode)); + } +#line 12260 "MachineIndependent/glslang_tab.cpp" + break; + + case 679: /* spirv_decorate_id_parameter_list: spirv_decorate_id_parameter_list COMMA spirv_decorate_id_parameter */ +#line 4349 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermNode)); + } +#line 12268 "MachineIndependent/glslang_tab.cpp" break; - case 667: /* spirv_decorate_id_parameter_list: constant_expression */ -#line 4312 "MachineIndependent/glslang.y" + case 680: /* spirv_decorate_id_parameter: variable_identifier */ +#line 4354 "MachineIndependent/glslang.y" { - if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat && - (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt && - (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtUint && - (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtBool) - parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "this type not allowed", (yyvsp[0].interm.intermTypedNode)->getType().getBasicString(), ""); - (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate((yyvsp[0].interm.intermTypedNode)); + if ((yyvsp[0].interm.intermTypedNode)->getAsConstantUnion() || (yyvsp[0].interm.intermTypedNode)->getAsSymbolNode()) + (yyval.interm.intermNode) = (yyvsp[0].interm.intermTypedNode); + else + parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "only allow constants or variables which are not elements of a composite", "", ""); } -#line 12064 "MachineIndependent/glslang_tab.cpp" +#line 12279 "MachineIndependent/glslang_tab.cpp" break; - case 668: /* spirv_decorate_id_parameter_list: spirv_decorate_id_parameter_list COMMA constant_expression */ -#line 4320 "MachineIndependent/glslang.y" - { - if ((yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtFloat && - (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtInt && - (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtUint && - (yyvsp[0].interm.intermTypedNode)->getBasicType() != EbtBool) - parseContext.error((yyvsp[0].interm.intermTypedNode)->getLoc(), "this type not allowed", (yyvsp[0].interm.intermTypedNode)->getType().getBasicString(), ""); - (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), (yyvsp[0].interm.intermTypedNode)); + case 681: /* spirv_decorate_id_parameter: FLOATCONSTANT */ +#line 4360 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).d, EbtFloat, (yyvsp[0].lex).loc, true); + } +#line 12287 "MachineIndependent/glslang_tab.cpp" + break; + + case 682: /* spirv_decorate_id_parameter: INTCONSTANT */ +#line 4363 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).i, (yyvsp[0].lex).loc, true); + } +#line 12295 "MachineIndependent/glslang_tab.cpp" + break; + + case 683: /* spirv_decorate_id_parameter: UINTCONSTANT */ +#line 4366 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).u, (yyvsp[0].lex).loc, true); } -#line 12077 "MachineIndependent/glslang_tab.cpp" +#line 12303 "MachineIndependent/glslang_tab.cpp" break; - case 669: /* spirv_decorate_string_parameter_list: STRING_LITERAL */ -#line 4330 "MachineIndependent/glslang.y" + case 684: /* spirv_decorate_id_parameter: BOOLCONSTANT */ +#line 4369 "MachineIndependent/glslang.y" + { + (yyval.interm.intermNode) = parseContext.intermediate.addConstantUnion((yyvsp[0].lex).b, (yyvsp[0].lex).loc, true); + } +#line 12311 "MachineIndependent/glslang_tab.cpp" + break; + + case 685: /* spirv_decorate_string_parameter_list: STRING_LITERAL */ +#line 4374 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.makeAggregate( parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true)); } -#line 12086 "MachineIndependent/glslang_tab.cpp" +#line 12320 "MachineIndependent/glslang_tab.cpp" break; - case 670: /* spirv_decorate_string_parameter_list: spirv_decorate_string_parameter_list COMMA STRING_LITERAL */ -#line 4334 "MachineIndependent/glslang.y" + case 686: /* spirv_decorate_string_parameter_list: spirv_decorate_string_parameter_list COMMA STRING_LITERAL */ +#line 4378 "MachineIndependent/glslang.y" { (yyval.interm.intermNode) = parseContext.intermediate.growAggregate((yyvsp[-2].interm.intermNode), parseContext.intermediate.addConstantUnion((yyvsp[0].lex).string, (yyvsp[0].lex).loc, true)); } -#line 12094 "MachineIndependent/glslang_tab.cpp" +#line 12328 "MachineIndependent/glslang_tab.cpp" break; - case 671: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN */ -#line 4339 "MachineIndependent/glslang.y" + case 687: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN */ +#line 4383 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-5].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).setSpirvType(*(yyvsp[-3].interm.spirvInst), (yyvsp[-1].interm.spirvTypeParams)); } -#line 12103 "MachineIndependent/glslang_tab.cpp" +#line 12337 "MachineIndependent/glslang_tab.cpp" break; - case 672: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN */ -#line 4343 "MachineIndependent/glslang.y" + case 688: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list COMMA spirv_type_parameter_list RIGHT_PAREN */ +#line 4387 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-7].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.intermediate.insertSpirvRequirement((yyvsp[-5].interm.spirvReq)); (yyval.interm.type).setSpirvType(*(yyvsp[-3].interm.spirvInst), (yyvsp[-1].interm.spirvTypeParams)); } -#line 12113 "MachineIndependent/glslang_tab.cpp" +#line 12347 "MachineIndependent/glslang_tab.cpp" break; - case 673: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN */ -#line 4348 "MachineIndependent/glslang.y" + case 689: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN */ +#line 4392 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-3].lex).loc, parseContext.symbolTable.atGlobalLevel()); (yyval.interm.type).setSpirvType(*(yyvsp[-1].interm.spirvInst)); } -#line 12122 "MachineIndependent/glslang_tab.cpp" +#line 12356 "MachineIndependent/glslang_tab.cpp" break; - case 674: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN */ -#line 4352 "MachineIndependent/glslang.y" + case 690: /* spirv_type_specifier: SPIRV_TYPE LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN */ +#line 4396 "MachineIndependent/glslang.y" { (yyval.interm.type).init((yyvsp[-5].lex).loc, parseContext.symbolTable.atGlobalLevel()); parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq)); (yyval.interm.type).setSpirvType(*(yyvsp[-1].interm.spirvInst)); } -#line 12132 "MachineIndependent/glslang_tab.cpp" +#line 12366 "MachineIndependent/glslang_tab.cpp" break; - case 675: /* spirv_type_parameter_list: spirv_type_parameter */ -#line 4359 "MachineIndependent/glslang.y" + case 691: /* spirv_type_parameter_list: spirv_type_parameter */ +#line 4403 "MachineIndependent/glslang.y" { (yyval.interm.spirvTypeParams) = (yyvsp[0].interm.spirvTypeParams); } -#line 12140 "MachineIndependent/glslang_tab.cpp" +#line 12374 "MachineIndependent/glslang_tab.cpp" break; - case 676: /* spirv_type_parameter_list: spirv_type_parameter_list COMMA spirv_type_parameter */ -#line 4362 "MachineIndependent/glslang.y" + case 692: /* spirv_type_parameter_list: spirv_type_parameter_list COMMA spirv_type_parameter */ +#line 4406 "MachineIndependent/glslang.y" { (yyval.interm.spirvTypeParams) = parseContext.mergeSpirvTypeParameters((yyvsp[-2].interm.spirvTypeParams), (yyvsp[0].interm.spirvTypeParams)); } -#line 12148 "MachineIndependent/glslang_tab.cpp" +#line 12382 "MachineIndependent/glslang_tab.cpp" break; - case 677: /* spirv_type_parameter: constant_expression */ -#line 4367 "MachineIndependent/glslang.y" + case 693: /* spirv_type_parameter: constant_expression */ +#line 4411 "MachineIndependent/glslang.y" { (yyval.interm.spirvTypeParams) = parseContext.makeSpirvTypeParameters((yyvsp[0].interm.intermTypedNode)->getLoc(), (yyvsp[0].interm.intermTypedNode)->getAsConstantUnion()); } -#line 12156 "MachineIndependent/glslang_tab.cpp" +#line 12390 "MachineIndependent/glslang_tab.cpp" + break; + + case 694: /* spirv_type_parameter: type_specifier_nonarray */ +#line 4414 "MachineIndependent/glslang.y" + { + (yyval.interm.spirvTypeParams) = parseContext.makeSpirvTypeParameters((yyvsp[0].interm.type).loc, (yyvsp[0].interm.type)); + } +#line 12398 "MachineIndependent/glslang_tab.cpp" break; - case 678: /* spirv_instruction_qualifier: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN */ -#line 4372 "MachineIndependent/glslang.y" + case 695: /* spirv_instruction_qualifier: SPIRV_INSTRUCTION LEFT_PAREN spirv_instruction_qualifier_list RIGHT_PAREN */ +#line 4419 "MachineIndependent/glslang.y" { (yyval.interm.spirvInst) = (yyvsp[-1].interm.spirvInst); } -#line 12164 "MachineIndependent/glslang_tab.cpp" +#line 12406 "MachineIndependent/glslang_tab.cpp" break; - case 679: /* spirv_instruction_qualifier: SPIRV_INSTRUCTION LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN */ -#line 4375 "MachineIndependent/glslang.y" + case 696: /* spirv_instruction_qualifier: SPIRV_INSTRUCTION LEFT_PAREN spirv_requirements_list COMMA spirv_instruction_qualifier_list RIGHT_PAREN */ +#line 4422 "MachineIndependent/glslang.y" { parseContext.intermediate.insertSpirvRequirement((yyvsp[-3].interm.spirvReq)); (yyval.interm.spirvInst) = (yyvsp[-1].interm.spirvInst); } -#line 12173 "MachineIndependent/glslang_tab.cpp" +#line 12415 "MachineIndependent/glslang_tab.cpp" break; - case 680: /* spirv_instruction_qualifier_list: spirv_instruction_qualifier_id */ -#line 4381 "MachineIndependent/glslang.y" + case 697: /* spirv_instruction_qualifier_list: spirv_instruction_qualifier_id */ +#line 4428 "MachineIndependent/glslang.y" { (yyval.interm.spirvInst) = (yyvsp[0].interm.spirvInst); } -#line 12181 "MachineIndependent/glslang_tab.cpp" +#line 12423 "MachineIndependent/glslang_tab.cpp" break; - case 681: /* spirv_instruction_qualifier_list: spirv_instruction_qualifier_list COMMA spirv_instruction_qualifier_id */ -#line 4384 "MachineIndependent/glslang.y" + case 698: /* spirv_instruction_qualifier_list: spirv_instruction_qualifier_list COMMA spirv_instruction_qualifier_id */ +#line 4431 "MachineIndependent/glslang.y" { (yyval.interm.spirvInst) = parseContext.mergeSpirvInstruction((yyvsp[-1].lex).loc, (yyvsp[-2].interm.spirvInst), (yyvsp[0].interm.spirvInst)); } -#line 12189 "MachineIndependent/glslang_tab.cpp" +#line 12431 "MachineIndependent/glslang_tab.cpp" break; - case 682: /* spirv_instruction_qualifier_id: IDENTIFIER EQUAL STRING_LITERAL */ -#line 4389 "MachineIndependent/glslang.y" + case 699: /* spirv_instruction_qualifier_id: IDENTIFIER EQUAL STRING_LITERAL */ +#line 4436 "MachineIndependent/glslang.y" { (yyval.interm.spirvInst) = parseContext.makeSpirvInstruction((yyvsp[-1].lex).loc, *(yyvsp[-2].lex).string, *(yyvsp[0].lex).string); } -#line 12197 "MachineIndependent/glslang_tab.cpp" +#line 12439 "MachineIndependent/glslang_tab.cpp" break; - case 683: /* spirv_instruction_qualifier_id: IDENTIFIER EQUAL INTCONSTANT */ -#line 4392 "MachineIndependent/glslang.y" + case 700: /* spirv_instruction_qualifier_id: IDENTIFIER EQUAL INTCONSTANT */ +#line 4439 "MachineIndependent/glslang.y" { (yyval.interm.spirvInst) = parseContext.makeSpirvInstruction((yyvsp[-1].lex).loc, *(yyvsp[-2].lex).string, (yyvsp[0].lex).i); } -#line 12205 "MachineIndependent/glslang_tab.cpp" +#line 12447 "MachineIndependent/glslang_tab.cpp" break; -#line 12209 "MachineIndependent/glslang_tab.cpp" +#line 12451 "MachineIndependent/glslang_tab.cpp" default: break; } @@ -12281,7 +12523,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); } yyerror (pParseContext, yymsgp); if (yysyntax_error_status == YYENOMEM) - goto yyexhaustedlab; + YYNOMEM; } } @@ -12317,6 +12559,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); label yyerrorlab therefore never appears in user code. */ if (0) YYERROR; + ++yynerrs; /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ @@ -12377,7 +12620,7 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); `-------------------------------------*/ yyacceptlab: yyresult = 0; - goto yyreturn; + goto yyreturnlab; /*-----------------------------------. @@ -12385,24 +12628,22 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); `-----------------------------------*/ yyabortlab: yyresult = 1; - goto yyreturn; + goto yyreturnlab; -#if 1 -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ +/*-----------------------------------------------------------. +| yyexhaustedlab -- YYNOMEM (memory exhaustion) comes here. | +`-----------------------------------------------------------*/ yyexhaustedlab: yyerror (pParseContext, YY_("memory exhausted")); yyresult = 2; - goto yyreturn; -#endif + goto yyreturnlab; -/*-------------------------------------------------------. -| yyreturn -- parsing is finished, clean up and return. | -`-------------------------------------------------------*/ -yyreturn: +/*----------------------------------------------------------. +| yyreturnlab -- parsing is finished, clean up and return. | +`----------------------------------------------------------*/ +yyreturnlab: if (yychar != YYEMPTY) { /* Make sure we have latest lookahead translation. See comments at @@ -12430,5 +12671,5 @@ YYSTYPE yylval YY_INITIAL_VALUE (= yyval_default); return yyresult; } -#line 4397 "MachineIndependent/glslang.y" +#line 4443 "MachineIndependent/glslang.y" diff --git a/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h b/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h index 596a10e6d..d6484924d 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h +++ b/src/libraries/glslang/glslang/MachineIndependent/glslang_tab.cpp.h @@ -1,8 +1,8 @@ -/* A Bison parser, made by GNU Bison 3.7.4. */ +/* A Bison parser, made by GNU Bison 3.8.2. */ /* Bison interface for Yacc-like parsers in C - Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2020 Free Software Foundation, + Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify @@ -16,7 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . */ /* As a special exception, you may create a larger work that contains part or all of the Bison parser skeleton and distribute that work @@ -217,295 +217,305 @@ extern int yydebug; FCOOPMATNV = 418, /* FCOOPMATNV */ ICOOPMATNV = 419, /* ICOOPMATNV */ UCOOPMATNV = 420, /* UCOOPMATNV */ - SAMPLERCUBEARRAY = 421, /* SAMPLERCUBEARRAY */ - SAMPLERCUBEARRAYSHADOW = 422, /* SAMPLERCUBEARRAYSHADOW */ - ISAMPLERCUBEARRAY = 423, /* ISAMPLERCUBEARRAY */ - USAMPLERCUBEARRAY = 424, /* USAMPLERCUBEARRAY */ - SAMPLER1D = 425, /* SAMPLER1D */ - SAMPLER1DARRAY = 426, /* SAMPLER1DARRAY */ - SAMPLER1DARRAYSHADOW = 427, /* SAMPLER1DARRAYSHADOW */ - ISAMPLER1D = 428, /* ISAMPLER1D */ - SAMPLER1DSHADOW = 429, /* SAMPLER1DSHADOW */ - SAMPLER2DRECT = 430, /* SAMPLER2DRECT */ - SAMPLER2DRECTSHADOW = 431, /* SAMPLER2DRECTSHADOW */ - ISAMPLER2DRECT = 432, /* ISAMPLER2DRECT */ - USAMPLER2DRECT = 433, /* USAMPLER2DRECT */ - SAMPLERBUFFER = 434, /* SAMPLERBUFFER */ - ISAMPLERBUFFER = 435, /* ISAMPLERBUFFER */ - USAMPLERBUFFER = 436, /* USAMPLERBUFFER */ - SAMPLER2DMS = 437, /* SAMPLER2DMS */ - ISAMPLER2DMS = 438, /* ISAMPLER2DMS */ - USAMPLER2DMS = 439, /* USAMPLER2DMS */ - SAMPLER2DMSARRAY = 440, /* SAMPLER2DMSARRAY */ - ISAMPLER2DMSARRAY = 441, /* ISAMPLER2DMSARRAY */ - USAMPLER2DMSARRAY = 442, /* USAMPLER2DMSARRAY */ - SAMPLEREXTERNALOES = 443, /* SAMPLEREXTERNALOES */ - SAMPLEREXTERNAL2DY2YEXT = 444, /* SAMPLEREXTERNAL2DY2YEXT */ - ISAMPLER1DARRAY = 445, /* ISAMPLER1DARRAY */ - USAMPLER1D = 446, /* USAMPLER1D */ - USAMPLER1DARRAY = 447, /* USAMPLER1DARRAY */ - F16SAMPLER1D = 448, /* F16SAMPLER1D */ - F16SAMPLER2D = 449, /* F16SAMPLER2D */ - F16SAMPLER3D = 450, /* F16SAMPLER3D */ - F16SAMPLER2DRECT = 451, /* F16SAMPLER2DRECT */ - F16SAMPLERCUBE = 452, /* F16SAMPLERCUBE */ - F16SAMPLER1DARRAY = 453, /* F16SAMPLER1DARRAY */ - F16SAMPLER2DARRAY = 454, /* F16SAMPLER2DARRAY */ - F16SAMPLERCUBEARRAY = 455, /* F16SAMPLERCUBEARRAY */ - F16SAMPLERBUFFER = 456, /* F16SAMPLERBUFFER */ - F16SAMPLER2DMS = 457, /* F16SAMPLER2DMS */ - F16SAMPLER2DMSARRAY = 458, /* F16SAMPLER2DMSARRAY */ - F16SAMPLER1DSHADOW = 459, /* F16SAMPLER1DSHADOW */ - F16SAMPLER2DSHADOW = 460, /* F16SAMPLER2DSHADOW */ - F16SAMPLER1DARRAYSHADOW = 461, /* F16SAMPLER1DARRAYSHADOW */ - F16SAMPLER2DARRAYSHADOW = 462, /* F16SAMPLER2DARRAYSHADOW */ - F16SAMPLER2DRECTSHADOW = 463, /* F16SAMPLER2DRECTSHADOW */ - F16SAMPLERCUBESHADOW = 464, /* F16SAMPLERCUBESHADOW */ - F16SAMPLERCUBEARRAYSHADOW = 465, /* F16SAMPLERCUBEARRAYSHADOW */ - IMAGE1D = 466, /* IMAGE1D */ - IIMAGE1D = 467, /* IIMAGE1D */ - UIMAGE1D = 468, /* UIMAGE1D */ - IMAGE2D = 469, /* IMAGE2D */ - IIMAGE2D = 470, /* IIMAGE2D */ - UIMAGE2D = 471, /* UIMAGE2D */ - IMAGE3D = 472, /* IMAGE3D */ - IIMAGE3D = 473, /* IIMAGE3D */ - UIMAGE3D = 474, /* UIMAGE3D */ - IMAGE2DRECT = 475, /* IMAGE2DRECT */ - IIMAGE2DRECT = 476, /* IIMAGE2DRECT */ - UIMAGE2DRECT = 477, /* UIMAGE2DRECT */ - IMAGECUBE = 478, /* IMAGECUBE */ - IIMAGECUBE = 479, /* IIMAGECUBE */ - UIMAGECUBE = 480, /* UIMAGECUBE */ - IMAGEBUFFER = 481, /* IMAGEBUFFER */ - IIMAGEBUFFER = 482, /* IIMAGEBUFFER */ - UIMAGEBUFFER = 483, /* UIMAGEBUFFER */ - IMAGE1DARRAY = 484, /* IMAGE1DARRAY */ - IIMAGE1DARRAY = 485, /* IIMAGE1DARRAY */ - UIMAGE1DARRAY = 486, /* UIMAGE1DARRAY */ - IMAGE2DARRAY = 487, /* IMAGE2DARRAY */ - IIMAGE2DARRAY = 488, /* IIMAGE2DARRAY */ - UIMAGE2DARRAY = 489, /* UIMAGE2DARRAY */ - IMAGECUBEARRAY = 490, /* IMAGECUBEARRAY */ - IIMAGECUBEARRAY = 491, /* IIMAGECUBEARRAY */ - UIMAGECUBEARRAY = 492, /* UIMAGECUBEARRAY */ - IMAGE2DMS = 493, /* IMAGE2DMS */ - IIMAGE2DMS = 494, /* IIMAGE2DMS */ - UIMAGE2DMS = 495, /* UIMAGE2DMS */ - IMAGE2DMSARRAY = 496, /* IMAGE2DMSARRAY */ - IIMAGE2DMSARRAY = 497, /* IIMAGE2DMSARRAY */ - UIMAGE2DMSARRAY = 498, /* UIMAGE2DMSARRAY */ - F16IMAGE1D = 499, /* F16IMAGE1D */ - F16IMAGE2D = 500, /* F16IMAGE2D */ - F16IMAGE3D = 501, /* F16IMAGE3D */ - F16IMAGE2DRECT = 502, /* F16IMAGE2DRECT */ - F16IMAGECUBE = 503, /* F16IMAGECUBE */ - F16IMAGE1DARRAY = 504, /* F16IMAGE1DARRAY */ - F16IMAGE2DARRAY = 505, /* F16IMAGE2DARRAY */ - F16IMAGECUBEARRAY = 506, /* F16IMAGECUBEARRAY */ - F16IMAGEBUFFER = 507, /* F16IMAGEBUFFER */ - F16IMAGE2DMS = 508, /* F16IMAGE2DMS */ - F16IMAGE2DMSARRAY = 509, /* F16IMAGE2DMSARRAY */ - I64IMAGE1D = 510, /* I64IMAGE1D */ - U64IMAGE1D = 511, /* U64IMAGE1D */ - I64IMAGE2D = 512, /* I64IMAGE2D */ - U64IMAGE2D = 513, /* U64IMAGE2D */ - I64IMAGE3D = 514, /* I64IMAGE3D */ - U64IMAGE3D = 515, /* U64IMAGE3D */ - I64IMAGE2DRECT = 516, /* I64IMAGE2DRECT */ - U64IMAGE2DRECT = 517, /* U64IMAGE2DRECT */ - I64IMAGECUBE = 518, /* I64IMAGECUBE */ - U64IMAGECUBE = 519, /* U64IMAGECUBE */ - I64IMAGEBUFFER = 520, /* I64IMAGEBUFFER */ - U64IMAGEBUFFER = 521, /* U64IMAGEBUFFER */ - I64IMAGE1DARRAY = 522, /* I64IMAGE1DARRAY */ - U64IMAGE1DARRAY = 523, /* U64IMAGE1DARRAY */ - I64IMAGE2DARRAY = 524, /* I64IMAGE2DARRAY */ - U64IMAGE2DARRAY = 525, /* U64IMAGE2DARRAY */ - I64IMAGECUBEARRAY = 526, /* I64IMAGECUBEARRAY */ - U64IMAGECUBEARRAY = 527, /* U64IMAGECUBEARRAY */ - I64IMAGE2DMS = 528, /* I64IMAGE2DMS */ - U64IMAGE2DMS = 529, /* U64IMAGE2DMS */ - I64IMAGE2DMSARRAY = 530, /* I64IMAGE2DMSARRAY */ - U64IMAGE2DMSARRAY = 531, /* U64IMAGE2DMSARRAY */ - TEXTURECUBEARRAY = 532, /* TEXTURECUBEARRAY */ - ITEXTURECUBEARRAY = 533, /* ITEXTURECUBEARRAY */ - UTEXTURECUBEARRAY = 534, /* UTEXTURECUBEARRAY */ - TEXTURE1D = 535, /* TEXTURE1D */ - ITEXTURE1D = 536, /* ITEXTURE1D */ - UTEXTURE1D = 537, /* UTEXTURE1D */ - TEXTURE1DARRAY = 538, /* TEXTURE1DARRAY */ - ITEXTURE1DARRAY = 539, /* ITEXTURE1DARRAY */ - UTEXTURE1DARRAY = 540, /* UTEXTURE1DARRAY */ - TEXTURE2DRECT = 541, /* TEXTURE2DRECT */ - ITEXTURE2DRECT = 542, /* ITEXTURE2DRECT */ - UTEXTURE2DRECT = 543, /* UTEXTURE2DRECT */ - TEXTUREBUFFER = 544, /* TEXTUREBUFFER */ - ITEXTUREBUFFER = 545, /* ITEXTUREBUFFER */ - UTEXTUREBUFFER = 546, /* UTEXTUREBUFFER */ - TEXTURE2DMS = 547, /* TEXTURE2DMS */ - ITEXTURE2DMS = 548, /* ITEXTURE2DMS */ - UTEXTURE2DMS = 549, /* UTEXTURE2DMS */ - TEXTURE2DMSARRAY = 550, /* TEXTURE2DMSARRAY */ - ITEXTURE2DMSARRAY = 551, /* ITEXTURE2DMSARRAY */ - UTEXTURE2DMSARRAY = 552, /* UTEXTURE2DMSARRAY */ - F16TEXTURE1D = 553, /* F16TEXTURE1D */ - F16TEXTURE2D = 554, /* F16TEXTURE2D */ - F16TEXTURE3D = 555, /* F16TEXTURE3D */ - F16TEXTURE2DRECT = 556, /* F16TEXTURE2DRECT */ - F16TEXTURECUBE = 557, /* F16TEXTURECUBE */ - F16TEXTURE1DARRAY = 558, /* F16TEXTURE1DARRAY */ - F16TEXTURE2DARRAY = 559, /* F16TEXTURE2DARRAY */ - F16TEXTURECUBEARRAY = 560, /* F16TEXTURECUBEARRAY */ - F16TEXTUREBUFFER = 561, /* F16TEXTUREBUFFER */ - F16TEXTURE2DMS = 562, /* F16TEXTURE2DMS */ - F16TEXTURE2DMSARRAY = 563, /* F16TEXTURE2DMSARRAY */ - SUBPASSINPUT = 564, /* SUBPASSINPUT */ - SUBPASSINPUTMS = 565, /* SUBPASSINPUTMS */ - ISUBPASSINPUT = 566, /* ISUBPASSINPUT */ - ISUBPASSINPUTMS = 567, /* ISUBPASSINPUTMS */ - USUBPASSINPUT = 568, /* USUBPASSINPUT */ - USUBPASSINPUTMS = 569, /* USUBPASSINPUTMS */ - F16SUBPASSINPUT = 570, /* F16SUBPASSINPUT */ - F16SUBPASSINPUTMS = 571, /* F16SUBPASSINPUTMS */ - SPIRV_INSTRUCTION = 572, /* SPIRV_INSTRUCTION */ - SPIRV_EXECUTION_MODE = 573, /* SPIRV_EXECUTION_MODE */ - SPIRV_EXECUTION_MODE_ID = 574, /* SPIRV_EXECUTION_MODE_ID */ - SPIRV_DECORATE = 575, /* SPIRV_DECORATE */ - SPIRV_DECORATE_ID = 576, /* SPIRV_DECORATE_ID */ - SPIRV_DECORATE_STRING = 577, /* SPIRV_DECORATE_STRING */ - SPIRV_TYPE = 578, /* SPIRV_TYPE */ - SPIRV_STORAGE_CLASS = 579, /* SPIRV_STORAGE_CLASS */ - SPIRV_BY_REFERENCE = 580, /* SPIRV_BY_REFERENCE */ - SPIRV_LITERAL = 581, /* SPIRV_LITERAL */ - LEFT_OP = 582, /* LEFT_OP */ - RIGHT_OP = 583, /* RIGHT_OP */ - INC_OP = 584, /* INC_OP */ - DEC_OP = 585, /* DEC_OP */ - LE_OP = 586, /* LE_OP */ - GE_OP = 587, /* GE_OP */ - EQ_OP = 588, /* EQ_OP */ - NE_OP = 589, /* NE_OP */ - AND_OP = 590, /* AND_OP */ - OR_OP = 591, /* OR_OP */ - XOR_OP = 592, /* XOR_OP */ - MUL_ASSIGN = 593, /* MUL_ASSIGN */ - DIV_ASSIGN = 594, /* DIV_ASSIGN */ - ADD_ASSIGN = 595, /* ADD_ASSIGN */ - MOD_ASSIGN = 596, /* MOD_ASSIGN */ - LEFT_ASSIGN = 597, /* LEFT_ASSIGN */ - RIGHT_ASSIGN = 598, /* RIGHT_ASSIGN */ - AND_ASSIGN = 599, /* AND_ASSIGN */ - XOR_ASSIGN = 600, /* XOR_ASSIGN */ - OR_ASSIGN = 601, /* OR_ASSIGN */ - SUB_ASSIGN = 602, /* SUB_ASSIGN */ - STRING_LITERAL = 603, /* STRING_LITERAL */ - LEFT_PAREN = 604, /* LEFT_PAREN */ - RIGHT_PAREN = 605, /* RIGHT_PAREN */ - LEFT_BRACKET = 606, /* LEFT_BRACKET */ - RIGHT_BRACKET = 607, /* RIGHT_BRACKET */ - LEFT_BRACE = 608, /* LEFT_BRACE */ - RIGHT_BRACE = 609, /* RIGHT_BRACE */ - DOT = 610, /* DOT */ - COMMA = 611, /* COMMA */ - COLON = 612, /* COLON */ - EQUAL = 613, /* EQUAL */ - SEMICOLON = 614, /* SEMICOLON */ - BANG = 615, /* BANG */ - DASH = 616, /* DASH */ - TILDE = 617, /* TILDE */ - PLUS = 618, /* PLUS */ - STAR = 619, /* STAR */ - SLASH = 620, /* SLASH */ - PERCENT = 621, /* PERCENT */ - LEFT_ANGLE = 622, /* LEFT_ANGLE */ - RIGHT_ANGLE = 623, /* RIGHT_ANGLE */ - VERTICAL_BAR = 624, /* VERTICAL_BAR */ - CARET = 625, /* CARET */ - AMPERSAND = 626, /* AMPERSAND */ - QUESTION = 627, /* QUESTION */ - INVARIANT = 628, /* INVARIANT */ - HIGH_PRECISION = 629, /* HIGH_PRECISION */ - MEDIUM_PRECISION = 630, /* MEDIUM_PRECISION */ - LOW_PRECISION = 631, /* LOW_PRECISION */ - PRECISION = 632, /* PRECISION */ - PACKED = 633, /* PACKED */ - RESOURCE = 634, /* RESOURCE */ - SUPERP = 635, /* SUPERP */ - FLOATCONSTANT = 636, /* FLOATCONSTANT */ - INTCONSTANT = 637, /* INTCONSTANT */ - UINTCONSTANT = 638, /* UINTCONSTANT */ - BOOLCONSTANT = 639, /* BOOLCONSTANT */ - IDENTIFIER = 640, /* IDENTIFIER */ - TYPE_NAME = 641, /* TYPE_NAME */ - CENTROID = 642, /* CENTROID */ - IN = 643, /* IN */ - OUT = 644, /* OUT */ - INOUT = 645, /* INOUT */ - STRUCT = 646, /* STRUCT */ - VOID = 647, /* VOID */ - WHILE = 648, /* WHILE */ - BREAK = 649, /* BREAK */ - CONTINUE = 650, /* CONTINUE */ - DO = 651, /* DO */ - ELSE = 652, /* ELSE */ - FOR = 653, /* FOR */ - IF = 654, /* IF */ - DISCARD = 655, /* DISCARD */ - RETURN = 656, /* RETURN */ - SWITCH = 657, /* SWITCH */ - CASE = 658, /* CASE */ - DEFAULT = 659, /* DEFAULT */ - TERMINATE_INVOCATION = 660, /* TERMINATE_INVOCATION */ - TERMINATE_RAY = 661, /* TERMINATE_RAY */ - IGNORE_INTERSECTION = 662, /* IGNORE_INTERSECTION */ - UNIFORM = 663, /* UNIFORM */ - SHARED = 664, /* SHARED */ - BUFFER = 665, /* BUFFER */ - FLAT = 666, /* FLAT */ - SMOOTH = 667, /* SMOOTH */ - LAYOUT = 668, /* LAYOUT */ - DOUBLECONSTANT = 669, /* DOUBLECONSTANT */ - INT16CONSTANT = 670, /* INT16CONSTANT */ - UINT16CONSTANT = 671, /* UINT16CONSTANT */ - FLOAT16CONSTANT = 672, /* FLOAT16CONSTANT */ - INT32CONSTANT = 673, /* INT32CONSTANT */ - UINT32CONSTANT = 674, /* UINT32CONSTANT */ - INT64CONSTANT = 675, /* INT64CONSTANT */ - UINT64CONSTANT = 676, /* UINT64CONSTANT */ - SUBROUTINE = 677, /* SUBROUTINE */ - DEMOTE = 678, /* DEMOTE */ - PAYLOADNV = 679, /* PAYLOADNV */ - PAYLOADINNV = 680, /* PAYLOADINNV */ - HITATTRNV = 681, /* HITATTRNV */ - CALLDATANV = 682, /* CALLDATANV */ - CALLDATAINNV = 683, /* CALLDATAINNV */ - PAYLOADEXT = 684, /* PAYLOADEXT */ - PAYLOADINEXT = 685, /* PAYLOADINEXT */ - HITATTREXT = 686, /* HITATTREXT */ - CALLDATAEXT = 687, /* CALLDATAEXT */ - CALLDATAINEXT = 688, /* CALLDATAINEXT */ - PATCH = 689, /* PATCH */ - SAMPLE = 690, /* SAMPLE */ - NONUNIFORM = 691, /* NONUNIFORM */ - COHERENT = 692, /* COHERENT */ - VOLATILE = 693, /* VOLATILE */ - RESTRICT = 694, /* RESTRICT */ - READONLY = 695, /* READONLY */ - WRITEONLY = 696, /* WRITEONLY */ - DEVICECOHERENT = 697, /* DEVICECOHERENT */ - QUEUEFAMILYCOHERENT = 698, /* QUEUEFAMILYCOHERENT */ - WORKGROUPCOHERENT = 699, /* WORKGROUPCOHERENT */ - SUBGROUPCOHERENT = 700, /* SUBGROUPCOHERENT */ - NONPRIVATE = 701, /* NONPRIVATE */ - SHADERCALLCOHERENT = 702, /* SHADERCALLCOHERENT */ - NOPERSPECTIVE = 703, /* NOPERSPECTIVE */ - EXPLICITINTERPAMD = 704, /* EXPLICITINTERPAMD */ - PERVERTEXNV = 705, /* PERVERTEXNV */ - PERPRIMITIVENV = 706, /* PERPRIMITIVENV */ - PERVIEWNV = 707, /* PERVIEWNV */ - PERTASKNV = 708, /* PERTASKNV */ - PRECISE = 709 /* PRECISE */ + COOPMAT = 421, /* COOPMAT */ + HITOBJECTNV = 422, /* HITOBJECTNV */ + HITOBJECTATTRNV = 423, /* HITOBJECTATTRNV */ + SAMPLERCUBEARRAY = 424, /* SAMPLERCUBEARRAY */ + SAMPLERCUBEARRAYSHADOW = 425, /* SAMPLERCUBEARRAYSHADOW */ + ISAMPLERCUBEARRAY = 426, /* ISAMPLERCUBEARRAY */ + USAMPLERCUBEARRAY = 427, /* USAMPLERCUBEARRAY */ + SAMPLER1D = 428, /* SAMPLER1D */ + SAMPLER1DARRAY = 429, /* SAMPLER1DARRAY */ + SAMPLER1DARRAYSHADOW = 430, /* SAMPLER1DARRAYSHADOW */ + ISAMPLER1D = 431, /* ISAMPLER1D */ + SAMPLER1DSHADOW = 432, /* SAMPLER1DSHADOW */ + SAMPLER2DRECT = 433, /* SAMPLER2DRECT */ + SAMPLER2DRECTSHADOW = 434, /* SAMPLER2DRECTSHADOW */ + ISAMPLER2DRECT = 435, /* ISAMPLER2DRECT */ + USAMPLER2DRECT = 436, /* USAMPLER2DRECT */ + SAMPLERBUFFER = 437, /* SAMPLERBUFFER */ + ISAMPLERBUFFER = 438, /* ISAMPLERBUFFER */ + USAMPLERBUFFER = 439, /* USAMPLERBUFFER */ + SAMPLER2DMS = 440, /* SAMPLER2DMS */ + ISAMPLER2DMS = 441, /* ISAMPLER2DMS */ + USAMPLER2DMS = 442, /* USAMPLER2DMS */ + SAMPLER2DMSARRAY = 443, /* SAMPLER2DMSARRAY */ + ISAMPLER2DMSARRAY = 444, /* ISAMPLER2DMSARRAY */ + USAMPLER2DMSARRAY = 445, /* USAMPLER2DMSARRAY */ + SAMPLEREXTERNALOES = 446, /* SAMPLEREXTERNALOES */ + SAMPLEREXTERNAL2DY2YEXT = 447, /* SAMPLEREXTERNAL2DY2YEXT */ + ISAMPLER1DARRAY = 448, /* ISAMPLER1DARRAY */ + USAMPLER1D = 449, /* USAMPLER1D */ + USAMPLER1DARRAY = 450, /* USAMPLER1DARRAY */ + F16SAMPLER1D = 451, /* F16SAMPLER1D */ + F16SAMPLER2D = 452, /* F16SAMPLER2D */ + F16SAMPLER3D = 453, /* F16SAMPLER3D */ + F16SAMPLER2DRECT = 454, /* F16SAMPLER2DRECT */ + F16SAMPLERCUBE = 455, /* F16SAMPLERCUBE */ + F16SAMPLER1DARRAY = 456, /* F16SAMPLER1DARRAY */ + F16SAMPLER2DARRAY = 457, /* F16SAMPLER2DARRAY */ + F16SAMPLERCUBEARRAY = 458, /* F16SAMPLERCUBEARRAY */ + F16SAMPLERBUFFER = 459, /* F16SAMPLERBUFFER */ + F16SAMPLER2DMS = 460, /* F16SAMPLER2DMS */ + F16SAMPLER2DMSARRAY = 461, /* F16SAMPLER2DMSARRAY */ + F16SAMPLER1DSHADOW = 462, /* F16SAMPLER1DSHADOW */ + F16SAMPLER2DSHADOW = 463, /* F16SAMPLER2DSHADOW */ + F16SAMPLER1DARRAYSHADOW = 464, /* F16SAMPLER1DARRAYSHADOW */ + F16SAMPLER2DARRAYSHADOW = 465, /* F16SAMPLER2DARRAYSHADOW */ + F16SAMPLER2DRECTSHADOW = 466, /* F16SAMPLER2DRECTSHADOW */ + F16SAMPLERCUBESHADOW = 467, /* F16SAMPLERCUBESHADOW */ + F16SAMPLERCUBEARRAYSHADOW = 468, /* F16SAMPLERCUBEARRAYSHADOW */ + IMAGE1D = 469, /* IMAGE1D */ + IIMAGE1D = 470, /* IIMAGE1D */ + UIMAGE1D = 471, /* UIMAGE1D */ + IMAGE2D = 472, /* IMAGE2D */ + IIMAGE2D = 473, /* IIMAGE2D */ + UIMAGE2D = 474, /* UIMAGE2D */ + IMAGE3D = 475, /* IMAGE3D */ + IIMAGE3D = 476, /* IIMAGE3D */ + UIMAGE3D = 477, /* UIMAGE3D */ + IMAGE2DRECT = 478, /* IMAGE2DRECT */ + IIMAGE2DRECT = 479, /* IIMAGE2DRECT */ + UIMAGE2DRECT = 480, /* UIMAGE2DRECT */ + IMAGECUBE = 481, /* IMAGECUBE */ + IIMAGECUBE = 482, /* IIMAGECUBE */ + UIMAGECUBE = 483, /* UIMAGECUBE */ + IMAGEBUFFER = 484, /* IMAGEBUFFER */ + IIMAGEBUFFER = 485, /* IIMAGEBUFFER */ + UIMAGEBUFFER = 486, /* UIMAGEBUFFER */ + IMAGE1DARRAY = 487, /* IMAGE1DARRAY */ + IIMAGE1DARRAY = 488, /* IIMAGE1DARRAY */ + UIMAGE1DARRAY = 489, /* UIMAGE1DARRAY */ + IMAGE2DARRAY = 490, /* IMAGE2DARRAY */ + IIMAGE2DARRAY = 491, /* IIMAGE2DARRAY */ + UIMAGE2DARRAY = 492, /* UIMAGE2DARRAY */ + IMAGECUBEARRAY = 493, /* IMAGECUBEARRAY */ + IIMAGECUBEARRAY = 494, /* IIMAGECUBEARRAY */ + UIMAGECUBEARRAY = 495, /* UIMAGECUBEARRAY */ + IMAGE2DMS = 496, /* IMAGE2DMS */ + IIMAGE2DMS = 497, /* IIMAGE2DMS */ + UIMAGE2DMS = 498, /* UIMAGE2DMS */ + IMAGE2DMSARRAY = 499, /* IMAGE2DMSARRAY */ + IIMAGE2DMSARRAY = 500, /* IIMAGE2DMSARRAY */ + UIMAGE2DMSARRAY = 501, /* UIMAGE2DMSARRAY */ + F16IMAGE1D = 502, /* F16IMAGE1D */ + F16IMAGE2D = 503, /* F16IMAGE2D */ + F16IMAGE3D = 504, /* F16IMAGE3D */ + F16IMAGE2DRECT = 505, /* F16IMAGE2DRECT */ + F16IMAGECUBE = 506, /* F16IMAGECUBE */ + F16IMAGE1DARRAY = 507, /* F16IMAGE1DARRAY */ + F16IMAGE2DARRAY = 508, /* F16IMAGE2DARRAY */ + F16IMAGECUBEARRAY = 509, /* F16IMAGECUBEARRAY */ + F16IMAGEBUFFER = 510, /* F16IMAGEBUFFER */ + F16IMAGE2DMS = 511, /* F16IMAGE2DMS */ + F16IMAGE2DMSARRAY = 512, /* F16IMAGE2DMSARRAY */ + I64IMAGE1D = 513, /* I64IMAGE1D */ + U64IMAGE1D = 514, /* U64IMAGE1D */ + I64IMAGE2D = 515, /* I64IMAGE2D */ + U64IMAGE2D = 516, /* U64IMAGE2D */ + I64IMAGE3D = 517, /* I64IMAGE3D */ + U64IMAGE3D = 518, /* U64IMAGE3D */ + I64IMAGE2DRECT = 519, /* I64IMAGE2DRECT */ + U64IMAGE2DRECT = 520, /* U64IMAGE2DRECT */ + I64IMAGECUBE = 521, /* I64IMAGECUBE */ + U64IMAGECUBE = 522, /* U64IMAGECUBE */ + I64IMAGEBUFFER = 523, /* I64IMAGEBUFFER */ + U64IMAGEBUFFER = 524, /* U64IMAGEBUFFER */ + I64IMAGE1DARRAY = 525, /* I64IMAGE1DARRAY */ + U64IMAGE1DARRAY = 526, /* U64IMAGE1DARRAY */ + I64IMAGE2DARRAY = 527, /* I64IMAGE2DARRAY */ + U64IMAGE2DARRAY = 528, /* U64IMAGE2DARRAY */ + I64IMAGECUBEARRAY = 529, /* I64IMAGECUBEARRAY */ + U64IMAGECUBEARRAY = 530, /* U64IMAGECUBEARRAY */ + I64IMAGE2DMS = 531, /* I64IMAGE2DMS */ + U64IMAGE2DMS = 532, /* U64IMAGE2DMS */ + I64IMAGE2DMSARRAY = 533, /* I64IMAGE2DMSARRAY */ + U64IMAGE2DMSARRAY = 534, /* U64IMAGE2DMSARRAY */ + TEXTURECUBEARRAY = 535, /* TEXTURECUBEARRAY */ + ITEXTURECUBEARRAY = 536, /* ITEXTURECUBEARRAY */ + UTEXTURECUBEARRAY = 537, /* UTEXTURECUBEARRAY */ + TEXTURE1D = 538, /* TEXTURE1D */ + ITEXTURE1D = 539, /* ITEXTURE1D */ + UTEXTURE1D = 540, /* UTEXTURE1D */ + TEXTURE1DARRAY = 541, /* TEXTURE1DARRAY */ + ITEXTURE1DARRAY = 542, /* ITEXTURE1DARRAY */ + UTEXTURE1DARRAY = 543, /* UTEXTURE1DARRAY */ + TEXTURE2DRECT = 544, /* TEXTURE2DRECT */ + ITEXTURE2DRECT = 545, /* ITEXTURE2DRECT */ + UTEXTURE2DRECT = 546, /* UTEXTURE2DRECT */ + TEXTUREBUFFER = 547, /* TEXTUREBUFFER */ + ITEXTUREBUFFER = 548, /* ITEXTUREBUFFER */ + UTEXTUREBUFFER = 549, /* UTEXTUREBUFFER */ + TEXTURE2DMS = 550, /* TEXTURE2DMS */ + ITEXTURE2DMS = 551, /* ITEXTURE2DMS */ + UTEXTURE2DMS = 552, /* UTEXTURE2DMS */ + TEXTURE2DMSARRAY = 553, /* TEXTURE2DMSARRAY */ + ITEXTURE2DMSARRAY = 554, /* ITEXTURE2DMSARRAY */ + UTEXTURE2DMSARRAY = 555, /* UTEXTURE2DMSARRAY */ + F16TEXTURE1D = 556, /* F16TEXTURE1D */ + F16TEXTURE2D = 557, /* F16TEXTURE2D */ + F16TEXTURE3D = 558, /* F16TEXTURE3D */ + F16TEXTURE2DRECT = 559, /* F16TEXTURE2DRECT */ + F16TEXTURECUBE = 560, /* F16TEXTURECUBE */ + F16TEXTURE1DARRAY = 561, /* F16TEXTURE1DARRAY */ + F16TEXTURE2DARRAY = 562, /* F16TEXTURE2DARRAY */ + F16TEXTURECUBEARRAY = 563, /* F16TEXTURECUBEARRAY */ + F16TEXTUREBUFFER = 564, /* F16TEXTUREBUFFER */ + F16TEXTURE2DMS = 565, /* F16TEXTURE2DMS */ + F16TEXTURE2DMSARRAY = 566, /* F16TEXTURE2DMSARRAY */ + SUBPASSINPUT = 567, /* SUBPASSINPUT */ + SUBPASSINPUTMS = 568, /* SUBPASSINPUTMS */ + ISUBPASSINPUT = 569, /* ISUBPASSINPUT */ + ISUBPASSINPUTMS = 570, /* ISUBPASSINPUTMS */ + USUBPASSINPUT = 571, /* USUBPASSINPUT */ + USUBPASSINPUTMS = 572, /* USUBPASSINPUTMS */ + F16SUBPASSINPUT = 573, /* F16SUBPASSINPUT */ + F16SUBPASSINPUTMS = 574, /* F16SUBPASSINPUTMS */ + SPIRV_INSTRUCTION = 575, /* SPIRV_INSTRUCTION */ + SPIRV_EXECUTION_MODE = 576, /* SPIRV_EXECUTION_MODE */ + SPIRV_EXECUTION_MODE_ID = 577, /* SPIRV_EXECUTION_MODE_ID */ + SPIRV_DECORATE = 578, /* SPIRV_DECORATE */ + SPIRV_DECORATE_ID = 579, /* SPIRV_DECORATE_ID */ + SPIRV_DECORATE_STRING = 580, /* SPIRV_DECORATE_STRING */ + SPIRV_TYPE = 581, /* SPIRV_TYPE */ + SPIRV_STORAGE_CLASS = 582, /* SPIRV_STORAGE_CLASS */ + SPIRV_BY_REFERENCE = 583, /* SPIRV_BY_REFERENCE */ + SPIRV_LITERAL = 584, /* SPIRV_LITERAL */ + ATTACHMENTEXT = 585, /* ATTACHMENTEXT */ + IATTACHMENTEXT = 586, /* IATTACHMENTEXT */ + UATTACHMENTEXT = 587, /* UATTACHMENTEXT */ + LEFT_OP = 588, /* LEFT_OP */ + RIGHT_OP = 589, /* RIGHT_OP */ + INC_OP = 590, /* INC_OP */ + DEC_OP = 591, /* DEC_OP */ + LE_OP = 592, /* LE_OP */ + GE_OP = 593, /* GE_OP */ + EQ_OP = 594, /* EQ_OP */ + NE_OP = 595, /* NE_OP */ + AND_OP = 596, /* AND_OP */ + OR_OP = 597, /* OR_OP */ + XOR_OP = 598, /* XOR_OP */ + MUL_ASSIGN = 599, /* MUL_ASSIGN */ + DIV_ASSIGN = 600, /* DIV_ASSIGN */ + ADD_ASSIGN = 601, /* ADD_ASSIGN */ + MOD_ASSIGN = 602, /* MOD_ASSIGN */ + LEFT_ASSIGN = 603, /* LEFT_ASSIGN */ + RIGHT_ASSIGN = 604, /* RIGHT_ASSIGN */ + AND_ASSIGN = 605, /* AND_ASSIGN */ + XOR_ASSIGN = 606, /* XOR_ASSIGN */ + OR_ASSIGN = 607, /* OR_ASSIGN */ + SUB_ASSIGN = 608, /* SUB_ASSIGN */ + STRING_LITERAL = 609, /* STRING_LITERAL */ + LEFT_PAREN = 610, /* LEFT_PAREN */ + RIGHT_PAREN = 611, /* RIGHT_PAREN */ + LEFT_BRACKET = 612, /* LEFT_BRACKET */ + RIGHT_BRACKET = 613, /* RIGHT_BRACKET */ + LEFT_BRACE = 614, /* LEFT_BRACE */ + RIGHT_BRACE = 615, /* RIGHT_BRACE */ + DOT = 616, /* DOT */ + COMMA = 617, /* COMMA */ + COLON = 618, /* COLON */ + EQUAL = 619, /* EQUAL */ + SEMICOLON = 620, /* SEMICOLON */ + BANG = 621, /* BANG */ + DASH = 622, /* DASH */ + TILDE = 623, /* TILDE */ + PLUS = 624, /* PLUS */ + STAR = 625, /* STAR */ + SLASH = 626, /* SLASH */ + PERCENT = 627, /* PERCENT */ + LEFT_ANGLE = 628, /* LEFT_ANGLE */ + RIGHT_ANGLE = 629, /* RIGHT_ANGLE */ + VERTICAL_BAR = 630, /* VERTICAL_BAR */ + CARET = 631, /* CARET */ + AMPERSAND = 632, /* AMPERSAND */ + QUESTION = 633, /* QUESTION */ + INVARIANT = 634, /* INVARIANT */ + HIGH_PRECISION = 635, /* HIGH_PRECISION */ + MEDIUM_PRECISION = 636, /* MEDIUM_PRECISION */ + LOW_PRECISION = 637, /* LOW_PRECISION */ + PRECISION = 638, /* PRECISION */ + PACKED = 639, /* PACKED */ + RESOURCE = 640, /* RESOURCE */ + SUPERP = 641, /* SUPERP */ + FLOATCONSTANT = 642, /* FLOATCONSTANT */ + INTCONSTANT = 643, /* INTCONSTANT */ + UINTCONSTANT = 644, /* UINTCONSTANT */ + BOOLCONSTANT = 645, /* BOOLCONSTANT */ + IDENTIFIER = 646, /* IDENTIFIER */ + TYPE_NAME = 647, /* TYPE_NAME */ + CENTROID = 648, /* CENTROID */ + IN = 649, /* IN */ + OUT = 650, /* OUT */ + INOUT = 651, /* INOUT */ + STRUCT = 652, /* STRUCT */ + VOID = 653, /* VOID */ + WHILE = 654, /* WHILE */ + BREAK = 655, /* BREAK */ + CONTINUE = 656, /* CONTINUE */ + DO = 657, /* DO */ + ELSE = 658, /* ELSE */ + FOR = 659, /* FOR */ + IF = 660, /* IF */ + DISCARD = 661, /* DISCARD */ + RETURN = 662, /* RETURN */ + SWITCH = 663, /* SWITCH */ + CASE = 664, /* CASE */ + DEFAULT = 665, /* DEFAULT */ + TERMINATE_INVOCATION = 666, /* TERMINATE_INVOCATION */ + TERMINATE_RAY = 667, /* TERMINATE_RAY */ + IGNORE_INTERSECTION = 668, /* IGNORE_INTERSECTION */ + UNIFORM = 669, /* UNIFORM */ + SHARED = 670, /* SHARED */ + BUFFER = 671, /* BUFFER */ + TILEIMAGEEXT = 672, /* TILEIMAGEEXT */ + FLAT = 673, /* FLAT */ + SMOOTH = 674, /* SMOOTH */ + LAYOUT = 675, /* LAYOUT */ + DOUBLECONSTANT = 676, /* DOUBLECONSTANT */ + INT16CONSTANT = 677, /* INT16CONSTANT */ + UINT16CONSTANT = 678, /* UINT16CONSTANT */ + FLOAT16CONSTANT = 679, /* FLOAT16CONSTANT */ + INT32CONSTANT = 680, /* INT32CONSTANT */ + UINT32CONSTANT = 681, /* UINT32CONSTANT */ + INT64CONSTANT = 682, /* INT64CONSTANT */ + UINT64CONSTANT = 683, /* UINT64CONSTANT */ + SUBROUTINE = 684, /* SUBROUTINE */ + DEMOTE = 685, /* DEMOTE */ + PAYLOADNV = 686, /* PAYLOADNV */ + PAYLOADINNV = 687, /* PAYLOADINNV */ + HITATTRNV = 688, /* HITATTRNV */ + CALLDATANV = 689, /* CALLDATANV */ + CALLDATAINNV = 690, /* CALLDATAINNV */ + PAYLOADEXT = 691, /* PAYLOADEXT */ + PAYLOADINEXT = 692, /* PAYLOADINEXT */ + HITATTREXT = 693, /* HITATTREXT */ + CALLDATAEXT = 694, /* CALLDATAEXT */ + CALLDATAINEXT = 695, /* CALLDATAINEXT */ + PATCH = 696, /* PATCH */ + SAMPLE = 697, /* SAMPLE */ + NONUNIFORM = 698, /* NONUNIFORM */ + COHERENT = 699, /* COHERENT */ + VOLATILE = 700, /* VOLATILE */ + RESTRICT = 701, /* RESTRICT */ + READONLY = 702, /* READONLY */ + WRITEONLY = 703, /* WRITEONLY */ + DEVICECOHERENT = 704, /* DEVICECOHERENT */ + QUEUEFAMILYCOHERENT = 705, /* QUEUEFAMILYCOHERENT */ + WORKGROUPCOHERENT = 706, /* WORKGROUPCOHERENT */ + SUBGROUPCOHERENT = 707, /* SUBGROUPCOHERENT */ + NONPRIVATE = 708, /* NONPRIVATE */ + SHADERCALLCOHERENT = 709, /* SHADERCALLCOHERENT */ + NOPERSPECTIVE = 710, /* NOPERSPECTIVE */ + EXPLICITINTERPAMD = 711, /* EXPLICITINTERPAMD */ + PERVERTEXEXT = 712, /* PERVERTEXEXT */ + PERVERTEXNV = 713, /* PERVERTEXNV */ + PERPRIMITIVENV = 714, /* PERPRIMITIVENV */ + PERVIEWNV = 715, /* PERVIEWNV */ + PERTASKNV = 716, /* PERTASKNV */ + PERPRIMITIVEEXT = 717, /* PERPRIMITIVEEXT */ + TASKPAYLOADWORKGROUPEXT = 718, /* TASKPAYLOADWORKGROUPEXT */ + PRECISE = 719 /* PRECISE */ }; typedef enum yytokentype yytoken_kind_t; #endif @@ -514,7 +524,7 @@ extern int yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 97 "MachineIndependent/glslang.y" +#line 72 "MachineIndependent/glslang.y" struct { glslang::TSourceLoc loc; @@ -550,10 +560,10 @@ union YYSTYPE glslang::TArraySizes* arraySizes; glslang::TIdentifierList* identifierList; }; - glslang::TArraySizes* typeParameters; + glslang::TTypeParameters* typeParameters; } interm; -#line 557 "MachineIndependent/glslang_tab.cpp.h" +#line 567 "MachineIndependent/glslang_tab.cpp.h" }; typedef union YYSTYPE YYSTYPE; @@ -563,6 +573,8 @@ typedef union YYSTYPE YYSTYPE; + int yyparse (glslang::TParseContext* pParseContext); + #endif /* !YY_YY_MACHINEINDEPENDENT_GLSLANG_TAB_CPP_H_INCLUDED */ diff --git a/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp b/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp index d8a3aab5d..5b1414c94 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/intermOut.cpp @@ -36,8 +36,6 @@ // POSSIBILITY OF SUCH DAMAGE. // -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) - #include "localintermediate.h" #include "../Include/InfoSink.h" @@ -663,11 +661,13 @@ bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) case EOpSubpassLoad: out.debug << "subpassLoad"; break; case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break; + case EOpColorAttachmentReadEXT: out.debug << "colorAttachmentReadEXT"; break; + case EOpConstructReference: out.debug << "Construct reference type"; break; -#ifndef GLSLANG_WEB + case EOpDeclare: out.debug << "Declare"; break; + case EOpSpirvInst: out.debug << "spirv_instruction"; break; -#endif default: out.debug.message(EPrefixError, "Bad unary op"); } @@ -692,6 +692,7 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node switch (node->getOp()) { case EOpSequence: out.debug << "Sequence\n"; return true; + case EOpScope: out.debug << "Scope\n"; return true; case EOpLinkerObjects: out.debug << "Linker Objects\n"; return true; case EOpComma: out.debug << "Comma"; break; case EOpFunction: out.debug << "Function Definition: " << node->getName(); break; @@ -804,7 +805,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpConstructStruct: out.debug << "Construct structure"; break; case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break; case EOpConstructReference: out.debug << "Construct reference"; break; - case EOpConstructCooperativeMatrix: out.debug << "Construct cooperative matrix"; break; + case EOpConstructCooperativeMatrixNV: out.debug << "Construct cooperative matrix NV"; break; + case EOpConstructCooperativeMatrixKHR: out.debug << "Construct cooperative matrix KHR"; break; case EOpConstructAccStruct: out.debug << "Construct acceleration structure"; break; case EOpLessThan: out.debug << "Compare Less Than"; break; @@ -1057,6 +1059,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpSubpassLoad: out.debug << "subpassLoad"; break; case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break; + case EOpColorAttachmentReadEXT: out.debug << "colorAttachmentReadEXT"; break; + case EOpTraceNV: out.debug << "traceNV"; break; case EOpTraceRayMotionNV: out.debug << "traceRayMotionNV"; break; case EOpTraceKHR: out.debug << "traceRayKHR"; break; @@ -1068,6 +1072,8 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpExecuteCallableNV: out.debug << "executeCallableNV"; break; case EOpExecuteCallableKHR: out.debug << "executeCallableKHR"; break; case EOpWritePackedPrimitiveIndices4x8NV: out.debug << "writePackedPrimitiveIndices4x8NV"; break; + case EOpEmitMeshTasksEXT: out.debug << "EmitMeshTasksEXT"; break; + case EOpSetMeshOutputsEXT: out.debug << "SetMeshOutputsEXT"; break; case EOpRayQueryInitialize: out.debug << "rayQueryInitializeEXT"; break; case EOpRayQueryTerminate: out.debug << "rayQueryTerminateEXT"; break; @@ -1092,22 +1098,60 @@ bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node case EOpRayQueryGetWorldRayOrigin: out.debug << "rayQueryGetWorldRayOriginEXT"; break; case EOpRayQueryGetIntersectionObjectToWorld: out.debug << "rayQueryGetIntersectionObjectToWorldEXT"; break; case EOpRayQueryGetIntersectionWorldToObject: out.debug << "rayQueryGetIntersectionWorldToObjectEXT"; break; + case EOpRayQueryGetIntersectionTriangleVertexPositionsEXT: out.debug << "rayQueryGetIntersectionTriangleVertexPositionsEXT"; break; - case EOpCooperativeMatrixLoad: out.debug << "Load cooperative matrix"; break; - case EOpCooperativeMatrixStore: out.debug << "Store cooperative matrix"; break; - case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices"; break; + case EOpCooperativeMatrixLoad: out.debug << "Load cooperative matrix KHR"; break; + case EOpCooperativeMatrixStore: out.debug << "Store cooperative matrix KHR"; break; + case EOpCooperativeMatrixMulAdd: out.debug << "MulAdd cooperative matrices KHR"; break; + case EOpCooperativeMatrixLoadNV: out.debug << "Load cooperative matrix NV"; break; + case EOpCooperativeMatrixStoreNV: out.debug << "Store cooperative matrix NV"; break; + case EOpCooperativeMatrixMulAddNV: out.debug << "MulAdd cooperative matrices NV"; break; case EOpIsHelperInvocation: out.debug << "IsHelperInvocation"; break; case EOpDebugPrintf: out.debug << "Debug printf"; break; -#ifndef GLSLANG_WEB + case EOpHitObjectTraceRayNV: out.debug << "HitObjectTraceRayNV"; break; + case EOpHitObjectTraceRayMotionNV: out.debug << "HitObjectTraceRayMotionNV"; break; + case EOpHitObjectRecordHitNV: out.debug << "HitObjectRecordHitNV"; break; + case EOpHitObjectRecordHitMotionNV: out.debug << "HitObjectRecordHitMotionNV"; break; + case EOpHitObjectRecordHitWithIndexNV: out.debug << "HitObjectRecordHitWithIndexNV"; break; + case EOpHitObjectRecordHitWithIndexMotionNV: out.debug << "HitObjectRecordHitWithIndexMotionNV"; break; + case EOpHitObjectRecordMissNV: out.debug << "HitObjectRecordMissNV"; break; + case EOpHitObjectRecordMissMotionNV: out.debug << "HitObjectRecordMissMotionNV"; break; + case EOpHitObjectRecordEmptyNV: out.debug << "HitObjectRecordEmptyNV"; break; + case EOpHitObjectExecuteShaderNV: out.debug << "HitObjectExecuteShaderNV"; break; + case EOpHitObjectIsEmptyNV: out.debug << "HitObjectIsEmptyNV"; break; + case EOpHitObjectIsMissNV: out.debug << "HitObjectIsMissNV"; break; + case EOpHitObjectIsHitNV: out.debug << "HitObjectIsHitNV"; break; + case EOpHitObjectGetRayTMinNV: out.debug << "HitObjectGetRayTMinNV"; break; + case EOpHitObjectGetRayTMaxNV: out.debug << "HitObjectGetRayTMaxNV"; break; + case EOpHitObjectGetObjectRayOriginNV: out.debug << "HitObjectGetObjectRayOriginNV"; break; + case EOpHitObjectGetObjectRayDirectionNV: out.debug << "HitObjectGetObjectRayDirectionNV"; break; + case EOpHitObjectGetWorldRayOriginNV: out.debug << "HitObjectGetWorldRayOriginNV"; break; + case EOpHitObjectGetWorldRayDirectionNV: out.debug << "HitObjectGetWorldRayDirectionNV"; break; + case EOpHitObjectGetObjectToWorldNV: out.debug << "HitObjectGetObjectToWorldNV"; break; + case EOpHitObjectGetWorldToObjectNV: out.debug << "HitObjectGetWorldToObjectNV"; break; + case EOpHitObjectGetInstanceCustomIndexNV: out.debug<< "HitObjectGetInstanceCustomIndexNV"; break; + case EOpHitObjectGetInstanceIdNV: out.debug << "HitObjectGetInstaneIdNV"; break; + case EOpHitObjectGetGeometryIndexNV: out.debug << "HitObjectGetGeometryIndexNV"; break; + case EOpHitObjectGetPrimitiveIndexNV: out.debug << "HitObjectGetPrimitiveIndexNV"; break; + case EOpHitObjectGetHitKindNV: out.debug << "HitObjectGetHitKindNV"; break; + case EOpHitObjectGetAttributesNV: out.debug << "HitObjectGetAttributesNV"; break; + case EOpHitObjectGetCurrentTimeNV: out.debug << "HitObjectGetCurrentTimeNV"; break; + case EOpHitObjectGetShaderBindingTableRecordIndexNV: out.debug << "HitObjectGetShaderBindingTableRecordIndexNV"; break; + case EOpHitObjectGetShaderRecordBufferHandleNV: out.debug << "HitObjectReadShaderRecordBufferHandleNV"; break; + case EOpReorderThreadNV: out.debug << "ReorderThreadNV"; break; + case EOpFetchMicroTriangleVertexPositionNV: out.debug << "MicroTriangleVertexPositionNV"; break; + case EOpFetchMicroTriangleVertexBarycentricNV: out.debug << "MicroTriangleVertexBarycentricNV"; break; + case EOpSpirvInst: out.debug << "spirv_instruction"; break; -#endif + case EOpStencilAttachmentReadEXT: out.debug << "stencilAttachmentReadEXT"; break; + case EOpDepthAttachmentReadEXT: out.debug << "depthAttachmentReadEXT"; break; default: out.debug.message(EPrefixError, "Bad aggregation op"); } - if (node->getOp() != EOpSequence && node->getOp() != EOpParameters) + if (node->getOp() != EOpSequence && node->getOp() != EOpScope && node->getOp() != EOpParameters) out.debug << " (" << node->getCompleteString() << ")"; out.debug << "\n"; @@ -1164,12 +1208,12 @@ bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node // - shows all digits, no premature rounding static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraOutput extra) { - if (IsInfinity(value)) { + if (std::isinf(value)) { if (value < 0) out.debug << "-1.#INF"; else out.debug << "+1.#INF"; - } else if (IsNan(value)) + } else if (std::isnan(value)) out.debug << "1.#IND"; else { const int maxSize = 340; @@ -1507,6 +1551,12 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) infoSink.debug << "using early_fragment_tests\n"; if (postDepthCoverage) infoSink.debug << "using post_depth_coverage\n"; + if (nonCoherentColorAttachmentReadEXT) + infoSink.debug << "using non_coherent_color_attachment_readEXT\n"; + if (nonCoherentDepthAttachmentReadEXT) + infoSink.debug << "using non_coherent_depth_attachment_readEXT\n"; + if (nonCoherentStencilAttachmentReadEXT) + infoSink.debug << "using non_coherent_stencil_attachment_readEXT\n"; if (depthLayout != EldNone) infoSink.debug << "using " << TQualifier::getLayoutDepthString(depthLayout) << "\n"; if (blendEquations != 0) { @@ -1522,12 +1572,12 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) infoSink.debug << "interlock ordering = " << TQualifier::getInterlockOrderingString(interlockOrdering) << "\n"; break; - case EShLangMeshNV: + case EShLangMesh: infoSink.debug << "max_vertices = " << vertices << "\n"; infoSink.debug << "max_primitives = " << primitives << "\n"; infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n"; // Fall through - case EShLangTaskNV: + case EShLangTask: // Fall through case EShLangCompute: infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n"; @@ -1547,7 +1597,7 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) break; } - if (treeRoot == 0 || ! tree) + if (treeRoot == nullptr || ! tree) return; TOutputTraverser it(infoSink); @@ -1557,5 +1607,3 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree) } } // end namespace glslang - -#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp b/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp index a3c53f505..ed853256b 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/iomapper.cpp @@ -33,8 +33,6 @@ // POSSIBILITY OF SUCH DAMAGE. // -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) - #include "../Include/Common.h" #include "../Include/InfoSink.h" #include "../Include/Types.h" @@ -145,6 +143,8 @@ class TVarSetTraverser : public TLiveTraverser base->getWritableType().getQualifier().layoutComponent = at->second.newComponent; if (at->second.newIndex != -1) base->getWritableType().getQualifier().layoutIndex = at->second.newIndex; + if (at->second.upgradedToPushConstant) + base->getWritableType().getQualifier().layoutPushConstant = true; } private: @@ -203,11 +203,7 @@ struct TResolverUniformAdaptor { inline void operator()(std::pair& entKey) { TVarEntryInfo& ent = entKey.second; - ent.newLocation = -1; - ent.newComponent = -1; - ent.newBinding = -1; - ent.newSet = -1; - ent.newIndex = -1; + ent.clearNewAssignments(); const bool isValid = resolver.validateBinding(stage, ent); if (isValid) { resolver.resolveSet(ent.stage, ent); @@ -281,11 +277,7 @@ struct TResolverInOutAdaptor { inline void operator()(std::pair& entKey) { TVarEntryInfo& ent = entKey.second; - ent.newLocation = -1; - ent.newComponent = -1; - ent.newBinding = -1; - ent.newSet = -1; - ent.newIndex = -1; + ent.clearNewAssignments(); const bool isValid = resolver.validateInOut(ent.stage, ent); if (isValid) { resolver.resolveInOutLocation(stage, ent); @@ -874,7 +866,7 @@ int TDefaultIoResolverBase::resolveInOutLocation(EShLanguage stage, TVarEntryInf } // no locations added if already present, a built-in variable, or a variable with SPIR-V decorate - if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) { + if (type.getQualifier().hasLocation() || type.isBuiltIn() || type.getQualifier().hasSpirvDecorate()) { return ent.newLocation = -1; } @@ -961,7 +953,7 @@ int TDefaultGlslIoResolver::resolveInOutLocation(EShLanguage stage, TVarEntryInf return ent.newLocation = type.getQualifier().layoutLocation; } // no locations added if already present, a built-in variable, or a variable with SPIR-V decorate - if (type.isBuiltIn() || type.getQualifier().hasSprivDecorate()) { + if (type.isBuiltIn() || type.getQualifier().hasSpirvDecorate()) { return ent.newLocation = -1; } // no locations on blocks of built-in variables @@ -1670,31 +1662,42 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) { if (size <= int(autoPushConstantMaxSize)) { qualifier.setBlockStorage(EbsPushConstant); qualifier.layoutPacking = autoPushConstantBlockPacking; + // Push constants don't have set/binding etc. decorations, remove those. + qualifier.layoutSet = TQualifier::layoutSetEnd; + at->second.clearNewAssignments(); + upgraded = true; } } } - // If it's been upgraded to push_constant, then remove it from the uniformVector + // If it's been upgraded to push_constant, then set the flag so when its traversed + // in the next for loop, all references to this symbol will get their flag changed. // so it doesn't get a set/binding assigned to it. if (upgraded) { - auto at = std::find_if(uniformVector.begin(), uniformVector.end(), - [this](const TVarLivePair& p) { return p.first == autoPushConstantBlockName; }); - if (at != uniformVector.end()) - uniformVector.erase(at); + std::for_each(uniformVector.begin(), uniformVector.end(), + [this](TVarLivePair& p) { + if (p.first == autoPushConstantBlockName) { + p.second.upgradedToPushConstant = true; + } + }); } } for (size_t stage = 0; stage < EShLangCount; stage++) { if (intermediates[stage] != nullptr) { // traverse each stage, set new location to each input/output and unifom symbol, set new binding to - // ubo, ssbo and opaque symbols + // ubo, ssbo and opaque symbols. Assign push_constant upgrades as well. TVarLiveMap** pUniformVarMap = uniformResolve.uniformVarMap; std::for_each(uniformVector.begin(), uniformVector.end(), [pUniformVarMap, stage](TVarLivePair p) { auto at = pUniformVarMap[stage]->find(p.second.symbol->getAccessName()); if (at != pUniformVarMap[stage]->end() && at->second.id == p.second.id){ - int resolvedBinding = at->second.newBinding; - at->second = p.second; - if (resolvedBinding > 0) - at->second.newBinding = resolvedBinding; + if (p.second.upgradedToPushConstant) { + at->second.upgradedToPushConstant = true; + } else { + int resolvedBinding = at->second.newBinding; + at->second = p.second; + if (resolvedBinding > 0) + at->second.newBinding = resolvedBinding; + } } }); TVarSetTraverser iter_iomap(*intermediates[stage], *inVarMaps[stage], *outVarMaps[stage], @@ -1709,5 +1712,3 @@ bool TGlslIoMapper::doMap(TIoMapResolver* resolver, TInfoSink& infoSink) { } } // end namespace glslang - -#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/src/libraries/glslang/glslang/MachineIndependent/iomapper.h b/src/libraries/glslang/glslang/MachineIndependent/iomapper.h index c43864e3a..35babbce1 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/iomapper.h +++ b/src/libraries/glslang/glslang/MachineIndependent/iomapper.h @@ -33,8 +33,6 @@ // POSSIBILITY OF SUCH DAMAGE. // -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) - #ifndef _IOMAPPER_INCLUDED #define _IOMAPPER_INCLUDED @@ -55,12 +53,23 @@ struct TVarEntryInfo { long long id; TIntermSymbol* symbol; bool live; + bool upgradedToPushConstant; int newBinding; int newSet; int newLocation; int newComponent; int newIndex; EShLanguage stage; + + void clearNewAssignments() { + upgradedToPushConstant = false; + newBinding = -1; + newSet = -1; + newLocation = -1; + newComponent = -1; + newIndex = -1; + } + struct TOrderById { inline bool operator()(const TVarEntryInfo& l, const TVarEntryInfo& r) { return l.id < r.id; } }; @@ -348,5 +357,3 @@ class TGlslIoMapper : public TIoMapper { } // end namespace glslang #endif // _IOMAPPER_INCLUDED - -#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/src/libraries/glslang/glslang/MachineIndependent/limits.cpp b/src/libraries/glslang/glslang/MachineIndependent/limits.cpp index 391570579..4404beca4 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/limits.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/limits.cpp @@ -187,14 +187,12 @@ bool TIndexTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) // void TParseContext::constantIndexExpressionCheck(TIntermNode* index) { -#ifndef GLSLANG_WEB TIndexTraverser it(inductiveLoopIds); index->traverse(&it); if (it.bad) error(it.badLoc, "Non-constant-index-expression", "limitations", ""); -#endif } } // end namespace glslang diff --git a/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp b/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp index 1fc7d1f14..d69300b84 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/linkValidate.cpp @@ -55,23 +55,25 @@ namespace glslang { // // Link-time error emitter. // -void TIntermediate::error(TInfoSink& infoSink, const char* message) +void TIntermediate::error(TInfoSink& infoSink, const char* message, EShLanguage unitStage) { -#ifndef GLSLANG_WEB infoSink.info.prefix(EPrefixError); - infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; -#endif + if (unitStage < EShLangCount) + infoSink.info << "Linking " << StageName(getStage()) << " and " << StageName(unitStage) << " stages: " << message << "\n"; + else + infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; ++numErrors; } // Link-time warning. -void TIntermediate::warn(TInfoSink& infoSink, const char* message) +void TIntermediate::warn(TInfoSink& infoSink, const char* message, EShLanguage unitStage) { -#ifndef GLSLANG_WEB infoSink.info.prefix(EPrefixWarning); - infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; -#endif + if (unitStage < EShLangCount) + infoSink.info << "Linking " << StageName(language) << " and " << StageName(unitStage) << " stages: " << message << "\n"; + else + infoSink.info << "Linking " << StageName(language) << " stage: " << message << "\n"; } // TODO: 4.4 offset/align: "Two blocks linked together in the same program with the same block @@ -83,11 +85,9 @@ void TIntermediate::warn(TInfoSink& infoSink, const char* message) // void TIntermediate::merge(TInfoSink& infoSink, TIntermediate& unit) { -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) mergeCallGraphs(infoSink, unit); mergeModes(infoSink, unit); mergeTrees(infoSink, unit); -#endif } // @@ -114,7 +114,7 @@ void TIntermediate::mergeUniformObjects(TInfoSink& infoSink, TIntermediate& unit } // -// do error checking on the shader boundary in / out vars +// do error checking on the shader boundary in / out vars // void TIntermediate::checkStageIO(TInfoSink& infoSink, TIntermediate& unit) { if (unit.treeRoot == nullptr || treeRoot == nullptr) @@ -155,8 +155,6 @@ void TIntermediate::mergeCallGraphs(TInfoSink& infoSink, TIntermediate& unit) callGraph.insert(callGraph.end(), unit.callGraph.begin(), unit.callGraph.end()); } -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) - #define MERGE_MAX(member) member = std::max(member, unit.member) #define MERGE_TRUE(member) if (unit.member) member = unit.member; @@ -206,7 +204,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) if (vertices == TQualifier::layoutNotSet) vertices = unit.vertices; else if (unit.vertices != TQualifier::layoutNotSet && vertices != unit.vertices) { - if (language == EShLangGeometry || language == EShLangMeshNV) + if (language == EShLangGeometry || language == EShLangMesh) error(infoSink, "Contradictory layout max_vertices values"); else if (language == EShLangTessControl) error(infoSink, "Contradictory layout vertices values"); @@ -216,7 +214,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) if (primitives == TQualifier::layoutNotSet) primitives = unit.primitives; else if (primitives != unit.primitives) { - if (language == EShLangMeshNV) + if (language == EShLangMesh) error(infoSink, "Contradictory layout max_primitives values"); else assert(0); @@ -265,6 +263,9 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) MERGE_TRUE(earlyFragmentTests); MERGE_TRUE(postDepthCoverage); + MERGE_TRUE(nonCoherentColorAttachmentReadEXT); + MERGE_TRUE(nonCoherentDepthAttachmentReadEXT); + MERGE_TRUE(nonCoherentStencilAttachmentReadEXT); if (depthLayout == EldNone) depthLayout = unit.depthLayout; @@ -313,6 +314,7 @@ void TIntermediate::mergeModes(TInfoSink& infoSink, TIntermediate& unit) MERGE_TRUE(autoMapLocations); MERGE_TRUE(invertY); MERGE_TRUE(dxPositionW); + MERGE_TRUE(debugInfo); MERGE_TRUE(flattenUniformArrays); MERGE_TRUE(useUnknownFormat); MERGE_TRUE(hlslOffsets); @@ -371,8 +373,6 @@ void TIntermediate::mergeTrees(TInfoSink& infoSink, TIntermediate& unit) ioAccessed.insert(unit.ioAccessed.begin(), unit.ioAccessed.end()); } -#endif - static const TString& getNameForIdMap(TIntermSymbol* symbol) { TShaderInterface si = symbol->getType().getShaderInterface(); @@ -580,9 +580,6 @@ void TIntermediate::mergeGlobalUniformBlocks(TInfoSink& infoSink, TIntermediate& } void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* block, TIntermSymbol* unitBlock, TIntermediate* unit) { - if (block->getType() == unitBlock->getType()) { - return; - } if (block->getType().getTypeName() != unitBlock->getType().getTypeName() || block->getType().getBasicType() != unitBlock->getType().getBasicType() || @@ -629,44 +626,42 @@ void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* bl } } - TType unitType; - unitType.shallowCopy(unitBlock->getType()); - // update symbol node in unit tree, // and other nodes that may reference it class TMergeBlockTraverser : public TIntermTraverser { public: - TMergeBlockTraverser(const glslang::TType &type, const glslang::TType& unitType, - glslang::TIntermediate& unit, - const std::map& memberIdxUpdates) : - newType(type), unitType(unitType), unit(unit), memberIndexUpdates(memberIdxUpdates) - { } - virtual ~TMergeBlockTraverser() { } - - const glslang::TType& newType; // type with modifications - const glslang::TType& unitType; // copy of original type - glslang::TIntermediate& unit; // intermediate that is being updated - const std::map& memberIndexUpdates; - - virtual void visitSymbol(TIntermSymbol* symbol) + TMergeBlockTraverser(const TIntermSymbol* newSym) + : newSymbol(newSym), newType(nullptr), unit(nullptr), memberIndexUpdates(nullptr) { - glslang::TType& symType = symbol->getWritableType(); + } + TMergeBlockTraverser(const TIntermSymbol* newSym, const glslang::TType* unitType, glslang::TIntermediate* unit, + const std::map* memberIdxUpdates) + : TIntermTraverser(false, true), newSymbol(newSym), newType(unitType), unit(unit), memberIndexUpdates(memberIdxUpdates) + { + } + virtual ~TMergeBlockTraverser() {} - if (symType == unitType) { - // each symbol node has a local copy of the unitType - // if merging involves changing properties that aren't shared objects - // they should be updated in all instances + const TIntermSymbol* newSymbol; + const glslang::TType* newType; // shallow copy of the new type + glslang::TIntermediate* unit; // intermediate that is being updated + const std::map* memberIndexUpdates; - // e.g. the struct list is a ptr to an object, so it can be updated - // once, outside the traverser - //*symType.getWritableStruct() = *newType.getStruct(); + virtual void visitSymbol(TIntermSymbol* symbol) + { + if (newSymbol->getAccessName() == symbol->getAccessName() && + newSymbol->getQualifier().getBlockStorage() == symbol->getQualifier().getBlockStorage()) { + // Each symbol node may have a local copy of the block structure. + // Update those structures to match the new one post-merge + *(symbol->getWritableType().getWritableStruct()) = *(newSymbol->getType().getStruct()); } - } virtual bool visitBinary(TVisit, glslang::TIntermBinary* node) { - if (node->getOp() == EOpIndexDirectStruct && node->getLeft()->getType() == unitType) { + if (!unit || !newType || !memberIndexUpdates || memberIndexUpdates->empty()) + return true; + + if (node->getOp() == EOpIndexDirectStruct && node->getLeft()->getType() == *newType) { // this is a dereference to a member of the block since the // member list changed, need to update this to point to the // right index @@ -674,8 +669,8 @@ void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* bl glslang::TIntermConstantUnion* constNode = node->getRight()->getAsConstantUnion(); unsigned int memberIdx = constNode->getConstArray()[0].getUConst(); - unsigned int newIdx = memberIndexUpdates.at(memberIdx); - TIntermTyped* newConstNode = unit.addConstantUnion(newIdx, node->getRight()->getLoc()); + unsigned int newIdx = memberIndexUpdates->at(memberIdx); + TIntermTyped* newConstNode = unit->addConstantUnion(newIdx, node->getRight()->getLoc()); node->setRight(newConstNode); delete constNode; @@ -684,10 +679,20 @@ void TIntermediate::mergeBlockDefinitions(TInfoSink& infoSink, TIntermSymbol* bl } return true; } - } finalLinkTraverser(block->getType(), unitType, *unit, memberIndexUpdates); + }; - // update the tree to use the new type - unit->getTreeRoot()->traverse(&finalLinkTraverser); + // 'this' may have symbols that are using the old block structure, so traverse the tree to update those + // in 'visitSymbol' + TMergeBlockTraverser finalLinkTraverser(block); + getTreeRoot()->traverse(&finalLinkTraverser); + + // The 'unit' intermediate needs the block structures update, but also structure entry indices + // may have changed from the old block to the new one that it was merged into, so update those + // in 'visitBinary' + TType newType; + newType.shallowCopy(block->getType()); + TMergeBlockTraverser unitFinalLinkTraverser(block, &newType, unit, &memberIndexUpdates); + unit->getTreeRoot()->traverse(&unitFinalLinkTraverser); // update the member list (*unitMemberList) = (*memberList); @@ -737,6 +742,21 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin symbol->getQualifier().layoutLocation = unitSymbol->getQualifier().layoutLocation; } + // Update implicit array sizes + if (symbol->getWritableType().isImplicitlySizedArray() && unitSymbol->getType().isImplicitlySizedArray()) { + if (unitSymbol->getType().getImplicitArraySize() > symbol->getType().getImplicitArraySize()){ + symbol->getWritableType().updateImplicitArraySize(unitSymbol->getType().getImplicitArraySize()); + } + } + else if (symbol->getWritableType().isImplicitlySizedArray() && unitSymbol->getType().isSizedArray()) { + if (symbol->getWritableType().getImplicitArraySize() > unitSymbol->getType().getOuterArraySize()) + error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders."); + } + else if (unitSymbol->getType().isImplicitlySizedArray() && symbol->getWritableType().isSizedArray()) { + if (unitSymbol->getType().getImplicitArraySize() > symbol->getWritableType().getOuterArraySize()) + error(infoSink, "Implicit size of unsized array doesn't match same symbol among multiple shaders."); + } + // Update implicit array sizes mergeImplicitArraySizes(symbol->getWritableType(), unitSymbol->getType()); @@ -747,6 +767,19 @@ void TIntermediate::mergeLinkerObjects(TInfoSink& infoSink, TIntermSequence& lin else if (symbol->getQualifier().isPushConstant() && unitSymbol->getQualifier().isPushConstant() && getStage() == unitStage) error(infoSink, "Only one push_constant block is allowed per stage"); } + + // Check conflicts between preset primitives and sizes of I/O variables among multiple geometry shaders + if (language == EShLangGeometry && unitStage == EShLangGeometry) + { + TIntermSymbol* unitSymbol = unitLinkerObjects[unitLinkObj]->getAsSymbolNode(); + if (unitSymbol->isArray() && unitSymbol->getQualifier().storage == EvqVaryingIn && unitSymbol->getQualifier().builtIn == EbvNone) + if ((unitSymbol->getArraySizes()->isImplicitlySized() && + unitSymbol->getArraySizes()->getImplicitSize() != TQualifier::mapGeometryToSize(getInputPrimitive())) || + (! unitSymbol->getArraySizes()->isImplicitlySized() && + unitSymbol->getArraySizes()->getDimSize(0) != TQualifier::mapGeometryToSize(getInputPrimitive()))) + error(infoSink, "Not all array sizes match across all geometry shaders in the program"); + } + if (merge) { linkerObjects.push_back(unitLinkerObjects[unitLinkObj]); @@ -816,9 +849,12 @@ void TIntermediate::mergeImplicitArraySizes(TType& type, const TType& unitType) // void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& symbol, const TIntermSymbol& unitSymbol, EShLanguage unitStage) { -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) bool crossStage = getStage() != unitStage; bool writeTypeComparison = false; + bool errorReported = false; + bool printQualifiers = false; + bool printPrecision = false; + bool printType = false; // Types have to match { @@ -847,14 +883,52 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy else { arraysMatch = symbol.getType().sameArrayness(unitSymbol.getType()) || (symbol.getType().isArray() && unitSymbol.getType().isArray() && - (symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray())); + (symbol.getType().isImplicitlySizedArray() || unitSymbol.getType().isImplicitlySizedArray() || + symbol.getType().isUnsizedArray() || unitSymbol.getType().isUnsizedArray())); } - if (!symbol.getType().sameElementType(unitSymbol.getType()) || - !symbol.getType().sameTypeParameters(unitSymbol.getType()) || - !arraysMatch ) { + int lpidx = -1; + int rpidx = -1; + if (!symbol.getType().sameElementType(unitSymbol.getType(), &lpidx, &rpidx)) { + if (lpidx >= 0 && rpidx >= 0) { + error(infoSink, "Member names and types must match:", unitStage); + infoSink.info << " Block: " << symbol.getType().getTypeName() << "\n"; + infoSink.info << " " << StageName(getStage()) << " stage: \"" + << (*symbol.getType().getStruct())[lpidx].type->getCompleteString(true, false, false, true, + (*symbol.getType().getStruct())[lpidx].type->getFieldName()) << "\"\n"; + infoSink.info << " " << StageName(unitStage) << " stage: \"" + << (*unitSymbol.getType().getStruct())[rpidx].type->getCompleteString(true, false, false, true, + (*unitSymbol.getType().getStruct())[rpidx].type->getFieldName()) << "\"\n"; + errorReported = true; + } else if (lpidx >= 0 && rpidx == -1) { + TString errmsg = StageName(getStage()); + errmsg.append(" block member has no corresponding member in ").append(StageName(unitStage)).append(" block:"); + error(infoSink, errmsg.c_str(), unitStage); + infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: " + << (*symbol.getType().getStruct())[lpidx].type->getFieldName() << "\n"; + infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: n/a \n"; + errorReported = true; + } else if (lpidx == -1 && rpidx >= 0) { + TString errmsg = StageName(unitStage); + errmsg.append(" block member has no corresponding member in ").append(StageName(getStage())).append(" block:"); + error(infoSink, errmsg.c_str(), unitStage); + infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: " + << (*unitSymbol.getType().getStruct())[rpidx].type->getFieldName() << "\n"; + infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: n/a \n"; + errorReported = true; + } else { + error(infoSink, "Types must match:", unitStage); + writeTypeComparison = true; + printType = true; + } + } else if (!arraysMatch) { + error(infoSink, "Array sizes must be compatible:", unitStage); + writeTypeComparison = true; + printType = true; + } else if (!symbol.getType().sameTypeParameters(unitSymbol.getType())) { + error(infoSink, "Type parameters must match:", unitStage); writeTypeComparison = true; - error(infoSink, "Types must match:"); + printType = true; } } @@ -875,13 +949,35 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy } const TQualifier& qualifier = (*symbol.getType().getStruct())[li].type->getQualifier(); const TQualifier & unitQualifier = (*unitSymbol.getType().getStruct())[ri].type->getQualifier(); - if (qualifier.layoutMatrix != unitQualifier.layoutMatrix || - qualifier.layoutOffset != unitQualifier.layoutOffset || - qualifier.layoutAlign != unitQualifier.layoutAlign || - qualifier.layoutLocation != unitQualifier.layoutLocation || - qualifier.layoutComponent != unitQualifier.layoutComponent) { - error(infoSink, "Interface block member layout qualifiers must match:"); - writeTypeComparison = true; + bool layoutQualifierError = false; + if (qualifier.layoutMatrix != unitQualifier.layoutMatrix) { + error(infoSink, "Interface block member layout matrix qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (qualifier.layoutOffset != unitQualifier.layoutOffset) { + error(infoSink, "Interface block member layout offset qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (qualifier.layoutAlign != unitQualifier.layoutAlign) { + error(infoSink, "Interface block member layout align qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (qualifier.layoutLocation != unitQualifier.layoutLocation) { + error(infoSink, "Interface block member layout location qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (qualifier.layoutComponent != unitQualifier.layoutComponent) { + error(infoSink, "Interface block member layout component qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (layoutQualifierError) { + infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << ", Member: " + << (*symbol.getType().getStruct())[li].type->getFieldName() << " \"" + << (*symbol.getType().getStruct())[li].type->getCompleteString(true, true, false, false) << "\"\n"; + infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << ", Member: " + << (*unitSymbol.getType().getStruct())[ri].type->getFieldName() << " \"" + << (*unitSymbol.getType().getStruct())[ri].type->getCompleteString(true, true, false, false) << "\"\n"; + errorReported = true; } ++li; ++ri; @@ -895,8 +991,9 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy // Qualifiers have to (almost) match // Storage... if (!isInOut && symbol.getQualifier().storage != unitSymbol.getQualifier().storage) { - error(infoSink, "Storage qualifiers must match:"); + error(infoSink, "Storage qualifiers must match:", unitStage); writeTypeComparison = true; + printQualifiers = true; } // Uniform and buffer blocks must either both have an instance name, or @@ -904,37 +1001,40 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy if (symbol.getQualifier().isUniformOrBuffer() && (IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()))) { error(infoSink, "Matched Uniform or Storage blocks must all be anonymous," - " or all be named:"); + " or all be named:", unitStage); writeTypeComparison = true; } if (symbol.getQualifier().storage == unitSymbol.getQualifier().storage && (IsAnonymous(symbol.getName()) != IsAnonymous(unitSymbol.getName()) || (!IsAnonymous(symbol.getName()) && symbol.getName() != unitSymbol.getName()))) { - warn(infoSink, "Matched shader interfaces are using different instance names."); + warn(infoSink, "Matched shader interfaces are using different instance names.", unitStage); writeTypeComparison = true; } // Precision... if (!isInOut && symbol.getQualifier().precision != unitSymbol.getQualifier().precision) { - error(infoSink, "Precision qualifiers must match:"); + error(infoSink, "Precision qualifiers must match:", unitStage); writeTypeComparison = true; + printPrecision = true; } // Invariance... if (! crossStage && symbol.getQualifier().invariant != unitSymbol.getQualifier().invariant) { - error(infoSink, "Presence of invariant qualifier must match:"); + error(infoSink, "Presence of invariant qualifier must match:", unitStage); writeTypeComparison = true; + printQualifiers = true; } // Precise... if (! crossStage && symbol.getQualifier().isNoContraction() != unitSymbol.getQualifier().isNoContraction()) { - error(infoSink, "Presence of precise qualifier must match:"); + error(infoSink, "Presence of precise qualifier must match:", unitStage); writeTypeComparison = true; + printPrecision = true; } // Auxiliary and interpolation... - // "interpolation qualification (e.g., flat) and auxiliary qualification (e.g. centroid) may differ. + // "interpolation qualification (e.g., flat) and auxiliary qualification (e.g. centroid) may differ. // These mismatches are allowed between any pair of stages ... // those provided in the fragment shader supersede those provided in previous stages." if (!crossStage && @@ -944,59 +1044,138 @@ void TIntermediate::mergeErrorCheck(TInfoSink& infoSink, const TIntermSymbol& sy symbol.getQualifier().isSample()!= unitSymbol.getQualifier().isSample() || symbol.getQualifier().isPatch() != unitSymbol.getQualifier().isPatch() || symbol.getQualifier().isNonPerspective() != unitSymbol.getQualifier().isNonPerspective())) { - error(infoSink, "Interpolation and auxiliary storage qualifiers must match:"); + error(infoSink, "Interpolation and auxiliary storage qualifiers must match:", unitStage); writeTypeComparison = true; + printQualifiers = true; } // Memory... - if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent || - symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent || - symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent || - symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent || - symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent || - symbol.getQualifier().shadercallcoherent!= unitSymbol.getQualifier().shadercallcoherent || - symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate || - symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil || - symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict || - symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly || - symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) { - error(infoSink, "Memory qualifiers must match:"); - writeTypeComparison = true; + bool memoryQualifierError = false; + if (symbol.getQualifier().coherent != unitSymbol.getQualifier().coherent) { + error(infoSink, "Memory coherent qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().devicecoherent != unitSymbol.getQualifier().devicecoherent) { + error(infoSink, "Memory devicecoherent qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().queuefamilycoherent != unitSymbol.getQualifier().queuefamilycoherent) { + error(infoSink, "Memory queuefamilycoherent qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().workgroupcoherent != unitSymbol.getQualifier().workgroupcoherent) { + error(infoSink, "Memory workgroupcoherent qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().subgroupcoherent != unitSymbol.getQualifier().subgroupcoherent) { + error(infoSink, "Memory subgroupcoherent qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().shadercallcoherent != unitSymbol.getQualifier().shadercallcoherent) { + error(infoSink, "Memory shadercallcoherent qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().nonprivate != unitSymbol.getQualifier().nonprivate) { + error(infoSink, "Memory nonprivate qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().volatil != unitSymbol.getQualifier().volatil) { + error(infoSink, "Memory volatil qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().restrict != unitSymbol.getQualifier().restrict) { + error(infoSink, "Memory restrict qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().readonly != unitSymbol.getQualifier().readonly) { + error(infoSink, "Memory readonly qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (symbol.getQualifier().writeonly != unitSymbol.getQualifier().writeonly) { + error(infoSink, "Memory writeonly qualifier must match:", unitStage); + memoryQualifierError = true; + } + if (memoryQualifierError) { + writeTypeComparison = true; + printQualifiers = true; } // Layouts... // TODO: 4.4 enhanced layouts: Generalize to include offset/align: current spec // requires separate user-supplied offset from actual computed offset, but // current implementation only has one offset. - if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix || - symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking || - (symbol.getQualifier().hasLocation() && unitSymbol.getQualifier().hasLocation() && symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation) || - symbol.getQualifier().layoutComponent != unitSymbol.getQualifier().layoutComponent || - symbol.getQualifier().layoutIndex != unitSymbol.getQualifier().layoutIndex || - (symbol.getQualifier().hasBinding() && unitSymbol.getQualifier().hasBinding() && symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding) || - (symbol.getQualifier().hasBinding() && (symbol.getQualifier().layoutOffset != unitSymbol.getQualifier().layoutOffset))) { - error(infoSink, "Layout qualification must match:"); + bool layoutQualifierError = false; + if (symbol.getQualifier().layoutMatrix != unitSymbol.getQualifier().layoutMatrix) { + error(infoSink, "Layout matrix qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (symbol.getQualifier().layoutPacking != unitSymbol.getQualifier().layoutPacking) { + error(infoSink, "Layout packing qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (symbol.getQualifier().hasLocation() && unitSymbol.getQualifier().hasLocation() && symbol.getQualifier().layoutLocation != unitSymbol.getQualifier().layoutLocation) { + error(infoSink, "Layout location qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (symbol.getQualifier().layoutComponent != unitSymbol.getQualifier().layoutComponent) { + error(infoSink, "Layout component qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (symbol.getQualifier().layoutIndex != unitSymbol.getQualifier().layoutIndex) { + error(infoSink, "Layout index qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (symbol.getQualifier().hasBinding() && unitSymbol.getQualifier().hasBinding() && symbol.getQualifier().layoutBinding != unitSymbol.getQualifier().layoutBinding) { + error(infoSink, "Layout binding qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (symbol.getQualifier().hasBinding() && (symbol.getQualifier().layoutOffset != unitSymbol.getQualifier().layoutOffset)) { + error(infoSink, "Layout offset qualifier must match:", unitStage); + layoutQualifierError = true; + } + if (layoutQualifierError) { writeTypeComparison = true; + printQualifiers = true; } // Initializers have to match, if both are present, and if we don't already know the types don't match - if (! writeTypeComparison) { + if (! writeTypeComparison && ! errorReported) { if (! symbol.getConstArray().empty() && ! unitSymbol.getConstArray().empty()) { if (symbol.getConstArray() != unitSymbol.getConstArray()) { - error(infoSink, "Initializers must match:"); + error(infoSink, "Initializers must match:", unitStage); infoSink.info << " " << symbol.getName() << "\n"; } } } if (writeTypeComparison) { - infoSink.info << " " << symbol.getName() << ": \"" << symbol.getType().getCompleteString() << "\" versus "; - if (symbol.getName() != unitSymbol.getName()) - infoSink.info << unitSymbol.getName() << ": "; - - infoSink.info << "\"" << unitSymbol.getType().getCompleteString() << "\"\n"; + if (symbol.getType().getBasicType() == EbtBlock && unitSymbol.getType().getBasicType() == EbtBlock && + symbol.getType().getStruct() && unitSymbol.getType().getStruct()) { + if (printType) { + infoSink.info << " " << StageName(getStage()) << " stage: \"" << symbol.getType().getCompleteString(true, printQualifiers, printPrecision, + printType, symbol.getName(), symbol.getType().getTypeName()) << "\"\n"; + infoSink.info << " " << StageName(unitStage) << " stage: \"" << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, + printType, unitSymbol.getName(), unitSymbol.getType().getTypeName()) << "\"\n"; + } else { + infoSink.info << " " << StageName(getStage()) << " stage: Block: " << symbol.getType().getTypeName() << " Instance: " << symbol.getName() + << ": \"" << symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n"; + infoSink.info << " " << StageName(unitStage) << " stage: Block: " << unitSymbol.getType().getTypeName() << " Instance: " << unitSymbol.getName() + << ": \"" << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n"; + } + } else { + if (printType) { + infoSink.info << " " << StageName(getStage()) << " stage: \"" + << symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType, symbol.getName()) << "\"\n"; + infoSink.info << " " << StageName(unitStage) << " stage: \"" + << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType, unitSymbol.getName()) << "\"\n"; + } else { + infoSink.info << " " << StageName(getStage()) << " stage: " << symbol.getName() << " \"" + << symbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n"; + infoSink.info << " " << StageName(unitStage) << " stage: " << unitSymbol.getName() << " \"" + << unitSymbol.getType().getCompleteString(true, printQualifiers, printPrecision, printType) << "\"\n"; + } + } } -#endif } void TIntermediate::sharedBlockCheck(TInfoSink& infoSink) @@ -1043,7 +1222,6 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) // overlap/alias/missing I/O, etc. inOutLocationCheck(infoSink); -#ifndef GLSLANG_WEB if (getNumPushConstants() > 1) error(infoSink, "Only one push_constant block is allowed per stage"); @@ -1136,8 +1314,8 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) error(infoSink, "At least one shader must specify a layout(max_vertices = value)"); break; case EShLangFragment: - // for GL_ARB_post_depth_coverage, EarlyFragmentTest is set automatically in - // ParseHelper.cpp. So if we reach here, this must be GL_EXT_post_depth_coverage + // for GL_ARB_post_depth_coverage, EarlyFragmentTest is set automatically in + // ParseHelper.cpp. So if we reach here, this must be GL_EXT_post_depth_coverage // requiring explicit early_fragment_tests if (getPostDepthCoverage() && !getEarlyFragmentTests()) error(infoSink, "post_depth_coverage requires early_fragment_tests"); @@ -1154,7 +1332,7 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) if (numShaderRecordBlocks > 1) error(infoSink, "Only one shaderRecordNV buffer block is allowed per stage"); break; - case EShLangMeshNV: + case EShLangMesh: // NV_mesh_shader doesn't allow use of both single-view and per-view builtins. if (inIoAccessed("gl_Position") && inIoAccessed("gl_PositionPerViewNV")) error(infoSink, "Can only use one of gl_Position or gl_PositionPerViewNV"); @@ -1173,9 +1351,11 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) if (primitives == TQualifier::layoutNotSet) error(infoSink, "At least one shader must specify a layout(max_primitives = value)"); // fall through - case EShLangTaskNV: + case EShLangTask: if (numTaskNVBlocks > 1) error(infoSink, "Only one taskNV interface block is allowed per shader"); + if (numTaskEXTPayloads > 1) + error(infoSink, "Only single variable of type taskPayloadSharedEXT is allowed per shader"); sharedBlockCheck(infoSink); break; default: @@ -1199,7 +1379,6 @@ void TIntermediate::finalCheck(TInfoSink& infoSink, bool keepUncalled) } finalLinkTraverser; treeRoot->traverse(&finalLinkTraverser); -#endif } // @@ -1222,7 +1401,7 @@ void TIntermediate::checkCallGraphCycles(TInfoSink& infoSink) TCall* newRoot; do { // See if we have unvisited parts of the graph. - newRoot = 0; + newRoot = nullptr; for (TGraph::iterator call = callGraph.begin(); call != callGraph.end(); ++call) { if (! call->visited) { newRoot = &(*call); @@ -1356,7 +1535,10 @@ void TIntermediate::checkCallGraphBodies(TInfoSink& infoSink, bool keepUncalled) if (! keepUncalled) { for (int f = 0; f < (int)functionSequence.size(); ++f) { if (! reachable[f]) + { + resetTopLevelUncalledStatus(functionSequence[f]->getAsAggregate()->getName()); functionSequence[f] = nullptr; + } } functionSequence.erase(std::remove(functionSequence.begin(), functionSequence.end(), nullptr), functionSequence.end()); } @@ -1424,7 +1606,7 @@ bool TIntermediate::userOutputUsed() const return found; } -// Accumulate locations used for inputs, outputs, and uniforms, payload and callable data +// Accumulate locations used for inputs, outputs, and uniforms, payload, callable data, and tileImageEXT // 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. @@ -1437,7 +1619,6 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ typeCollision = false; int set; - int setRT; if (qualifier.isPipeInput()) set = 0; else if (qualifier.isPipeOutput()) @@ -1446,10 +1627,14 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ set = 2; else if (qualifier.storage == EvqBuffer) set = 3; + else if (qualifier.storage == EvqTileImageEXT) + set = 4; else if (qualifier.isAnyPayload()) - setRT = 0; + set = 0; else if (qualifier.isAnyCallable()) - setRT = 1; + set = 1; + else if (qualifier.isHitObjectAttrNV()) + set = 2; else return -1; @@ -1488,13 +1673,14 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ // For raytracing IO (payloads and callabledata) each declaration occupies a single // slot irrespective of type. int collision = -1; // no collision -#ifndef GLSLANG_WEB - if (qualifier.isAnyPayload() || qualifier.isAnyCallable()) { + if (qualifier.isAnyPayload() || qualifier.isAnyCallable() || qualifier.isHitObjectAttrNV()) { TRange range(qualifier.layoutLocation, qualifier.layoutLocation); - collision = checkLocationRT(setRT, qualifier.layoutLocation); + collision = checkLocationRT(set, qualifier.layoutLocation); if (collision < 0) - usedIoRT[setRT].push_back(range); - } else if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 && + usedIoRT[set].push_back(range); + return collision; + } + if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 && (qualifier.isPipeInput() || qualifier.isPipeOutput())) { // Dealing with dvec3 in/out split across two locations. // Need two io-ranges. @@ -1520,31 +1706,33 @@ int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& typ if (collision < 0) usedIo[set].push_back(range2); } - } else -#endif - { - // Not a dvec3 in/out split across two locations, generic path. - // Need a single IO-range block. + return collision; + } - TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation + size - 1); - TRange componentRange(0, 3); - if (qualifier.hasComponent() || type.getVectorSize() > 0) { - int consumedComponents = type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1); - if (qualifier.hasComponent()) - componentRange.start = qualifier.layoutComponent; - componentRange.last = componentRange.start + consumedComponents - 1; - } + // Not a dvec3 in/out split across two locations, generic path. + // Need a single IO-range block. - // combine location and component ranges - TIoRange range(locationRange, componentRange, type.getBasicType(), qualifier.hasIndex() ? qualifier.getIndex() : 0); + TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation + size - 1); + TRange componentRange(0, 3); + if (qualifier.hasComponent() || type.getVectorSize() > 0) { + int consumedComponents = type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1); + if (qualifier.hasComponent()) + componentRange.start = qualifier.layoutComponent; + componentRange.last = componentRange.start + consumedComponents - 1; + } - // check for collisions, except for vertex inputs on desktop targeting OpenGL - if (! (!isEsProfile() && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0) - collision = checkLocationRange(set, range, type, typeCollision); + // combine location and component ranges + TBasicType basicTy = type.getBasicType(); + if (basicTy == EbtSampler && type.getSampler().isAttachmentEXT()) + basicTy = type.getSampler().type; + TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0); - if (collision < 0) - usedIo[set].push_back(range); - } + // check for collisions, except for vertex inputs on desktop targeting OpenGL + if (! (!isEsProfile() && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0) + collision = checkLocationRange(set, range, type, typeCollision); + + if (collision < 0) + usedIo[set].push_back(range); return collision; } @@ -1567,6 +1755,19 @@ int TIntermediate::checkLocationRange(int set, const TIoRange& range, const TTyp } } + // check typeCollision between tileImageEXT and out + if (set == 4 || set == 1) { + // if the set is "tileImageEXT", check against "out" and vice versa + int againstSet = (set == 4) ? 1 : 4; + for (size_t r = 0; r < usedIo[againstSet].size(); ++r) { + if (range.location.overlap(usedIo[againstSet][r].location) && type.getBasicType() != usedIo[againstSet][r].basicType) { + // aliased-type mismatch + typeCollision = true; + return std::max(range.location.start, usedIo[againstSet][r].location.start); + } + } + } + return -1; // no collision } @@ -1630,10 +1831,8 @@ int TIntermediate::computeTypeLocationSize(const TType& type, EShLanguage stage) if (type.isSizedArray() && !type.getQualifier().isPerView()) return type.getOuterArraySize() * computeTypeLocationSize(elementType, stage); else { -#ifndef GLSLANG_WEB // unset perViewNV attributes for arrayed per-view outputs: "perviewNV vec4 v[MAX_VIEWS][3];" elementType.getQualifier().perViewNV = false; -#endif return computeTypeLocationSize(elementType, stage); } } @@ -1709,8 +1908,6 @@ int TIntermediate::computeTypeUniformLocationSize(const TType& type) return 1; } -#ifndef GLSLANG_WEB - // Accumulate xfb buffer ranges and check for collisions as the accumulation is done. // // Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value. @@ -1802,7 +1999,7 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains return size; } - int numComponents; + int numComponents {0}; if (type.isScalar()) numComponents = 1; else if (type.isVector()) @@ -1828,8 +2025,6 @@ unsigned int TIntermediate::computeTypeXfbSize(const TType& type, bool& contains } } -#endif - const int baseAlignmentVec4Std140 = 16; // Return the size and alignment of a component of the given type. @@ -1837,10 +2032,6 @@ const int baseAlignmentVec4Std140 = 16; // Return value is the alignment.. int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size) { -#ifdef GLSLANG_WEB - size = 4; return 4; -#endif - switch (type.getBasicType()) { case EbtInt64: case EbtUint64: @@ -1851,6 +2042,15 @@ int TIntermediate::getBaseAlignmentScalar(const TType& type, int& size) case EbtInt16: case EbtUint16: size = 2; return 2; case EbtReference: size = 8; return 8; + case EbtSampler: + { + if (type.isBindlessImage() || type.isBindlessTexture()) { + size = 8; return 8; + } + else { + size = 4; return 4; + } + } default: size = 4; return 4; } } @@ -2068,7 +2268,7 @@ int TIntermediate::getScalarAlignment(const TType& type, int& size, int& stride, if (type.isVector()) { int scalarAlign = getBaseAlignmentScalar(type, size); - + size *= type.getVectorSize(); return scalarAlign; } @@ -2089,7 +2289,7 @@ int TIntermediate::getScalarAlignment(const TType& type, int& size, int& stride, assert(0); // all cases should be covered above size = 1; - return 1; + return 1; } int TIntermediate::getMemberAlignment(const TType& type, int& size, int& stride, TLayoutPacking layoutPacking, bool rowMajor) @@ -2171,7 +2371,6 @@ int TIntermediate::computeBufferReferenceTypeSize(const TType& type) return size; } -#ifndef GLSLANG_WEB bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) { return type.isArray() && ((language == EShLangGeometry && type.getQualifier().storage == EvqVaryingIn) || @@ -2179,10 +2378,9 @@ bool TIntermediate::isIoResizeArray(const TType& type, EShLanguage language) { ! type.getQualifier().patch) || (language == EShLangTessEvaluation && type.getQualifier().storage == EvqVaryingIn) || (language == EShLangFragment && type.getQualifier().storage == EvqVaryingIn && - type.getQualifier().pervertexNV) || - (language == EShLangMeshNV && type.getQualifier().storage == EvqVaryingOut && + (type.getQualifier().pervertexNV || type.getQualifier().pervertexEXT)) || + (language == EShLangMesh && type.getQualifier().storage == EvqVaryingOut && !type.getQualifier().perTaskNV)); } -#endif // not GLSLANG_WEB } // end namespace glslang diff --git a/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h b/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h index 1386cb3a8..c73f2b4d5 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h +++ b/src/libraries/glslang/glslang/MachineIndependent/localintermediate.h @@ -43,11 +43,12 @@ #include "../Public/ShaderLang.h" #include "Versions.h" -#include -#include #include -#include #include +#include +#include +#include +#include class TInfoSink; @@ -147,7 +148,6 @@ struct TOffsetRange { TRange offset; }; -#ifndef GLSLANG_WEB // Things that need to be tracked per xfb buffer. struct TXfbBuffer { TXfbBuffer() : stride(TQualifier::layoutXfbStrideEnd), implicitStride(0), contains64BitType(false), @@ -159,7 +159,6 @@ struct TXfbBuffer { bool contains32BitType; bool contains16BitType; }; -#endif // Track a set of strings describing how the module was processed. // This includes command line options, transforms, etc., ideally inclusive enough @@ -225,6 +224,16 @@ enum ComputeDerivativeMode { LayoutDerivativeGroupLinear, // derivative_group_linearNV }; +// +// Status type on AST level. Some uncalled status or functions would be reset in call graph. +// Currently we will keep status set by explicitly declared layout or variable decl. +// +enum AstRefType { + AstRefTypeVar, // Status set by variable decl + AstRefTypeFunc, // Status set by function decl + AstRefTypeLayout, // Status set by layout decl +}; + class TIdMaps { public: TMap& operator[](long long i) { return maps[i]; } @@ -283,34 +292,38 @@ class TIntermediate { public: explicit TIntermediate(EShLanguage l, int v = 0, EProfile p = ENoProfile) : language(l), -#ifndef GLSLANG_ANGLE profile(p), version(v), -#endif - treeRoot(0), + treeRoot(nullptr), resources(TBuiltInResource{}), numEntryPoints(0), numErrors(0), numPushConstants(0), recursive(false), invertY(false), dxPositionW(false), + enhancedMsgs(false), + debugInfo(false), useStorageBuffer(false), invariantAll(false), nanMinMaxClamp(false), depthReplacing(false), + stencilReplacing(false), uniqueId(0), globalUniformBlockName(""), atomicCounterBlockName(""), globalUniformBlockSet(TQualifier::layoutSetEnd), globalUniformBlockBinding(TQualifier::layoutBindingEnd), - atomicCounterBlockSet(TQualifier::layoutSetEnd) -#ifndef GLSLANG_WEB - , + atomicCounterBlockSet(TQualifier::layoutSetEnd), implicitThisName("@this"), implicitCounterName("@count"), source(EShSourceNone), useVulkanMemoryModel(false), invocations(TQualifier::layoutNotSet), vertices(TQualifier::layoutNotSet), inputPrimitive(ElgNone), outputPrimitive(ElgNone), - pixelCenterInteger(false), originUpperLeft(false), + pixelCenterInteger(false), originUpperLeft(false),texCoordBuiltinRedeclared(false), vertexSpacing(EvsNone), vertexOrder(EvoNone), interlockOrdering(EioNone), pointMode(false), earlyFragmentTests(false), - postDepthCoverage(false), depthLayout(EldNone), + postDepthCoverage(false), earlyAndLateFragmentTestsAMD(false), + nonCoherentColorAttachmentReadEXT(false), + nonCoherentDepthAttachmentReadEXT(false), + nonCoherentStencilAttachmentReadEXT(false), + depthLayout(EldNone), + stencilLayout(ElsNone), hlslFunctionality1(false), blendEquations(0), xfbMode(false), multiStream(false), layoutOverrideCoverage(false), @@ -320,6 +333,7 @@ class TIntermediate { primitives(TQualifier::layoutNotSet), numTaskNVBlocks(0), layoutPrimitiveCulling(false), + numTaskEXTPayloads(0), autoMapBindings(false), autoMapLocations(false), flattenUniformArrays(false), @@ -335,7 +349,6 @@ class TIntermediate { spirvRequirement(nullptr), spirvExecutionMode(nullptr), uniformLocationBase(0) -#endif { localSize[0] = 1; localSize[1] = 1; @@ -346,23 +359,17 @@ class TIntermediate { localSizeSpecId[0] = TQualifier::layoutNotSet; localSizeSpecId[1] = TQualifier::layoutNotSet; localSizeSpecId[2] = TQualifier::layoutNotSet; -#ifndef GLSLANG_WEB xfbBuffers.resize(TQualifier::layoutXfbBufferEnd); shiftBinding.fill(0); -#endif } void setVersion(int v) { -#ifndef GLSLANG_ANGLE version = v; -#endif } void setProfile(EProfile p) { -#ifndef GLSLANG_ANGLE profile = p; -#endif } int getVersion() const { return version; } @@ -419,6 +426,9 @@ class TIntermediate { case EShTargetVulkan_1_2: processes.addProcess("target-env vulkan1.2"); break; + case EShTargetVulkan_1_3: + processes.addProcess("target-env vulkan1.3"); + break; default: processes.addProcess("target-env vulkanUnknown"); break; @@ -456,6 +466,12 @@ class TIntermediate { const std::string& getEntryPointName() const { return entryPointName; } const std::string& getEntryPointMangledName() const { return entryPointMangledName; } + void setDebugInfo(bool debuginfo) + { + debugInfo = debuginfo; + } + bool getDebugInfo() const { return debugInfo; } + void setInvertY(bool invert) { invertY = invert; @@ -466,12 +482,18 @@ class TIntermediate { void setDxPositionW(bool dxPosW) { - dxPositionW = dxPosW; - if (dxPositionW) - processes.addProcess("dx-position-w"); + dxPositionW = dxPosW; + if (dxPositionW) + processes.addProcess("dx-position-w"); } bool getDxPositionW() const { return dxPositionW; } + void setEnhancedMsgs() + { + enhancedMsgs = true; + } + bool getEnhancedMsgs() const { return enhancedMsgs && getSource() == EShSourceGlsl; } + #ifdef ENABLE_HLSL void setSource(EShSource s) { source = s; } EShSource getSource() const { return source; } @@ -506,6 +528,8 @@ class TIntermediate { TOperator mapTypeToConstructorOp(const TType&) const; TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right); TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&); + TIntermAggregate* mergeAggregate(TIntermNode* left, TIntermNode* right); + TIntermAggregate* mergeAggregate(TIntermNode* left, TIntermNode* right, const TSourceLoc&); TIntermAggregate* makeAggregate(TIntermNode* node); TIntermAggregate* makeAggregate(TIntermNode* node, const TSourceLoc&); TIntermAggregate* makeAggregate(const TSourceLoc&); @@ -551,7 +575,8 @@ class TIntermediate { TIntermTyped* foldSwizzle(TIntermTyped* node, TSwizzleSelectors& fields, const TSourceLoc&); // Tree ops - static const TIntermTyped* findLValueBase(const TIntermTyped*, bool swizzleOkay , bool BufferReferenceOk = false); + static const TIntermTyped* traverseLValueBase(const TIntermTyped*, bool swizzleOkay, bool bufferReferenceOk = false, + std::function proc = {}); // Linkage related void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); @@ -577,6 +602,8 @@ class TIntermediate { bool isInvariantAll() const { return invariantAll; } void setDepthReplacing() { depthReplacing = true; } bool isDepthReplacing() const { return depthReplacing; } + void setStencilReplacing() { stencilReplacing = true; } + bool isStencilReplacing() const { return stencilReplacing; } bool setLocalSize(int dim, int size) { if (localSizeNotDefault[dim]) @@ -606,34 +633,6 @@ class TIntermediate { localSizeSpecId[1] != TQualifier::layoutNotSet || localSizeSpecId[2] != TQualifier::layoutNotSet; } -#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 addShaderRecordCount() { } - 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; } @@ -728,6 +727,65 @@ class TIntermediate { useVariablePointers = true; processes.addProcess("use-variable-pointers"); } + // Set the global flag for bindless texture + void setBindlessTextureMode(const TString& currentCaller, AstRefType type) + { + // When type is not func, currentCaller should be "" (empty string) + bindlessTextureModeCaller[currentCaller] = type; + } + + // Get the global flag for bindless texture + bool getBindlessTextureMode() const + { + return (bindlessTextureModeCaller.size() > 0); + } + + // Set the global flag for bindless image + void setBindlessImageMode(const TString& currentCaller, AstRefType type) + { + // When type is not func, currentCaller should be "" (empty string) + bindlessImageModeCaller[currentCaller] = type; + } + + // Get the global flag for bindless image + bool getBindlessImageMode() const + { + return (bindlessImageModeCaller.size() > 0); + } + + // Get the global flag for bindless texture + bool resetTopLevelUncalledStatus(const TString& deadCaller) + { + // For reflection collection purpose, currently uniform layout setting and some + // flags introduced by variables (IO, global, etc,.) won't be reset here. + // Remove each global status (AST top level) introduced by uncalled functions. + // If a status is set by several functions, keep those which in call graph. + bool result = false; + + // For two types of bindless mode flag, we would only reset which is set by an uncalled function. + // If one status flag's key in caller vec is empty, it should be come from a non-function setting. + if (!bindlessTextureModeCaller.empty()) { + auto caller = bindlessTextureModeCaller.find(deadCaller); + if (caller != bindlessTextureModeCaller.end() && bindlessTextureModeCaller[deadCaller] == AstRefTypeFunc) { + bindlessTextureModeCaller.erase(caller); + result = true; + } + } + if (!bindlessImageModeCaller.empty()) { + auto caller = bindlessImageModeCaller.find(deadCaller); + if (caller != bindlessImageModeCaller.end() && bindlessImageModeCaller[deadCaller] == AstRefTypeFunc) { + bindlessImageModeCaller.erase(caller); + result = true; + } + } + return result; + } + + bool getBindlessMode() const + { + return getBindlessTextureMode() || getBindlessImageMode(); + } + bool usingVariablePointers() const { return useVariablePointers; } #ifdef ENABLE_HLSL @@ -743,6 +801,7 @@ class TIntermediate { int getNumPushConstants() const { return numPushConstants; } void addShaderRecordCount() { ++numShaderRecordBlocks; } void addTaskNVCount() { ++numTaskNVBlocks; } + void addTaskPayloadEXTCount() { ++numTaskEXTPayloads; } bool setInvocations(int i) { @@ -808,10 +867,18 @@ class TIntermediate { return true; } TLayoutGeometry getOutputPrimitive() const { return outputPrimitive; } + void setNonCoherentColorAttachmentReadEXT() { nonCoherentColorAttachmentReadEXT = true; } + bool getNonCoherentColorAttachmentReadEXT() const { return nonCoherentColorAttachmentReadEXT; } + void setNonCoherentDepthAttachmentReadEXT() { nonCoherentDepthAttachmentReadEXT = true; } + bool getNonCoherentDepthAttachmentReadEXT() const { return nonCoherentDepthAttachmentReadEXT; } + void setNonCoherentStencilAttachmentReadEXT() { nonCoherentStencilAttachmentReadEXT = true; } + bool getNonCoherentStencilAttachmentReadEXT() const { return nonCoherentStencilAttachmentReadEXT; } void setPostDepthCoverage() { postDepthCoverage = true; } bool getPostDepthCoverage() const { return postDepthCoverage; } void setEarlyFragmentTests() { earlyFragmentTests = true; } + void setEarlyAndLateFragmentTestsAMD() { earlyAndLateFragmentTestsAMD = true; } bool getEarlyFragmentTests() const { return earlyFragmentTests; } + bool getEarlyAndLateFragmentTestsAMD() const { return earlyAndLateFragmentTestsAMD; } bool setDepth(TLayoutDepth d) { if (depthLayout != EldNone) @@ -819,11 +886,21 @@ class TIntermediate { depthLayout = d; return true; } + bool setStencil(TLayoutStencil s) + { + if (stencilLayout != ElsNone) + return stencilLayout == s; + stencilLayout = s; + return true; + } TLayoutDepth getDepth() const { return depthLayout; } + TLayoutStencil getStencil() const { return stencilLayout; } void setOriginUpperLeft() { originUpperLeft = true; } bool getOriginUpperLeft() const { return originUpperLeft; } void setPixelCenterInteger() { pixelCenterInteger = true; } bool getPixelCenterInteger() const { return pixelCenterInteger; } + void setTexCoordRedeclared() { texCoordBuiltinRedeclared = true; } + bool getTexCoordRedeclared() const { return texCoordBuiltinRedeclared; } void addBlendEquation(TBlendEquationShift b) { blendEquations |= (1 << b); } unsigned int getBlendEquations() const { return blendEquations; } bool setXfbBufferStride(int buffer, unsigned stride) @@ -894,7 +971,6 @@ class TIntermediate { void insertSpirvExecutionModeId(int executionMode, const TIntermAggregate* args); bool hasSpirvExecutionMode() const { return spirvExecutionMode != nullptr; } const TSpirvExecutionMode& getSpirvExecutionMode() const { return *spirvExecutionMode; } -#endif // GLSLANG_WEB void addBlockStorageOverride(const char* nameStr, TBlockStorageClass backing) { @@ -1001,12 +1077,6 @@ class TIntermediate { void setUniqueId(unsigned long long id) { uniqueId = id; } // Certain explicit conversions are allowed conditionally -#ifdef GLSLANG_WEB - bool getArithemeticInt8Enabled() const { return false; } - bool getArithemeticInt16Enabled() const { return false; } - bool getArithemeticFloat16Enabled() const { return false; } - void updateNumericFeature(TNumericFeatures::feature f, bool on) { } -#else bool getArithemeticInt8Enabled() const { return numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types) || numericFeatures.contains(TNumericFeatures::shader_explicit_arithmetic_types_int8); @@ -1024,12 +1094,11 @@ class TIntermediate { } void updateNumericFeature(TNumericFeatures::feature f, bool on) { on ? numericFeatures.insert(f) : numericFeatures.erase(f); } -#endif protected: TIntermSymbol* addSymbol(long long Id, const TString&, const TType&, const TConstUnionArray&, TIntermTyped* subtree, const TSourceLoc&); - void error(TInfoSink& infoSink, const char*); - void warn(TInfoSink& infoSink, const char*); + void error(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount); + void warn(TInfoSink& infoSink, const char*, EShLanguage unitStage = EShLangCount); void mergeCallGraphs(TInfoSink&, TIntermediate&); void mergeModes(TInfoSink&, TIntermediate&); void mergeTrees(TInfoSink&, TIntermediate&); @@ -1066,13 +1135,8 @@ class TIntermediate { typedef std::list TGraph; TGraph callGraph; -#ifdef GLSLANG_ANGLE - const EProfile profile = ECoreProfile; - const int version = 450; -#else EProfile profile; // source profile int version; // source version -#endif SpvVersion spvVersion; TIntermNode* treeRoot; std::set requestedExtensions; // cumulation of all enabled or required extensions; not connected to what subset of the shader used them @@ -1083,10 +1147,13 @@ class TIntermediate { bool recursive; bool invertY; bool dxPositionW; + bool enhancedMsgs; + bool debugInfo; bool useStorageBuffer; bool invariantAll; bool nanMinMaxClamp; // true if desiring min/max/clamp to favor non-NaN over NaN bool depthReplacing; + bool stencilReplacing; int localSize[3]; bool localSizeNotDefault[3]; int localSizeSpecId[3]; @@ -1098,7 +1165,6 @@ class TIntermediate { unsigned int globalUniformBlockBinding; unsigned int atomicCounterBlockSet; -#ifndef GLSLANG_WEB public: const char* const implicitThisName; const char* const implicitCounterName; @@ -1111,13 +1177,19 @@ class TIntermediate { TLayoutGeometry outputPrimitive; bool pixelCenterInteger; bool originUpperLeft; + bool texCoordBuiltinRedeclared; TVertexSpacing vertexSpacing; TVertexOrder vertexOrder; TInterlockOrdering interlockOrdering; bool pointMode; bool earlyFragmentTests; bool postDepthCoverage; + bool earlyAndLateFragmentTestsAMD; + bool nonCoherentColorAttachmentReadEXT; + bool nonCoherentDepthAttachmentReadEXT; + bool nonCoherentStencilAttachmentReadEXT; TLayoutDepth depthLayout; + TLayoutStencil stencilLayout; bool hlslFunctionality1; int blendEquations; // an 'or'ing of masks of shifts of TBlendEquationShift bool xfbMode; @@ -1130,6 +1202,7 @@ class TIntermediate { int primitives; int numTaskNVBlocks; bool layoutPrimitiveCulling; + int numTaskEXTPayloads; // Base shift values std::array shiftBinding; @@ -1157,20 +1230,22 @@ class TIntermediate { TSpirvRequirement* spirvRequirement; TSpirvExecutionMode* spirvExecutionMode; - + std::map bindlessTextureModeCaller; + std::map bindlessImageModeCaller; std::unordered_map uniformLocationOverrides; int uniformLocationBase; TNumericFeatures numericFeatures; -#endif std::unordered_map blockBackingOverrides; std::unordered_set usedConstantId; // specialization constant ids used std::vector usedAtomics; // sets of bindings used by atomic counters std::vector usedIo[4]; // sets of used locations, one for each of in, out, uniform, and buffers - std::vector usedIoRT[2]; // sets of used location, one for rayPayload/rayPayloadIN and other - // for callableData/callableDataIn + std::vector usedIoRT[4]; // sets of used location, one for rayPayload/rayPayloadIN, + // one for callableData/callableDataIn, one for hitObjectAttributeNV and + // one for shaderrecordhitobjectNV // set of names of statically read/written I/O that might need extra checking std::set ioAccessed; + // source code of shader, useful as part of debug information std::string sourceFile; std::string sourceText; diff --git a/src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp b/src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp index 6c182991f..835097234 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/parseConst.cpp @@ -198,7 +198,7 @@ void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) bool TIntermediate::parseConstTree(TIntermNode* root, TConstUnionArray unionArray, TOperator constructorType, const TType& t, bool singleConstantParam) { - if (root == 0) + if (root == nullptr) return false; TConstTraverser it(unionArray, singleConstantParam, constructorType, t); diff --git a/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h b/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h index 7248354e4..63841c408 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h +++ b/src/libraries/glslang/glslang/MachineIndependent/parseVersions.h @@ -58,72 +58,18 @@ class TParseVersions { const SpvVersion& spvVersion, EShLanguage language, TInfoSink& infoSink, bool forwardCompatible, EShMessages messages) : -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) 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(nullptr) { } 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 extensionRequires(const TSourceLoc&, const char* const extension, const char* behavior) { } - 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 -#ifdef GLSLANG_ANGLE - const bool forwardCompatible = true; - const EProfile profile = ECoreProfile; -#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) -#endif 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, @@ -167,29 +113,19 @@ class TParseVersions { virtual void explicitInt32Check(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 fcoopmatCheck(const TSourceLoc&, const char* op, bool builtIn = false); - virtual void intcoopmatCheck(const TSourceLoc&, const char *op, bool builtIn = false); + virtual void fcoopmatCheckNV(const TSourceLoc&, const char* op, bool builtIn = false); + virtual void intcoopmatCheckNV(const TSourceLoc&, const char *op, bool builtIn = false); + virtual void coopmatCheck(const TSourceLoc&, const char* op, bool builtIn = false); bool relaxedErrors() const { return (messages & EShMsgRelaxedErrors) != 0; } bool suppressWarnings() const { return (messages & EShMsgSuppressWarnings) != 0; } bool isForwardCompatible() const { return forwardCompatible; } -#endif // GLSLANG_WEB + virtual void spvRemoved(const TSourceLoc&, const char* op); virtual void vulkanRemoved(const TSourceLoc&, const char* op); virtual void requireVulkan(const TSourceLoc&, const char* op); virtual void requireSpv(const TSourceLoc&, const char* op); virtual void requireSpv(const TSourceLoc&, const char *op, unsigned int version); - -#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, const char* szExtraInfoFormat, ...) = 0; virtual void C_DECL warn(const TSourceLoc&, const char* szReason, const char* szToken, @@ -198,7 +134,6 @@ class TParseVersions { const char* szExtraInfoFormat, ...) = 0; virtual void C_DECL ppWarn(const TSourceLoc&, const char* szReason, const char* szToken, const char* szExtraInfoFormat, ...) = 0; -#endif void addError() { ++numErrors; } int getNumErrors() const { return numErrors; } @@ -231,6 +166,7 @@ class TParseVersions { protected: TMap extensionBehavior; // for each extension string, what its current behavior is TMap extensionMinSpv; // for each extension string, store minimum spirv required + TVector spvUnsupportedExt; // for extensions reserved for spv usage. EShMessages messages; // errors/warnings/rule-sets int numErrors; // number of compile-time errors encountered TInputScanner* currentScanner; diff --git a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp index aa1e0d745..16b9d2437 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp @@ -378,8 +378,6 @@ namespace { int op_cmpl(int a) { return ~a; } int op_not(int a) { return !a; } -}; - struct TBinop { int token, precedence, (*op)(int, int); } binop[] = { @@ -412,6 +410,8 @@ struct TUnop { { '!', op_not }, }; +} // anonymous namespace + #define NUM_ELEMENTS(A) (sizeof(A) / sizeof(A[0])) int TPpContext::eval(int token, int precedence, bool shortCircuit, int& res, bool& err, TPpToken* ppToken) @@ -736,7 +736,6 @@ int TPpContext::CPPline(TPpToken* ppToken) parseContext.setCurrentLine(lineRes); if (token != '\n') { -#ifndef GLSLANG_WEB if (token == PpAtomConstString) { parseContext.ppRequireExtensions(directiveLoc, 1, &E_GL_GOOGLE_cpp_style_line_directive, "filename-based #line"); // We need to save a copy of the string instead of pointing @@ -746,9 +745,7 @@ int TPpContext::CPPline(TPpToken* ppToken) parseContext.setCurrentSourceName(sourceName); hasFile = true; token = scanToken(ppToken); - } else -#endif - { + } else { token = eval(token, MIN_PRECEDENCE, false, fileRes, fileErr, ppToken); if (! fileErr) { parseContext.setCurrentString(fileRes); @@ -974,7 +971,6 @@ int TPpContext::readCPPline(TPpToken* ppToken) case PpAtomLine: token = CPPline(ppToken); break; -#ifndef GLSLANG_WEB case PpAtomInclude: if(!parseContext.isReadingHLSL()) { parseContext.ppRequireExtensions(ppToken->loc, 1, &E_GL_GOOGLE_include_directive, "#include"); @@ -984,7 +980,6 @@ int TPpContext::readCPPline(TPpToken* ppToken) case PpAtomPragma: token = CPPpragma(ppToken); break; -#endif case PpAtomUndef: token = CPPundef(ppToken); break; @@ -1126,9 +1121,6 @@ int TPpContext::tMacroInput::scan(TPpToken* ppToken) pasting = true; } - // HLSL does expand macros before concatenation - if (pasting && pp->parseContext.isReadingHLSL()) - pasting = false; // TODO: preprocessor: properly handle whitespace (or lack of it) between tokens when expanding if (token == PpAtomIdentifier) { @@ -1138,9 +1130,12 @@ int TPpContext::tMacroInput::scan(TPpToken* ppToken) break; if (i >= 0) { TokenStream* arg = expandedArgs[i]; - if (arg == nullptr || pasting) + bool expanded = !!arg && !pasting; + // HLSL does expand macros before concatenation + if (arg == nullptr || (pasting && !pp->parseContext.isReadingHLSL()) ) { arg = args[i]; - pp->pushTokenStreamInput(*arg, prepaste); + } + pp->pushTokenStreamInput(*arg, prepaste, expanded); return pp->scanToken(ppToken); } @@ -1183,6 +1178,9 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b { ppToken->space = false; int macroAtom = atomStrings.getAtom(ppToken->name); + if (ppToken->fullyExpanded) + return MacroExpandNotStarted; + switch (macroAtom) { case PpAtomLineMacro: // Arguments which are macro have been replaced in the first stage. @@ -1214,8 +1212,10 @@ MacroExpandResult TPpContext::MacroExpand(TPpToken* ppToken, bool expandUndef, b MacroSymbol* macro = macroAtom == 0 ? nullptr : lookupMacroDef(macroAtom); // no recursive expansions - if (macro != nullptr && macro->busy) + if (macro != nullptr && macro->busy) { + ppToken->fullyExpanded = true; return MacroExpandNotStarted; + } // not expanding undefined macros if ((macro == nullptr || macro->undef) && ! expandUndef) diff --git a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp index 1363ce2be..70f511978 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp @@ -85,7 +85,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. namespace glslang { TPpContext::TPpContext(TParseContextBase& pc, const std::string& rootFileName, TShader::Includer& inclr) : - preamble(0), strings(0), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false), + preamble(nullptr), strings(nullptr), previous_token('\n'), parseContext(pc), includer(inclr), inComment(false), rootFileName(rootFileName), currentSourceFile(rootFileName), disableEscapeSequences(false) diff --git a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h index 714b5eadb..1ec30491c 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h +++ b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpContext.h @@ -86,11 +86,6 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "../ParseHelper.h" #include "PpTokens.h" -/* windows only pragma */ -#ifdef _MSC_VER - #pragma warning(disable : 4127) -#endif - namespace glslang { class TPpToken { @@ -102,6 +97,7 @@ class TPpToken { i64val = 0; loc.init(); name[0] = 0; + fullyExpanded = false; } // Used for comparing macro definitions, so checks what is relevant for that. @@ -117,6 +113,8 @@ class TPpToken { // True if a space (for white space or a removed comment) should also be // recognized, in front of the token returned: bool space; + + bool fullyExpanded; // Numeric value of the token: union { int ival; @@ -217,6 +215,7 @@ class TPpContext { virtual bool peekContinuedPasting(int) { return false; } // true when non-spaced tokens can paste virtual bool endOfReplacementList() { return false; } // true when at the end of a macro replacement list (RHS of #define) virtual bool isMacroInput() { return false; } + virtual bool isStringInput() { return false; } // Will be called when we start reading tokens from this instance virtual void notifyActivated() {} @@ -357,7 +356,8 @@ class TPpContext { // Scanner data: int previous_token; TParseContextBase& parseContext; - + std::vector lastLineTokens; + std::vector lastLineTokenLocs; // Get the next token from *stack* of input sources, popping input sources // that are out of tokens, down until an input source is found that has a token. // Return EndOfInput when there are no more tokens to be found by doing this. @@ -371,7 +371,31 @@ class TPpContext { break; popInput(); } - + if (!inputStack.empty() && inputStack.back()->isStringInput()) { + if (token == '\n') { + bool seenNumSign = false; + for (int i = 0; i < (int)lastLineTokens.size() - 1;) { + int curPos = i; + int curToken = lastLineTokens[i++]; + if (curToken == '#' && lastLineTokens[i] == '#') { + curToken = PpAtomPaste; + i++; + } + if (curToken == '#') { + if (seenNumSign) { + parseContext.ppError(lastLineTokenLocs[curPos], "(#) can be preceded in its line only by spaces or horizontal tabs", "#", ""); + } else { + seenNumSign = true; + } + } + } + lastLineTokens.clear(); + lastLineTokenLocs.clear(); + } else { + lastLineTokens.push_back(token); + lastLineTokenLocs.push_back(ppToken->loc); + } + } return token; } int getChar() { return inputStack.back()->getch(); } @@ -475,16 +499,27 @@ class TPpContext { // // From PpTokens.cpp // - void pushTokenStreamInput(TokenStream&, bool pasting = false); + void pushTokenStreamInput(TokenStream&, bool pasting = false, bool expanded = false); void UngetToken(int token, TPpToken*); class tTokenInput : public tInput { public: - tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting) : + tTokenInput(TPpContext* pp, TokenStream* t, bool prepasting, bool expanded) : tInput(pp), tokens(t), - lastTokenPastes(prepasting) { } - virtual int scan(TPpToken *ppToken) override { return tokens->getToken(pp->parseContext, ppToken); } + lastTokenPastes(prepasting), + preExpanded(expanded) { } + virtual int scan(TPpToken *ppToken) override { + int token = tokens->getToken(pp->parseContext, ppToken); + ppToken->fullyExpanded = preExpanded; + if (tokens->atEnd() && token == PpAtomIdentifier) { + int macroAtom = pp->atomStrings.getAtom(ppToken->name); + MacroSymbol* macro = macroAtom == 0 ? nullptr : pp->lookupMacroDef(macroAtom); + if (macro && macro->functionLike) + ppToken->fullyExpanded = false; + } + return token; + } virtual int getch() override { assert(0); return EndOfInput; } virtual void ungetch() override { assert(0); } virtual bool peekPasting() override { return tokens->peekTokenizedPasting(lastTokenPastes); } @@ -492,6 +527,7 @@ class TPpContext { protected: TokenStream* tokens; bool lastTokenPastes; // true if the last token in the input is to be pasted, rather than consumed as a token + bool preExpanded; }; class tUngotTokenInput : public tInput { @@ -512,7 +548,7 @@ class TPpContext { public: tStringInput(TPpContext* pp, TInputScanner& i) : tInput(pp), input(&i) { } virtual int scan(TPpToken*) override; - + bool isStringInput() override { return true; } // Scanner used to get source stream characters. // - Escaped newlines are handled here, invisibly to the caller. // - All forms of newline are handled, and turned into just a '\n'. diff --git a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp index ad1179200..34dec2076 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp @@ -3,6 +3,7 @@ // Copyright (C) 2013 LunarG, Inc. // Copyright (C) 2017 ARM Limited. // Copyright (C) 2015-2018 Google, Inc. +// Copyright (c) 2023, Mobica Limited // // All rights reserved. // @@ -259,7 +260,6 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) // Suffix: bool isDouble = false; bool isFloat16 = false; -#ifndef GLSLANG_WEB if (ch == 'l' || ch == 'L') { if (ifdepth == 0 && parseContext.intermediate.getSource() == EShSourceGlsl) parseContext.doubleCheck(ppToken->loc, "double floating-point suffix"); @@ -299,14 +299,11 @@ int TPpContext::lFloatConst(int len, int ch, TPpToken* ppToken) isFloat16 = true; } } else -#endif if (ch == 'f' || ch == 'F') { -#ifndef GLSLANG_WEB if (ifdepth == 0) parseContext.profileRequires(ppToken->loc, EEsProfile, 300, nullptr, "floating-point suffix"); if (ifdepth == 0 && !parseContext.relaxedErrors()) parseContext.profileRequires(ppToken->loc, ~EEsProfile, 120, nullptr, "floating-point suffix"); -#endif if (ifdepth == 0 && !hasDecimalOrExponent) parseContext.ppError(ppToken->loc, "float literal needs a decimal point or exponent", "", ""); saveName(ch); @@ -480,9 +477,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) E_GL_EXT_shader_explicit_arithmetic_types_int16 }; static const int Num_Int16_Extensions = sizeof(Int16_Extensions) / sizeof(Int16_Extensions[0]); - ppToken->ival = 0; - ppToken->i64val = 0; - ppToken->space = false; + ppToken->clear(); ch = getch(); for (;;) { while (ch == ' ' || ch == '\t') { @@ -551,7 +546,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ival = 0; do { - if (len < MaxTokenLength && ival <= 0x0fffffffffffffffull) { + if (len < MaxTokenLength && ival <= 0x7fffffffffffffffull) { ppToken->name[len++] = (char)ch; if (ch >= '0' && ch <= '9') { ii = ch - '0'; @@ -584,7 +579,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->name[len++] = (char)ch; isUnsigned = true; -#ifndef GLSLANG_WEB int nextCh = getch(); if (nextCh == 'l' || nextCh == 'L') { if (len < MaxTokenLength) @@ -610,7 +604,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt16 = true; -#endif } else ungetch(); ppToken->name[len] = '\0'; @@ -641,6 +634,108 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->ival = (int)ival; return isUnsigned ? PpAtomConstUint : PpAtomConstInt; } + } else if ((ch == 'b' || ch == 'B') && pp->parseContext.intermediate.getSource() == EShSourceHlsl) { + // must be binary + bool isUnsigned = false; + bool isInt64 = false; + bool isInt16 = false; + ppToken->name[len++] = (char)ch; + ch = getch(); + + // Check value + if ((ch == '0' || ch == '1')) + { + ival = 0; + do { + if (len < MaxTokenLength && ival <= 0x7fffffffffffffffull) { + ppToken->name[len++] = (char)ch; + if (ch == '0' || ch == '1') { + ii = ch - '0'; + } else { + pp->parseContext.ppError(ppToken->loc, "bad digit in binary literal", "", ""); + } + ival = (ival << 1) | ii; + } + else + { + if (! AlreadyComplained) { + if(len < MaxTokenLength) + pp->parseContext.ppError(ppToken->loc, "binary literal too big", "", ""); + else + pp->parseContext.ppError(ppToken->loc, "binary literal too long", "", ""); + AlreadyComplained = 1; + } + ival = 0xffffffffffffffffull; + } + ch = getch(); + } while (ch == '0' || ch == '1'); + } + else + { + pp->parseContext.ppError(ppToken->loc, "bad digit in binary literal", "", ""); + } + + // check type + if (ch == 'u' || ch == 'U') { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + isUnsigned = true; + + int nextCh = getch(); + if (nextCh == 'l' || nextCh == 'L') { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt64 = true; + } else + ungetch(); + + nextCh = getch(); + if ((nextCh == 's' || nextCh == 'S') && + pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)nextCh; + isInt16 = true; + } else + ungetch(); + } else if (ch == 'l' || ch == 'L') { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + isInt64 = true; + } else if ((ch == 's' || ch == 'S') && + pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + if (len < MaxTokenLength) + ppToken->name[len++] = (char)ch; + isInt16 = true; + } else { + ungetch(); + } + ppToken->name[len] = '\0'; + + // Assign value + if (isInt64 && pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + if (pp->ifdepth == 0) { + pp->parseContext.requireProfile(ppToken->loc, ~EEsProfile, + "64-bit binary literal"); + pp->parseContext.profileRequires(ppToken->loc, ~EEsProfile, 0, + Num_Int64_Extensions, Int64_Extensions, "64-bit binary literal"); + } + ppToken->i64val = ival; + return isUnsigned ? PpAtomConstUint64 : PpAtomConstInt64; + } else if (isInt16) { + if (pp->ifdepth == 0) { + if (pp->parseContext.intermediate.getSource() == EShSourceGlsl) { + pp->parseContext.requireProfile(ppToken->loc, ~EEsProfile, + "16-bit binary literal"); + pp->parseContext.profileRequires(ppToken->loc, ~EEsProfile, 0, + Num_Int16_Extensions, Int16_Extensions, "16-bit binary literal"); + } + } + ppToken->ival = (int)ival; + return isUnsigned ? PpAtomConstUint16 : PpAtomConstInt16; + } else { + ppToken->ival = (int)ival; + return isUnsigned ? PpAtomConstUint : PpAtomConstInt; + } } else { // could be octal integer or floating point, speculative pursue octal until it must be floating point @@ -692,7 +787,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->name[len++] = (char)ch; isUnsigned = true; -#ifndef GLSLANG_WEB int nextCh = getch(); if (nextCh == 'l' || nextCh == 'L') { if (len < MaxTokenLength) @@ -718,7 +812,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt16 = true; -#endif } else ungetch(); ppToken->name[len] = '\0'; @@ -781,7 +874,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) ppToken->name[len++] = (char)ch; isUnsigned = true; -#ifndef GLSLANG_WEB int nextCh = getch(); if (nextCh == 'l' || nextCh == 'L') { if (len < MaxTokenLength) @@ -807,7 +899,6 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken) if (len < MaxTokenLength) ppToken->name[len++] = (char)ch; isInt16 = true; -#endif } else ungetch(); diff --git a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp index 7ed58703f..e6ee64cf9 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp @@ -85,9 +85,6 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS #endif -#if (defined(_MSC_VER) && _MSC_VER < 1900 /*vs2015*/) -#define snprintf sprintf_s -#endif #include #include @@ -116,17 +113,15 @@ int TPpContext::TokenStream::getToken(TParseContextBase& parseContext, TPpToken int atom = stream[currentPos++].get(*ppToken); ppToken->loc = parseContext.getCurrentLoc(); -#ifndef GLSLANG_WEB // Check for ##, unless the current # is the last character if (atom == '#') { if (peekToken('#')) { parseContext.requireProfile(ppToken->loc, ~EEsProfile, "token pasting (##)"); - parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, 0, "token pasting (##)"); + parseContext.profileRequires(ppToken->loc, ~EEsProfile, 130, nullptr, "token pasting (##)"); currentPos++; atom = PpAtomPaste; } } -#endif return atom; } @@ -195,9 +190,9 @@ bool TPpContext::TokenStream::peekUntokenizedPasting() return pasting; } -void TPpContext::pushTokenStreamInput(TokenStream& ts, bool prepasting) +void TPpContext::pushTokenStreamInput(TokenStream& ts, bool prepasting, bool expanded) { - pushInput(new tTokenInput(this, &ts, prepasting)); + pushInput(new tTokenInput(this, &ts, prepasting, expanded)); ts.reset(); } diff --git a/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp b/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp index 9def592ba..7b5cd03fa 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/propagateNoContraction.cpp @@ -37,8 +37,6 @@ // propagate the 'noContraction' qualifier. // -#ifndef GLSLANG_WEB - #include "propagateNoContraction.h" #include @@ -423,7 +421,7 @@ getSymbolToDefinitionMappingAndPreciseSymbolIDs(const glslang::TIntermediate& in ReturnBranchNodeSet()); TIntermNode* root = intermediate.getTreeRoot(); - if (root == 0) + if (root == nullptr) return result_tuple; NodeMapping& symbol_definition_mapping = std::get<0>(result_tuple); @@ -865,6 +863,4 @@ void PropagateNoContraction(const glslang::TIntermediate& intermediate) precise_object_accesschains.erase(precise_object_accesschain); } } -}; - -#endif // GLSLANG_WEB +} diff --git a/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp b/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp index c76d9c6e2..b1b6aea38 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp +++ b/src/libraries/glslang/glslang/MachineIndependent/reflection.cpp @@ -33,8 +33,6 @@ // POSSIBILITY OF SUCH DAMAGE. // -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) - #include "../Include/Common.h" #include "reflection.h" #include "LiveTraverser.h" @@ -251,7 +249,7 @@ class TReflectionTraverser : public TIntermTraverser { void blowUpActiveAggregate(const TType& baseType, const TString& baseName, const TList& derefs, TList::const_iterator deref, int offset, int blockIndex, int arraySize, int topLevelArraySize, int topLevelArrayStride, TStorageQualifier baseStorage, bool active, - const TConstUnionArray* constArray = nullptr) + const TConstUnionArray* constArray = nullptr) { // when strictArraySuffix is enabled, we closely follow the rules from ARB_program_interface_query. // Broadly: @@ -266,18 +264,18 @@ class TReflectionTraverser : public TIntermTraverser { // process the part of the dereference chain that was explicit in the shader TString name = baseName; const TType* terminalType = &baseType; - const TConstUnionArray* terminalConstArray = constArray; + const TConstUnionArray* terminalConstArray = constArray; for (; deref != derefs.end(); ++deref) { TIntermBinary* visitNode = *deref; terminalType = &visitNode->getType(); - if (visitNode->getAsSymbolNode()) - terminalConstArray = &visitNode->getAsSymbolNode()->getConstArray(); - else if (visitNode->getAsConstantUnion()) - terminalConstArray = &visitNode->getAsConstantUnion()->getConstArray(); - else if (visitNode->getLeft() != nullptr && visitNode->getLeft()->getAsSymbolNode()) - terminalConstArray = &visitNode->getLeft()->getAsSymbolNode()->getConstArray(); - else - terminalConstArray = nullptr; + if (visitNode->getAsSymbolNode()) + terminalConstArray = &visitNode->getAsSymbolNode()->getConstArray(); + else if (visitNode->getAsConstantUnion()) + terminalConstArray = &visitNode->getAsConstantUnion()->getConstArray(); + else if (visitNode->getLeft() != nullptr && visitNode->getLeft()->getAsSymbolNode()) + terminalConstArray = &visitNode->getLeft()->getAsSymbolNode()->getConstArray(); + else + terminalConstArray = nullptr; int index; switch (visitNode->getOp()) { case EOpIndexIndirect: { @@ -692,7 +690,7 @@ class TReflectionTraverser : public TIntermTraverser { } // For a binary operation indexing into an aggregate, chase down the base of the aggregate. - // Return 0 if the topology does not fit this situation. + // Return nullptr if the topology does not fit this situation. TIntermSymbol* findBase(const TIntermBinary* node) { TIntermSymbol *base = node->getLeft()->getAsSymbolNode(); @@ -1280,5 +1278,3 @@ void TReflection::dump() } } // end namespace glslang - -#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/src/libraries/glslang/glslang/MachineIndependent/reflection.h b/src/libraries/glslang/glslang/MachineIndependent/reflection.h index 5af4467c1..221d93f8b 100644 --- a/src/libraries/glslang/glslang/MachineIndependent/reflection.h +++ b/src/libraries/glslang/glslang/MachineIndependent/reflection.h @@ -33,8 +33,6 @@ // POSSIBILITY OF SUCH DAMAGE. // -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) - #ifndef _REFLECTION_INCLUDED #define _REFLECTION_INCLUDED @@ -219,5 +217,3 @@ class TReflection { } // end namespace glslang #endif // _REFLECTION_INCLUDED - -#endif // !GLSLANG_WEB && !GLSLANG_ANGLE diff --git a/src/libraries/glslang/glslang/MachineIndependent/span.h b/src/libraries/glslang/glslang/MachineIndependent/span.h new file mode 100644 index 000000000..bd705fead --- /dev/null +++ b/src/libraries/glslang/glslang/MachineIndependent/span.h @@ -0,0 +1,92 @@ +#pragma once + +// +// Copyright (C) 2023 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. +// + +// Partial implementation of std::span for C++11 +// Replace with std::span if repo standard is bumped to C++20 +// +// This code was copied from https://github.com/KhronosGroup/Vulkan-ValidationLayers/blob/main/layers/containers/custom_containers.h +template +class span { + public: + using pointer = T *; + using const_pointer = T const *; + using iterator = pointer; + using const_iterator = const_pointer; + + span() = default; + span(pointer start, size_t n) : data_(start), count_(n) {} + template + span(Iterator start, Iterator end) : data_(&(*start)), count_(end - start) {} + template + span(Container &c) : data_(c.data()), count_(c.size()) {} + + iterator begin() { return data_; } + const_iterator begin() const { return data_; } + + iterator end() { return data_ + count_; } + const_iterator end() const { return data_ + count_; } + + T &operator[](int i) { return data_[i]; } + const T &operator[](int i) const { return data_[i]; } + + T &front() { return *data_; } + const T &front() const { return *data_; } + + T &back() { return *(data_ + (count_ - 1)); } + const T &back() const { return *(data_ + (count_ - 1)); } + + size_t size() const { return count_; } + bool empty() const { return count_ == 0; } + + pointer data() { return data_; } + const_pointer data() const { return data_; } + + private: + pointer data_ = {}; + size_t count_ = 0; +}; + +// +// Allow type inference that using the constructor doesn't allow in C++11 +template +span make_span(T *begin, size_t count) { + return span(begin, count); +} +template +span make_span(T *begin, T *end) { + return make_span(begin, end); +} diff --git a/src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp b/src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp index 81da99c2c..fbb51f7bd 100644 --- a/src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp +++ b/src/libraries/glslang/glslang/OSDependent/Unix/ossource.cpp @@ -36,15 +36,8 @@ // This file contains the Linux-specific functions // #include "../osinclude.h" -#include "../../../OGLCompilersDLL/InitializeDll.h" -#include -#include -#include -#include -#include #include -#include #if !defined(__Fuchsia__) #include @@ -52,150 +45,6 @@ namespace glslang { -// -// Thread cleanup -// - -// -// Wrapper for Linux call to DetachThread. This is required as pthread_cleanup_push() expects -// the cleanup routine to return void. -// -static void DetachThreadLinux(void *) -{ - DetachThread(); -} - -// -// Registers cleanup handler, sets cancel type and state, and executes the thread specific -// cleanup handler. This function will be called in the Standalone.cpp for regression -// testing. When OpenGL applications are run with the driver code, Linux OS does the -// thread cleanup. -// -void OS_CleanupThreadData(void) -{ -#if defined(__ANDROID__) || defined(__Fuchsia__) - DetachThreadLinux(NULL); -#else - int old_cancel_state, old_cancel_type; - void *cleanupArg = NULL; - - // - // Set thread cancel state and push cleanup handler. - // - pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancel_state); - pthread_cleanup_push(DetachThreadLinux, (void *) cleanupArg); - - // - // Put the thread in deferred cancellation mode. - // - pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &old_cancel_type); - - // - // Pop cleanup handler and execute it prior to unregistering the cleanup handler. - // - pthread_cleanup_pop(1); - - // - // Restore the thread's previous cancellation mode. - // - pthread_setcanceltype(old_cancel_state, NULL); -#endif -} - -// -// Thread Local Storage Operations -// -inline OS_TLSIndex PthreadKeyToTLSIndex(pthread_key_t key) -{ - return (OS_TLSIndex)((uintptr_t)key + 1); -} - -inline pthread_key_t TLSIndexToPthreadKey(OS_TLSIndex nIndex) -{ - return (pthread_key_t)((uintptr_t)nIndex - 1); -} - -OS_TLSIndex OS_AllocTLSIndex() -{ - pthread_key_t pPoolIndex; - - // - // Create global pool key. - // - if ((pthread_key_create(&pPoolIndex, NULL)) != 0) { - assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage"); - return OS_INVALID_TLS_INDEX; - } - else - return PthreadKeyToTLSIndex(pPoolIndex); -} - -bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue) -{ - if (nIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "OS_SetTLSValue(): Invalid TLS Index"); - return false; - } - - if (pthread_setspecific(TLSIndexToPthreadKey(nIndex), lpvValue) == 0) - return true; - else - return false; -} - -void* OS_GetTLSValue(OS_TLSIndex nIndex) -{ - // - // This function should return 0 if nIndex is invalid. - // - assert(nIndex != OS_INVALID_TLS_INDEX); - return pthread_getspecific(TLSIndexToPthreadKey(nIndex)); -} - -bool OS_FreeTLSIndex(OS_TLSIndex nIndex) -{ - if (nIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "OS_SetTLSValue(): Invalid TLS Index"); - return false; - } - - // - // Delete the global pool key. - // - if (pthread_key_delete(TLSIndexToPthreadKey(nIndex)) == 0) - return true; - else - return false; -} - -namespace { - pthread_mutex_t gMutex; -} - -static void InitMutex(void) -{ - pthread_mutexattr_t mutexattr; - pthread_mutexattr_init(&mutexattr); - pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&gMutex, &mutexattr); -} - -void InitGlobalLock() -{ - static pthread_once_t once = PTHREAD_ONCE_INIT; - pthread_once(&once, InitMutex); -} - -void GetGlobalLock() -{ - pthread_mutex_lock(&gMutex); -} - -void ReleaseGlobalLock() -{ - pthread_mutex_unlock(&gMutex); -} - // #define DUMP_COUNTERS void OS_DumpMemoryCounters() diff --git a/src/libraries/glslang/glslang/OSDependent/Web/glslang.js.cpp b/src/libraries/glslang/glslang/OSDependent/Web/glslang.js.cpp index f2306a609..c820da6aa 100644 --- a/src/libraries/glslang/glslang/OSDependent/Web/glslang.js.cpp +++ b/src/libraries/glslang/glslang/OSDependent/Web/glslang.js.cpp @@ -141,6 +141,15 @@ const TBuiltInResource DefaultTBuiltInResource = { /* .maxTaskWorkGroupSizeY_NV = */ 1, /* .maxTaskWorkGroupSizeZ_NV = */ 1, /* .maxMeshViewCountNV = */ 4, + /* .maxMeshOutputVerticesEXT = */ 256, + /* .maxMeshOutputPrimitivesEXT = */ 512, + /* .maxMeshWorkGroupSizeX_EXT = */ 32, + /* .maxMeshWorkGroupSizeY_EXT = */ 1, + /* .maxMeshWorkGroupSizeZ_EXT = */ 1, + /* .maxTaskWorkGroupSizeX_EXT = */ 32, + /* .maxTaskWorkGroupSizeY_EXT = */ 1, + /* .maxTaskWorkGroupSizeZ_EXT = */ 1, + /* .maxMeshViewCountEXT = */ 4, /* .maxDualSourceDrawBuffersEXT = */ 1, /* .limits = */ { diff --git a/src/libraries/glslang/glslang/OSDependent/Web/glslang.pre.js b/src/libraries/glslang/glslang/OSDependent/Web/glslang.pre.js index 46a569506..390390e99 100644 --- a/src/libraries/glslang/glslang/OSDependent/Web/glslang.pre.js +++ b/src/libraries/glslang/glslang/OSDependent/Web/glslang.pre.js @@ -25,7 +25,7 @@ Module['compileGLSLZeroCopy'] = function(glsl, shader_stage, gen_debug, spirv_ve var p_output = Module['_malloc'](4); var p_output_len = Module['_malloc'](4); - var id = ccall('convert_glsl_to_spirv', + var id = Module['ccall']('convert_glsl_to_spirv', 'number', ['string', 'number', 'boolean', 'number', 'number', 'number'], [glsl, shader_stage_int, gen_debug, spirv_version_int, p_output, p_output_len]); diff --git a/src/libraries/glslang/glslang/OSDependent/Windows/ossource.cpp b/src/libraries/glslang/glslang/OSDependent/Windows/ossource.cpp index 870840c56..d7f89f71b 100644 --- a/src/libraries/glslang/glslang/OSDependent/Windows/ossource.cpp +++ b/src/libraries/glslang/glslang/OSDependent/Windows/ossource.cpp @@ -37,11 +37,9 @@ #define STRICT #define VC_EXTRALEAN 1 #include -#include #include #include #include -#include // // This file contains the Window-OS-specific functions @@ -53,84 +51,6 @@ namespace glslang { -inline OS_TLSIndex ToGenericTLSIndex (DWORD handle) -{ - return (OS_TLSIndex)((uintptr_t)handle + 1); -} - -inline DWORD ToNativeTLSIndex (OS_TLSIndex nIndex) -{ - return (DWORD)((uintptr_t)nIndex - 1); -} - -// -// Thread Local Storage Operations -// -OS_TLSIndex OS_AllocTLSIndex() -{ - DWORD dwIndex = TlsAlloc(); - if (dwIndex == TLS_OUT_OF_INDEXES) { - assert(0 && "OS_AllocTLSIndex(): Unable to allocate Thread Local Storage"); - return OS_INVALID_TLS_INDEX; - } - - return ToGenericTLSIndex(dwIndex); -} - -bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue) -{ - if (nIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "OS_SetTLSValue(): Invalid TLS Index"); - return false; - } - - if (TlsSetValue(ToNativeTLSIndex(nIndex), lpvValue)) - return true; - else - return false; -} - -void* OS_GetTLSValue(OS_TLSIndex nIndex) -{ - assert(nIndex != OS_INVALID_TLS_INDEX); - return TlsGetValue(ToNativeTLSIndex(nIndex)); -} - -bool OS_FreeTLSIndex(OS_TLSIndex nIndex) -{ - if (nIndex == OS_INVALID_TLS_INDEX) { - assert(0 && "OS_SetTLSValue(): Invalid TLS Index"); - return false; - } - - if (TlsFree(ToNativeTLSIndex(nIndex))) - return true; - else - return false; -} - -HANDLE GlobalLock; - -void InitGlobalLock() -{ - GlobalLock = CreateMutex(0, false, 0); -} - -void GetGlobalLock() -{ - WaitForSingleObject(GlobalLock, INFINITE); -} - -void ReleaseGlobalLock() -{ - ReleaseMutex(GlobalLock); -} - -unsigned int __stdcall EnterGenericThread (void* entry) -{ - return ((TThreadEntrypoint)entry)(0); -} - //#define DUMP_COUNTERS void OS_DumpMemoryCounters() diff --git a/src/libraries/glslang/glslang/OSDependent/osinclude.h b/src/libraries/glslang/glslang/OSDependent/osinclude.h index 218abe4f2..0d677e4af 100644 --- a/src/libraries/glslang/glslang/OSDependent/osinclude.h +++ b/src/libraries/glslang/glslang/OSDependent/osinclude.h @@ -37,25 +37,6 @@ namespace glslang { -// -// Thread Local Storage Operations -// -typedef void* OS_TLSIndex; -#define OS_INVALID_TLS_INDEX ((void*)0) - -OS_TLSIndex OS_AllocTLSIndex(); -bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue); -bool OS_FreeTLSIndex(OS_TLSIndex nIndex); -void* OS_GetTLSValue(OS_TLSIndex nIndex); - -void InitGlobalLock(); -void GetGlobalLock(); -void ReleaseGlobalLock(); - -typedef unsigned int (*TThreadEntrypoint)(void*); - -void OS_CleanupThreadData(void); - void OS_DumpMemoryCounters(); } // end namespace glslang diff --git a/src/libraries/glslang/glslang/OSDependent/Windows/main.cpp b/src/libraries/glslang/glslang/Public/ResourceLimits.h similarity index 61% rename from src/libraries/glslang/glslang/OSDependent/Windows/main.cpp rename to src/libraries/glslang/glslang/Public/ResourceLimits.h index 0217e0a64..f70be8172 100644 --- a/src/libraries/glslang/glslang/OSDependent/Windows/main.cpp +++ b/src/libraries/glslang/glslang/Public/ResourceLimits.h @@ -1,5 +1,6 @@ // -// Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +// Copyright (C) 2016 Google, Inc. +// // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -14,7 +15,7 @@ // disclaimer in the documentation and/or other materials provided // with the distribution. // -// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// 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. // @@ -30,45 +31,27 @@ // 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 "glslang/OGLCompilersDLL/InitializeDll.h" - -#define STRICT -#define VC_EXTRALEAN 1 -#include -#include - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) -{ - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - if (! glslang::InitProcess()) - return FALSE; - break; - case DLL_THREAD_ATTACH: +#ifndef _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_ +#define _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_ - if (! glslang::InitThread()) - return FALSE; - break; +#include - case DLL_THREAD_DETACH: +#include "../Include/ResourceLimits.h" - if (! glslang::DetachThread()) - return FALSE; - break; +// Return pointer to user-writable Resource to pass through API in +// future-proof way. +extern TBuiltInResource* GetResources(); - case DLL_PROCESS_DETACH: +// These are the default resources for TBuiltInResources, used for both +// - parsing this string for the case where the user didn't supply one, +// - dumping out a template for user construction of a config file. +extern const TBuiltInResource* GetDefaultResources(); - glslang::DetachProcess(); - break; +// Returns the DefaultTBuiltInResource as a human-readable string. +std::string GetDefaultTBuiltInResourceString(); - default: - assert(0 && "DllMain(): Reason for calling DLL Main is unknown"); - return FALSE; - } +// Decodes the resource limits from |config| to |resources|. +void DecodeResourceLimits(TBuiltInResource* resources, char* config); - return TRUE; -} +#endif // _STAND_ALONE_RESOURCE_LIMITS_INCLUDED_ diff --git a/src/libraries/glslang/glslang/Public/ShaderLang.h b/src/libraries/glslang/glslang/Public/ShaderLang.h index 1fd692c7c..e9bb4cb81 100644 --- a/src/libraries/glslang/glslang/Public/ShaderLang.h +++ b/src/libraries/glslang/glslang/Public/ShaderLang.h @@ -108,8 +108,10 @@ typedef enum { EShLangMissNV = EShLangMiss, EShLangCallable, EShLangCallableNV = EShLangCallable, - EShLangTaskNV, - EShLangMeshNV, + EShLangTask, + EShLangTaskNV = EShLangTask, + EShLangMesh, + EShLangMeshNV = EShLangMesh, LAST_ELEMENT_MARKER(EShLangCount), } EShLanguage; // would be better as stage, but this is ancient now @@ -132,8 +134,10 @@ typedef enum : unsigned { EShLangMissNVMask = EShLangMissMask, EShLangCallableMask = (1 << EShLangCallable), EShLangCallableNVMask = EShLangCallableMask, - EShLangTaskNVMask = (1 << EShLangTaskNV), - EShLangMeshNVMask = (1 << EShLangMeshNV), + EShLangTaskMask = (1 << EShLangTask), + EShLangTaskNVMask = EShLangTaskMask, + EShLangMeshMask = (1 << EShLangMesh), + EShLangMeshNVMask = EShLangMeshMask, LAST_ELEMENT_MARKER(EShLanguageMaskCount), } EShLanguageMask; @@ -151,8 +155,8 @@ typedef enum { typedef enum { EShClientNone, // use when there is no client, e.g. for validation - EShClientVulkan, - EShClientOpenGL, + EShClientVulkan, // as GLSL dialect, specifies KHR_vulkan_glsl extension + EShClientOpenGL, // as GLSL dialect, specifies ARB_gl_spirv extension LAST_ELEMENT_MARKER(EShClientCount), } EShClient; @@ -164,12 +168,12 @@ typedef enum { } EShTargetLanguage; typedef enum { - EShTargetUniversal = 0, // Universal EShTargetVulkan_1_0 = (1 << 22), // Vulkan 1.0 EShTargetVulkan_1_1 = (1 << 22) | (1 << 12), // Vulkan 1.1 EShTargetVulkan_1_2 = (1 << 22) | (2 << 12), // Vulkan 1.2 + EShTargetVulkan_1_3 = (1 << 22) | (3 << 12), // Vulkan 1.3 EShTargetOpenGL_450 = 450, // OpenGL - LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 4), + LAST_ELEMENT_MARKER(EShTargetClientVersionCount = 5), } EShTargetClientVersion; typedef EShTargetClientVersion EshTargetClientVersion; @@ -265,6 +269,7 @@ enum EShMessages : unsigned { EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (for samplers and semantics) EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table + EShMsgEnhanced = (1 << 15), // enhanced message readability LAST_ELEMENT_MARKER(EShMsgCount), }; @@ -301,7 +306,7 @@ typedef struct { // // ShHandle held by but opaque to the driver. It is allocated, -// managed, and de-allocated by the compiler/linker. It's contents +// managed, and de-allocated by the compiler/linker. Its contents // are defined by and used by the compiler and linker. For example, // symbol table information and object code passed from the compiler // to the linker can be stored where ShHandle points. @@ -314,8 +319,8 @@ typedef void* ShHandle; // Driver calls these to create and destroy compiler/linker // objects. // -GLSLANG_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int debugOptions); // one per shader -GLSLANG_EXPORT ShHandle ShConstructLinker(const EShExecutable, int debugOptions); // one per shader pair +GLSLANG_EXPORT ShHandle ShConstructCompiler(const EShLanguage, int /*debugOptions unused*/); // one per shader +GLSLANG_EXPORT ShHandle ShConstructLinker(const EShExecutable, int /*debugOptions unused*/); // one per shader pair GLSLANG_EXPORT ShHandle ShConstructUniformMap(); // one per uniform namespace (currently entire program object) GLSLANG_EXPORT void ShDestruct(ShHandle); @@ -326,18 +331,13 @@ GLSLANG_EXPORT void ShDestruct(ShHandle); // The info-log should be written by ShCompile into // ShHandle, so it can answer future queries. // -GLSLANG_EXPORT int ShCompile( - const ShHandle, - const char* const shaderStrings[], - const int numStrings, - const int* lengths, - const EShOptimizationLevel, - const TBuiltInResource *resources, - int debugOptions, - int defaultVersion = 110, // use 100 for ES environment, overridden by #version in shader - bool forwardCompatible = false, // give errors for use of deprecated features - EShMessages messages = EShMsgDefault // warnings and errors - ); +GLSLANG_EXPORT int ShCompile(const ShHandle, const char* const shaderStrings[], const int numStrings, + const int* lengths, const EShOptimizationLevel, const TBuiltInResource* resources, + int, // debugOptions unused + int defaultVersion = 110, // use 100 for ES environment, overridden by #version in shader + bool forwardCompatible = false, // give errors for use of deprecated features + EShMessages messages = EShMsgDefault // warnings and errors +); GLSLANG_EXPORT int ShLinkExt( const ShHandle, // linker object @@ -471,6 +471,8 @@ class TShader { GLSLANG_EXPORT void setSourceEntryPoint(const char* sourceEntryPointName); GLSLANG_EXPORT void addProcesses(const std::vector&); GLSLANG_EXPORT void setUniqueId(unsigned long long id); + GLSLANG_EXPORT void setOverrideVersion(int version); + GLSLANG_EXPORT void setDebugInfo(bool debugInfo); // IO resolver binding data: see comments in ShaderLang.cpp GLSLANG_EXPORT void setShiftBinding(TResourceType res, unsigned int base); @@ -489,6 +491,7 @@ class TShader { GLSLANG_EXPORT void setUniformLocationBase(int base); GLSLANG_EXPORT void setInvertY(bool invert); GLSLANG_EXPORT void setDxPositionW(bool dxPosW); + GLSLANG_EXPORT void setEnhancedMsgs(); #ifdef ENABLE_HLSL GLSLANG_EXPORT void setHlslIoMapping(bool hlslIoMap); GLSLANG_EXPORT void setFlattenUniformArrays(bool flatten); @@ -516,11 +519,14 @@ class TShader { // 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. + // For example, to choose the Vulkan dialect of GLSL defined by + // version 100 of the KHR_vulkan_glsl extension: lang = EShSourceGlsl, + // dialect = EShClientVulkan, and version = 100. // // 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. + // setEnvClient: The client that will be hosting the execution, and its 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. @@ -563,6 +569,9 @@ class TShader { void setEnvInputVulkanRulesRelaxed() { environment.input.vulkanRulesRelaxed = true; } bool getEnvInputVulkanRulesRelaxed() const { return environment.input.vulkanRulesRelaxed; } + void setCompileOnly() { compileOnly = true; } + bool getCompileOnly() const { return compileOnly; } + // Interface to #include handlers. // // To support #include, a client of Glslang does the following: @@ -707,16 +716,20 @@ class TShader { // a function in the source string can be renamed FROM this TO the name given in setEntryPoint. std::string sourceEntryPointName; + // overrides #version in shader source or default version if #version isn't present + int overrideVersion; + TEnvironment environment; + // Indicates this shader is meant to be used without linking + bool compileOnly = false; + friend class TProgram; private: TShader& operator=(TShader&); }; -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) - // // A reflection database and its interface, consistent with the OpenGL API reflection queries. // @@ -727,7 +740,7 @@ class TObjectReflection { GLSLANG_EXPORT TObjectReflection(const std::string& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex, const TConstUnionArray* pConstArray = nullptr); const TType* getType() const { return type; } - const TConstUnionArray* getConstArray() const { return constArray; } + const TConstUnionArray* getConstArray() const { return constArray; } GLSLANG_EXPORT int getBinding() const; GLSLANG_EXPORT void dump() const; static TObjectReflection badReflection() { return TObjectReflection(); } @@ -752,7 +765,7 @@ class TObjectReflection { } const TType* type; - const TConstUnionArray* constArray; + const TConstUnionArray* constArray; }; class TReflection; @@ -835,8 +848,6 @@ class TIoMapResolver virtual void addStage(EShLanguage stage, TIntermediate& stageIntermediate) = 0; }; -#endif // !GLSLANG_WEB && !GLSLANG_ANGLE - // 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() // for all shaders, call link(). @@ -856,8 +867,6 @@ class TProgram { TIntermediate* getIntermediate(EShLanguage stage) const { return intermediate[stage]; } -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) - // Reflection Interface // call first, to do liveness analysis, index mapping, etc.; returns false on failure @@ -950,7 +959,6 @@ class TProgram { // If resolver is not provided it uses the previous approach // and respects auto assignment and offsets. GLSLANG_EXPORT bool mapIO(TIoMapResolver* pResolver = nullptr, TIoMapper* pIoMapper = nullptr); -#endif // !GLSLANG_WEB && !GLSLANG_ANGLE protected: GLSLANG_EXPORT bool linkStage(EShLanguage, EShMessages); @@ -961,9 +969,7 @@ class TProgram { TIntermediate* intermediate[EShLangCount]; bool newedIntermediate[EShLangCount]; // track which intermediate were "new" versus reusing a singleton unit in a stage TInfoSink* infoSink; -#if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE) TReflection* reflection; -#endif bool linked; private: diff --git a/src/libraries/glslang/glslang/ResourceLimits/ResourceLimits.cpp b/src/libraries/glslang/glslang/ResourceLimits/ResourceLimits.cpp new file mode 100644 index 000000000..c255604b9 --- /dev/null +++ b/src/libraries/glslang/glslang/ResourceLimits/ResourceLimits.cpp @@ -0,0 +1,542 @@ +// +// 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. + +#include +#include +#include +#include + +#include "../../glslang/Public/ResourceLimits.h" + +TBuiltInResource Resources; + +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, + /* .maxMeshOutputVerticesEXT = */ 256, + /* .maxMeshOutputPrimitivesEXT = */ 256, + /* .maxMeshWorkGroupSizeX_EXT = */ 128, + /* .maxMeshWorkGroupSizeY_EXT = */ 128, + /* .maxMeshWorkGroupSizeZ_EXT = */ 128, + /* .maxTaskWorkGroupSizeX_EXT = */ 128, + /* .maxTaskWorkGroupSizeY_EXT = */ 128, + /* .maxTaskWorkGroupSizeZ_EXT = */ 128, + /* .maxMeshViewCountEXT = */ 4, + /* .maxDualSourceDrawBuffersEXT = */ 1, + + /* .limits = */ { + /* .nonInductiveForLoops = */ 1, + /* .whileLoops = */ 1, + /* .doWhileLoops = */ 1, + /* .generalUniformIndexing = */ 1, + /* .generalAttributeMatrixVectorIndexing = */ 1, + /* .generalVaryingIndexing = */ 1, + /* .generalSamplerIndexing = */ 1, + /* .generalVariableIndexing = */ 1, + /* .generalConstantMatrixVectorIndexing = */ 1, + }}; + +std::string GetDefaultTBuiltInResourceString() +{ + std::ostringstream ostream; + + ostream << "MaxLights " << DefaultTBuiltInResource.maxLights << "\n" + << "MaxClipPlanes " << DefaultTBuiltInResource.maxClipPlanes << "\n" + << "MaxTextureUnits " << DefaultTBuiltInResource.maxTextureUnits << "\n" + << "MaxTextureCoords " << DefaultTBuiltInResource.maxTextureCoords << "\n" + << "MaxVertexAttribs " << DefaultTBuiltInResource.maxVertexAttribs << "\n" + << "MaxVertexUniformComponents " << DefaultTBuiltInResource.maxVertexUniformComponents << "\n" + << "MaxVaryingFloats " << DefaultTBuiltInResource.maxVaryingFloats << "\n" + << "MaxVertexTextureImageUnits " << DefaultTBuiltInResource.maxVertexTextureImageUnits << "\n" + << "MaxCombinedTextureImageUnits " << DefaultTBuiltInResource.maxCombinedTextureImageUnits << "\n" + << "MaxTextureImageUnits " << DefaultTBuiltInResource.maxTextureImageUnits << "\n" + << "MaxFragmentUniformComponents " << DefaultTBuiltInResource.maxFragmentUniformComponents << "\n" + << "MaxDrawBuffers " << DefaultTBuiltInResource.maxDrawBuffers << "\n" + << "MaxVertexUniformVectors " << DefaultTBuiltInResource.maxVertexUniformVectors << "\n" + << "MaxVaryingVectors " << DefaultTBuiltInResource.maxVaryingVectors << "\n" + << "MaxFragmentUniformVectors " << DefaultTBuiltInResource.maxFragmentUniformVectors << "\n" + << "MaxVertexOutputVectors " << DefaultTBuiltInResource.maxVertexOutputVectors << "\n" + << "MaxFragmentInputVectors " << DefaultTBuiltInResource.maxFragmentInputVectors << "\n" + << "MinProgramTexelOffset " << DefaultTBuiltInResource.minProgramTexelOffset << "\n" + << "MaxProgramTexelOffset " << DefaultTBuiltInResource.maxProgramTexelOffset << "\n" + << "MaxClipDistances " << DefaultTBuiltInResource.maxClipDistances << "\n" + << "MaxComputeWorkGroupCountX " << DefaultTBuiltInResource.maxComputeWorkGroupCountX << "\n" + << "MaxComputeWorkGroupCountY " << DefaultTBuiltInResource.maxComputeWorkGroupCountY << "\n" + << "MaxComputeWorkGroupCountZ " << DefaultTBuiltInResource.maxComputeWorkGroupCountZ << "\n" + << "MaxComputeWorkGroupSizeX " << DefaultTBuiltInResource.maxComputeWorkGroupSizeX << "\n" + << "MaxComputeWorkGroupSizeY " << DefaultTBuiltInResource.maxComputeWorkGroupSizeY << "\n" + << "MaxComputeWorkGroupSizeZ " << DefaultTBuiltInResource.maxComputeWorkGroupSizeZ << "\n" + << "MaxComputeUniformComponents " << DefaultTBuiltInResource.maxComputeUniformComponents << "\n" + << "MaxComputeTextureImageUnits " << DefaultTBuiltInResource.maxComputeTextureImageUnits << "\n" + << "MaxComputeImageUniforms " << DefaultTBuiltInResource.maxComputeImageUniforms << "\n" + << "MaxComputeAtomicCounters " << DefaultTBuiltInResource.maxComputeAtomicCounters << "\n" + << "MaxComputeAtomicCounterBuffers " << DefaultTBuiltInResource.maxComputeAtomicCounterBuffers << "\n" + << "MaxVaryingComponents " << DefaultTBuiltInResource.maxVaryingComponents << "\n" + << "MaxVertexOutputComponents " << DefaultTBuiltInResource.maxVertexOutputComponents << "\n" + << "MaxGeometryInputComponents " << DefaultTBuiltInResource.maxGeometryInputComponents << "\n" + << "MaxGeometryOutputComponents " << DefaultTBuiltInResource.maxGeometryOutputComponents << "\n" + << "MaxFragmentInputComponents " << DefaultTBuiltInResource.maxFragmentInputComponents << "\n" + << "MaxImageUnits " << DefaultTBuiltInResource.maxImageUnits << "\n" + << "MaxCombinedImageUnitsAndFragmentOutputs " << DefaultTBuiltInResource.maxCombinedImageUnitsAndFragmentOutputs << "\n" + << "MaxCombinedShaderOutputResources " << DefaultTBuiltInResource.maxCombinedShaderOutputResources << "\n" + << "MaxImageSamples " << DefaultTBuiltInResource.maxImageSamples << "\n" + << "MaxVertexImageUniforms " << DefaultTBuiltInResource.maxVertexImageUniforms << "\n" + << "MaxTessControlImageUniforms " << DefaultTBuiltInResource.maxTessControlImageUniforms << "\n" + << "MaxTessEvaluationImageUniforms " << DefaultTBuiltInResource.maxTessEvaluationImageUniforms << "\n" + << "MaxGeometryImageUniforms " << DefaultTBuiltInResource.maxGeometryImageUniforms << "\n" + << "MaxFragmentImageUniforms " << DefaultTBuiltInResource.maxFragmentImageUniforms << "\n" + << "MaxCombinedImageUniforms " << DefaultTBuiltInResource.maxCombinedImageUniforms << "\n" + << "MaxGeometryTextureImageUnits " << DefaultTBuiltInResource.maxGeometryTextureImageUnits << "\n" + << "MaxGeometryOutputVertices " << DefaultTBuiltInResource.maxGeometryOutputVertices << "\n" + << "MaxGeometryTotalOutputComponents " << DefaultTBuiltInResource.maxGeometryTotalOutputComponents << "\n" + << "MaxGeometryUniformComponents " << DefaultTBuiltInResource.maxGeometryUniformComponents << "\n" + << "MaxGeometryVaryingComponents " << DefaultTBuiltInResource.maxGeometryVaryingComponents << "\n" + << "MaxTessControlInputComponents " << DefaultTBuiltInResource.maxTessControlInputComponents << "\n" + << "MaxTessControlOutputComponents " << DefaultTBuiltInResource.maxTessControlOutputComponents << "\n" + << "MaxTessControlTextureImageUnits " << DefaultTBuiltInResource.maxTessControlTextureImageUnits << "\n" + << "MaxTessControlUniformComponents " << DefaultTBuiltInResource.maxTessControlUniformComponents << "\n" + << "MaxTessControlTotalOutputComponents " << DefaultTBuiltInResource.maxTessControlTotalOutputComponents << "\n" + << "MaxTessEvaluationInputComponents " << DefaultTBuiltInResource.maxTessEvaluationInputComponents << "\n" + << "MaxTessEvaluationOutputComponents " << DefaultTBuiltInResource.maxTessEvaluationOutputComponents << "\n" + << "MaxTessEvaluationTextureImageUnits " << DefaultTBuiltInResource.maxTessEvaluationTextureImageUnits << "\n" + << "MaxTessEvaluationUniformComponents " << DefaultTBuiltInResource.maxTessEvaluationUniformComponents << "\n" + << "MaxTessPatchComponents " << DefaultTBuiltInResource.maxTessPatchComponents << "\n" + << "MaxPatchVertices " << DefaultTBuiltInResource.maxPatchVertices << "\n" + << "MaxTessGenLevel " << DefaultTBuiltInResource.maxTessGenLevel << "\n" + << "MaxViewports " << DefaultTBuiltInResource.maxViewports << "\n" + << "MaxVertexAtomicCounters " << DefaultTBuiltInResource.maxVertexAtomicCounters << "\n" + << "MaxTessControlAtomicCounters " << DefaultTBuiltInResource.maxTessControlAtomicCounters << "\n" + << "MaxTessEvaluationAtomicCounters " << DefaultTBuiltInResource.maxTessEvaluationAtomicCounters << "\n" + << "MaxGeometryAtomicCounters " << DefaultTBuiltInResource.maxGeometryAtomicCounters << "\n" + << "MaxFragmentAtomicCounters " << DefaultTBuiltInResource.maxFragmentAtomicCounters << "\n" + << "MaxCombinedAtomicCounters " << DefaultTBuiltInResource.maxCombinedAtomicCounters << "\n" + << "MaxAtomicCounterBindings " << DefaultTBuiltInResource.maxAtomicCounterBindings << "\n" + << "MaxVertexAtomicCounterBuffers " << DefaultTBuiltInResource.maxVertexAtomicCounterBuffers << "\n" + << "MaxTessControlAtomicCounterBuffers " << DefaultTBuiltInResource.maxTessControlAtomicCounterBuffers << "\n" + << "MaxTessEvaluationAtomicCounterBuffers " << DefaultTBuiltInResource.maxTessEvaluationAtomicCounterBuffers << "\n" + << "MaxGeometryAtomicCounterBuffers " << DefaultTBuiltInResource.maxGeometryAtomicCounterBuffers << "\n" + << "MaxFragmentAtomicCounterBuffers " << DefaultTBuiltInResource.maxFragmentAtomicCounterBuffers << "\n" + << "MaxCombinedAtomicCounterBuffers " << DefaultTBuiltInResource.maxCombinedAtomicCounterBuffers << "\n" + << "MaxAtomicCounterBufferSize " << DefaultTBuiltInResource.maxAtomicCounterBufferSize << "\n" + << "MaxTransformFeedbackBuffers " << DefaultTBuiltInResource.maxTransformFeedbackBuffers << "\n" + << "MaxTransformFeedbackInterleavedComponents " << DefaultTBuiltInResource.maxTransformFeedbackInterleavedComponents << "\n" + << "MaxCullDistances " << DefaultTBuiltInResource.maxCullDistances << "\n" + << "MaxCombinedClipAndCullDistances " << DefaultTBuiltInResource.maxCombinedClipAndCullDistances << "\n" + << "MaxSamples " << DefaultTBuiltInResource.maxSamples << "\n" + << "MaxMeshOutputVerticesNV " << DefaultTBuiltInResource.maxMeshOutputVerticesNV << "\n" + << "MaxMeshOutputPrimitivesNV " << DefaultTBuiltInResource.maxMeshOutputPrimitivesNV << "\n" + << "MaxMeshWorkGroupSizeX_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeX_NV << "\n" + << "MaxMeshWorkGroupSizeY_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeY_NV << "\n" + << "MaxMeshWorkGroupSizeZ_NV " << DefaultTBuiltInResource.maxMeshWorkGroupSizeZ_NV << "\n" + << "MaxTaskWorkGroupSizeX_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeX_NV << "\n" + << "MaxTaskWorkGroupSizeY_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeY_NV << "\n" + << "MaxTaskWorkGroupSizeZ_NV " << DefaultTBuiltInResource.maxTaskWorkGroupSizeZ_NV << "\n" + << "MaxMeshViewCountNV " << DefaultTBuiltInResource.maxMeshViewCountNV << "\n" + << "MaxMeshOutputVerticesEXT " << DefaultTBuiltInResource.maxMeshOutputVerticesEXT << "\n" + << "MaxMeshOutputPrimitivesEXT " << DefaultTBuiltInResource.maxMeshOutputPrimitivesEXT << "\n" + << "MaxMeshWorkGroupSizeX_EXT " << DefaultTBuiltInResource.maxMeshWorkGroupSizeX_EXT << "\n" + << "MaxMeshWorkGroupSizeY_EXT " << DefaultTBuiltInResource.maxMeshWorkGroupSizeY_EXT << "\n" + << "MaxMeshWorkGroupSizeZ_EXT " << DefaultTBuiltInResource.maxMeshWorkGroupSizeZ_EXT << "\n" + << "MaxTaskWorkGroupSizeX_EXT " << DefaultTBuiltInResource.maxTaskWorkGroupSizeX_EXT << "\n" + << "MaxTaskWorkGroupSizeY_EXT " << DefaultTBuiltInResource.maxTaskWorkGroupSizeY_EXT << "\n" + << "MaxTaskWorkGroupSizeZ_EXT " << DefaultTBuiltInResource.maxTaskWorkGroupSizeZ_EXT << "\n" + << "MaxMeshViewCountEXT " << DefaultTBuiltInResource.maxMeshViewCountEXT << "\n" + << "MaxDualSourceDrawBuffersEXT " << DefaultTBuiltInResource.maxDualSourceDrawBuffersEXT << "\n" + << "nonInductiveForLoops " << DefaultTBuiltInResource.limits.nonInductiveForLoops << "\n" + << "whileLoops " << DefaultTBuiltInResource.limits.whileLoops << "\n" + << "doWhileLoops " << DefaultTBuiltInResource.limits.doWhileLoops << "\n" + << "generalUniformIndexing " << DefaultTBuiltInResource.limits.generalUniformIndexing << "\n" + << "generalAttributeMatrixVectorIndexing " << DefaultTBuiltInResource.limits.generalAttributeMatrixVectorIndexing << "\n" + << "generalVaryingIndexing " << DefaultTBuiltInResource.limits.generalVaryingIndexing << "\n" + << "generalSamplerIndexing " << DefaultTBuiltInResource.limits.generalSamplerIndexing << "\n" + << "generalVariableIndexing " << DefaultTBuiltInResource.limits.generalVariableIndexing << "\n" + << "generalConstantMatrixVectorIndexing " << DefaultTBuiltInResource.limits.generalConstantMatrixVectorIndexing << "\n" + ; + + return ostream.str(); +} + +void DecodeResourceLimits(TBuiltInResource* resources, char* config) +{ + static const char* delims = " \t\n\r"; + + size_t pos = 0; + std::string configStr(config); + + while ((pos = configStr.find_first_not_of(delims, pos)) != std::string::npos) { + const size_t token_s = pos; + const size_t token_e = configStr.find_first_of(delims, token_s); + const size_t value_s = configStr.find_first_not_of(delims, token_e); + const size_t value_e = configStr.find_first_of(delims, value_s); + pos = value_e; + + // Faster to use compare(), but prefering readability. + const std::string tokenStr = configStr.substr(token_s, token_e-token_s); + const std::string valueStr = configStr.substr(value_s, value_e-value_s); + + if (value_s == std::string::npos || ! (valueStr[0] == '-' || isdigit(valueStr[0]))) { + printf("Error: '%s' bad .conf file. Each name must be followed by one number.\n", + valueStr.c_str()); + return; + } + + const int value = std::atoi(valueStr.c_str()); + + if (tokenStr == "MaxLights") + resources->maxLights = value; + else if (tokenStr == "MaxClipPlanes") + resources->maxClipPlanes = value; + else if (tokenStr == "MaxTextureUnits") + resources->maxTextureUnits = value; + else if (tokenStr == "MaxTextureCoords") + resources->maxTextureCoords = value; + else if (tokenStr == "MaxVertexAttribs") + resources->maxVertexAttribs = value; + else if (tokenStr == "MaxVertexUniformComponents") + resources->maxVertexUniformComponents = value; + else if (tokenStr == "MaxVaryingFloats") + resources->maxVaryingFloats = value; + else if (tokenStr == "MaxVertexTextureImageUnits") + resources->maxVertexTextureImageUnits = value; + else if (tokenStr == "MaxCombinedTextureImageUnits") + resources->maxCombinedTextureImageUnits = value; + else if (tokenStr == "MaxTextureImageUnits") + resources->maxTextureImageUnits = value; + else if (tokenStr == "MaxFragmentUniformComponents") + resources->maxFragmentUniformComponents = value; + else if (tokenStr == "MaxDrawBuffers") + resources->maxDrawBuffers = value; + else if (tokenStr == "MaxVertexUniformVectors") + resources->maxVertexUniformVectors = value; + else if (tokenStr == "MaxVaryingVectors") + resources->maxVaryingVectors = value; + else if (tokenStr == "MaxFragmentUniformVectors") + resources->maxFragmentUniformVectors = value; + else if (tokenStr == "MaxVertexOutputVectors") + resources->maxVertexOutputVectors = value; + else if (tokenStr == "MaxFragmentInputVectors") + resources->maxFragmentInputVectors = value; + else if (tokenStr == "MinProgramTexelOffset") + resources->minProgramTexelOffset = value; + else if (tokenStr == "MaxProgramTexelOffset") + resources->maxProgramTexelOffset = value; + else if (tokenStr == "MaxClipDistances") + resources->maxClipDistances = value; + else if (tokenStr == "MaxComputeWorkGroupCountX") + resources->maxComputeWorkGroupCountX = value; + else if (tokenStr == "MaxComputeWorkGroupCountY") + resources->maxComputeWorkGroupCountY = value; + else if (tokenStr == "MaxComputeWorkGroupCountZ") + resources->maxComputeWorkGroupCountZ = value; + else if (tokenStr == "MaxComputeWorkGroupSizeX") + resources->maxComputeWorkGroupSizeX = value; + else if (tokenStr == "MaxComputeWorkGroupSizeY") + resources->maxComputeWorkGroupSizeY = value; + else if (tokenStr == "MaxComputeWorkGroupSizeZ") + resources->maxComputeWorkGroupSizeZ = value; + else if (tokenStr == "MaxComputeUniformComponents") + resources->maxComputeUniformComponents = value; + else if (tokenStr == "MaxComputeTextureImageUnits") + resources->maxComputeTextureImageUnits = value; + else if (tokenStr == "MaxComputeImageUniforms") + resources->maxComputeImageUniforms = value; + else if (tokenStr == "MaxComputeAtomicCounters") + resources->maxComputeAtomicCounters = value; + else if (tokenStr == "MaxComputeAtomicCounterBuffers") + resources->maxComputeAtomicCounterBuffers = value; + else if (tokenStr == "MaxVaryingComponents") + resources->maxVaryingComponents = value; + else if (tokenStr == "MaxVertexOutputComponents") + resources->maxVertexOutputComponents = value; + else if (tokenStr == "MaxGeometryInputComponents") + resources->maxGeometryInputComponents = value; + else if (tokenStr == "MaxGeometryOutputComponents") + resources->maxGeometryOutputComponents = value; + else if (tokenStr == "MaxFragmentInputComponents") + resources->maxFragmentInputComponents = value; + else if (tokenStr == "MaxImageUnits") + resources->maxImageUnits = value; + else if (tokenStr == "MaxCombinedImageUnitsAndFragmentOutputs") + resources->maxCombinedImageUnitsAndFragmentOutputs = value; + else if (tokenStr == "MaxCombinedShaderOutputResources") + resources->maxCombinedShaderOutputResources = value; + else if (tokenStr == "MaxImageSamples") + resources->maxImageSamples = value; + else if (tokenStr == "MaxVertexImageUniforms") + resources->maxVertexImageUniforms = value; + else if (tokenStr == "MaxTessControlImageUniforms") + resources->maxTessControlImageUniforms = value; + else if (tokenStr == "MaxTessEvaluationImageUniforms") + resources->maxTessEvaluationImageUniforms = value; + else if (tokenStr == "MaxGeometryImageUniforms") + resources->maxGeometryImageUniforms = value; + else if (tokenStr == "MaxFragmentImageUniforms") + resources->maxFragmentImageUniforms = value; + else if (tokenStr == "MaxCombinedImageUniforms") + resources->maxCombinedImageUniforms = value; + else if (tokenStr == "MaxGeometryTextureImageUnits") + resources->maxGeometryTextureImageUnits = value; + else if (tokenStr == "MaxGeometryOutputVertices") + resources->maxGeometryOutputVertices = value; + else if (tokenStr == "MaxGeometryTotalOutputComponents") + resources->maxGeometryTotalOutputComponents = value; + else if (tokenStr == "MaxGeometryUniformComponents") + resources->maxGeometryUniformComponents = value; + else if (tokenStr == "MaxGeometryVaryingComponents") + resources->maxGeometryVaryingComponents = value; + else if (tokenStr == "MaxTessControlInputComponents") + resources->maxTessControlInputComponents = value; + else if (tokenStr == "MaxTessControlOutputComponents") + resources->maxTessControlOutputComponents = value; + else if (tokenStr == "MaxTessControlTextureImageUnits") + resources->maxTessControlTextureImageUnits = value; + else if (tokenStr == "MaxTessControlUniformComponents") + resources->maxTessControlUniformComponents = value; + else if (tokenStr == "MaxTessControlTotalOutputComponents") + resources->maxTessControlTotalOutputComponents = value; + else if (tokenStr == "MaxTessEvaluationInputComponents") + resources->maxTessEvaluationInputComponents = value; + else if (tokenStr == "MaxTessEvaluationOutputComponents") + resources->maxTessEvaluationOutputComponents = value; + else if (tokenStr == "MaxTessEvaluationTextureImageUnits") + resources->maxTessEvaluationTextureImageUnits = value; + else if (tokenStr == "MaxTessEvaluationUniformComponents") + resources->maxTessEvaluationUniformComponents = value; + else if (tokenStr == "MaxTessPatchComponents") + resources->maxTessPatchComponents = value; + else if (tokenStr == "MaxPatchVertices") + resources->maxPatchVertices = value; + else if (tokenStr == "MaxTessGenLevel") + resources->maxTessGenLevel = value; + else if (tokenStr == "MaxViewports") + resources->maxViewports = value; + else if (tokenStr == "MaxVertexAtomicCounters") + resources->maxVertexAtomicCounters = value; + else if (tokenStr == "MaxTessControlAtomicCounters") + resources->maxTessControlAtomicCounters = value; + else if (tokenStr == "MaxTessEvaluationAtomicCounters") + resources->maxTessEvaluationAtomicCounters = value; + else if (tokenStr == "MaxGeometryAtomicCounters") + resources->maxGeometryAtomicCounters = value; + else if (tokenStr == "MaxFragmentAtomicCounters") + resources->maxFragmentAtomicCounters = value; + else if (tokenStr == "MaxCombinedAtomicCounters") + resources->maxCombinedAtomicCounters = value; + else if (tokenStr == "MaxAtomicCounterBindings") + resources->maxAtomicCounterBindings = value; + else if (tokenStr == "MaxVertexAtomicCounterBuffers") + resources->maxVertexAtomicCounterBuffers = value; + else if (tokenStr == "MaxTessControlAtomicCounterBuffers") + resources->maxTessControlAtomicCounterBuffers = value; + else if (tokenStr == "MaxTessEvaluationAtomicCounterBuffers") + resources->maxTessEvaluationAtomicCounterBuffers = value; + else if (tokenStr == "MaxGeometryAtomicCounterBuffers") + resources->maxGeometryAtomicCounterBuffers = value; + else if (tokenStr == "MaxFragmentAtomicCounterBuffers") + resources->maxFragmentAtomicCounterBuffers = value; + else if (tokenStr == "MaxCombinedAtomicCounterBuffers") + resources->maxCombinedAtomicCounterBuffers = value; + else if (tokenStr == "MaxAtomicCounterBufferSize") + resources->maxAtomicCounterBufferSize = value; + else if (tokenStr == "MaxTransformFeedbackBuffers") + resources->maxTransformFeedbackBuffers = value; + else if (tokenStr == "MaxTransformFeedbackInterleavedComponents") + resources->maxTransformFeedbackInterleavedComponents = value; + else if (tokenStr == "MaxCullDistances") + resources->maxCullDistances = value; + else if (tokenStr == "MaxCombinedClipAndCullDistances") + resources->maxCombinedClipAndCullDistances = value; + else if (tokenStr == "MaxSamples") + resources->maxSamples = value; + else if (tokenStr == "MaxMeshOutputVerticesNV") + resources->maxMeshOutputVerticesNV = value; + else if (tokenStr == "MaxMeshOutputPrimitivesNV") + resources->maxMeshOutputPrimitivesNV = value; + else if (tokenStr == "MaxMeshWorkGroupSizeX_NV") + resources->maxMeshWorkGroupSizeX_NV = value; + else if (tokenStr == "MaxMeshWorkGroupSizeY_NV") + resources->maxMeshWorkGroupSizeY_NV = value; + else if (tokenStr == "MaxMeshWorkGroupSizeZ_NV") + resources->maxMeshWorkGroupSizeZ_NV = value; + else if (tokenStr == "MaxTaskWorkGroupSizeX_NV") + resources->maxTaskWorkGroupSizeX_NV = value; + else if (tokenStr == "MaxTaskWorkGroupSizeY_NV") + resources->maxTaskWorkGroupSizeY_NV = value; + else if (tokenStr == "MaxTaskWorkGroupSizeZ_NV") + resources->maxTaskWorkGroupSizeZ_NV = value; + else if (tokenStr == "MaxMeshViewCountNV") + resources->maxMeshViewCountNV = value; + else if (tokenStr == "MaxMeshOutputVerticesEXT") + resources->maxMeshOutputVerticesEXT = value; + else if (tokenStr == "MaxMeshOutputPrimitivesEXT") + resources->maxMeshOutputPrimitivesEXT = value; + else if (tokenStr == "MaxMeshWorkGroupSizeX_EXT") + resources->maxMeshWorkGroupSizeX_EXT = value; + else if (tokenStr == "MaxMeshWorkGroupSizeY_EXT") + resources->maxMeshWorkGroupSizeY_EXT = value; + else if (tokenStr == "MaxMeshWorkGroupSizeZ_EXT") + resources->maxMeshWorkGroupSizeZ_EXT = value; + else if (tokenStr == "MaxTaskWorkGroupSizeX_EXT") + resources->maxTaskWorkGroupSizeX_EXT = value; + else if (tokenStr == "MaxTaskWorkGroupSizeY_EXT") + resources->maxTaskWorkGroupSizeY_EXT = value; + else if (tokenStr == "MaxTaskWorkGroupSizeZ_EXT") + resources->maxTaskWorkGroupSizeZ_EXT = value; + else if (tokenStr == "MaxMeshViewCountEXT") + resources->maxMeshViewCountEXT = value; + else if (tokenStr == "MaxDualSourceDrawBuffersEXT") + resources->maxDualSourceDrawBuffersEXT = value; + else if (tokenStr == "nonInductiveForLoops") + resources->limits.nonInductiveForLoops = (value != 0); + else if (tokenStr == "whileLoops") + resources->limits.whileLoops = (value != 0); + else if (tokenStr == "doWhileLoops") + resources->limits.doWhileLoops = (value != 0); + else if (tokenStr == "generalUniformIndexing") + resources->limits.generalUniformIndexing = (value != 0); + else if (tokenStr == "generalAttributeMatrixVectorIndexing") + resources->limits.generalAttributeMatrixVectorIndexing = (value != 0); + else if (tokenStr == "generalVaryingIndexing") + resources->limits.generalVaryingIndexing = (value != 0); + else if (tokenStr == "generalSamplerIndexing") + resources->limits.generalSamplerIndexing = (value != 0); + else if (tokenStr == "generalVariableIndexing") + resources->limits.generalVariableIndexing = (value != 0); + else if (tokenStr == "generalConstantMatrixVectorIndexing") + resources->limits.generalConstantMatrixVectorIndexing = (value != 0); + else + printf("Warning: unrecognized limit (%s) in configuration file.\n", tokenStr.c_str()); + + } +} + +TBuiltInResource* GetResources() +{ + return &Resources; +} + +const TBuiltInResource* GetDefaultResources() +{ + return &DefaultTBuiltInResource; +} diff --git a/src/libraries/glslang/glslang/build_info.h b/src/libraries/glslang/glslang/build_info.h index 319bfa5f7..ffb33ca0d 100644 --- a/src/libraries/glslang/glslang/build_info.h +++ b/src/libraries/glslang/glslang/build_info.h @@ -34,29 +34,29 @@ #ifndef GLSLANG_BUILD_INFO #define GLSLANG_BUILD_INFO -#define GLSLANG_VERSION_MAJOR 11 +#define GLSLANG_VERSION_MAJOR 14 #define GLSLANG_VERSION_MINOR 0 #define GLSLANG_VERSION_PATCH 0 #define GLSLANG_VERSION_FLAVOR "" #define GLSLANG_VERSION_GREATER_THAN(major, minor, patch) \ - (((major) > GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \ - (((minor) > GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \ - ((patch) > GLSLANG_VERSION_PATCH))))) + ((GLSLANG_VERSION_MAJOR) > (major) || ((major) == GLSLANG_VERSION_MAJOR && \ + ((GLSLANG_VERSION_MINOR) > (minor) || ((minor) == GLSLANG_VERSION_MINOR && \ + (GLSLANG_VERSION_PATCH) > (patch))))) #define GLSLANG_VERSION_GREATER_OR_EQUAL_TO(major, minor, patch) \ - (((major) > GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \ - (((minor) > GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \ - ((patch) >= GLSLANG_VERSION_PATCH))))) + ((GLSLANG_VERSION_MAJOR) > (major) || ((major) == GLSLANG_VERSION_MAJOR && \ + ((GLSLANG_VERSION_MINOR) > (minor) || ((minor) == GLSLANG_VERSION_MINOR && \ + (GLSLANG_VERSION_PATCH >= (patch)))))) #define GLSLANG_VERSION_LESS_THAN(major, minor, patch) \ - (((major) < GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \ - (((minor) < GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \ - ((patch) < GLSLANG_VERSION_PATCH))))) + ((GLSLANG_VERSION_MAJOR) < (major) || ((major) == GLSLANG_VERSION_MAJOR && \ + ((GLSLANG_VERSION_MINOR) < (minor) || ((minor) == GLSLANG_VERSION_MINOR && \ + (GLSLANG_VERSION_PATCH) < (patch))))) #define GLSLANG_VERSION_LESS_OR_EQUAL_TO(major, minor, patch) \ - (((major) < GLSLANG_VERSION_MAJOR) || ((major) == GLSLANG_VERSION_MAJOR && \ - (((minor) < GLSLANG_VERSION_MINOR) || ((minor) == GLSLANG_VERSION_MINOR && \ - ((patch) <= GLSLANG_VERSION_PATCH))))) + ((GLSLANG_VERSION_MAJOR) < (major) || ((major) == GLSLANG_VERSION_MAJOR && \ + ((GLSLANG_VERSION_MINOR) < (minor) || ((minor) == GLSLANG_VERSION_MINOR && \ + (GLSLANG_VERSION_PATCH <= (patch)))))) #endif // GLSLANG_BUILD_INFO diff --git a/src/modules/graphics/ShaderStage.cpp b/src/modules/graphics/ShaderStage.cpp index 621c3b9af..7c6c60d39 100644 --- a/src/modules/graphics/ShaderStage.cpp +++ b/src/modules/graphics/ShaderStage.cpp @@ -23,114 +23,7 @@ #include "Graphics.h" #include "libraries/glslang/glslang/Public/ShaderLang.h" - -// TODO: Use love.graphics to determine actual limits? -static const TBuiltInResource defaultTBuiltInResource = { - /* .MaxLights = */ 32, - /* .MaxClipPlanes = */ 6, - /* .MaxTextureUnits = */ 32, - /* .MaxTextureCoords = */ 32, - /* .MaxVertexAttribs = */ 64, - /* .MaxVertexUniformComponents = */ 16384, - /* .MaxVaryingFloats = */ 128, - /* .MaxVertexTextureImageUnits = */ 32, - /* .MaxCombinedTextureImageUnits = */ 80, - /* .MaxTextureImageUnits = */ 32, - /* .MaxFragmentUniformComponents = */ 16384, - /* .MaxDrawBuffers = */ 8, - /* .MaxVertexUniformVectors = */ 4096, - /* .MaxVaryingVectors = */ 32, - /* .MaxFragmentUniformVectors = */ 4096, - /* .MaxVertexOutputVectors = */ 32, - /* .MaxFragmentInputVectors = */ 31, - /* .MinProgramTexelOffset = */ -8, - /* .MaxProgramTexelOffset = */ 7, - /* .MaxClipDistances = */ 8, - /* .MaxComputeWorkGroupCountX = */ 65535, - /* .MaxComputeWorkGroupCountY = */ 65535, - /* .MaxComputeWorkGroupCountZ = */ 65535, - /* .MaxComputeWorkGroupSizeX = */ 1024, - /* .MaxComputeWorkGroupSizeY = */ 1024, - /* .MaxComputeWorkGroupSizeZ = */ 64, - /* .MaxComputeUniformComponents = */ 1024, - /* .MaxComputeTextureImageUnits = */ 32, - /* .MaxComputeImageUniforms = */ 16, - /* .MaxComputeAtomicCounters = */ 4096, - /* .MaxComputeAtomicCounterBuffers = */ 8, - /* .MaxVaryingComponents = */ 128, - /* .MaxVertexOutputComponents = */ 128, - /* .MaxGeometryInputComponents = */ 128, - /* .MaxGeometryOutputComponents = */ 128, - /* .MaxFragmentInputComponents = */ 128, - /* .MaxImageUnits = */ 192, - /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 144, - /* .MaxCombinedShaderOutputResources = */ 144, - /* .MaxImageSamples = */ 32, - /* .MaxVertexImageUniforms = */ 16, - /* .MaxTessControlImageUniforms = */ 16, - /* .MaxTessEvaluationImageUniforms = */ 16, - /* .MaxGeometryImageUniforms = */ 16, - /* .MaxFragmentImageUniforms = */ 16, - /* .MaxCombinedImageUniforms = */ 80, - /* .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 = */ 4096, - /* .MaxTessControlAtomicCounters = */ 4096, - /* .MaxTessEvaluationAtomicCounters = */ 4096, - /* .MaxGeometryAtomicCounters = */ 4096, - /* .MaxFragmentAtomicCounters = */ 4096, - /* .MaxCombinedAtomicCounters = */ 4096, - /* .MaxAtomicCounterBindings = */ 8, - /* .MaxVertexAtomicCounterBuffers = */ 8, - /* .MaxTessControlAtomicCounterBuffers = */ 8, - /* .MaxTessEvaluationAtomicCounterBuffers = */ 8, - /* .MaxGeometryAtomicCounterBuffers = */ 8, - /* .MaxFragmentAtomicCounterBuffers = */ 8, - /* .MaxCombinedAtomicCounterBuffers = */ 8, - /* .MaxAtomicCounterBufferSize = */ 16384, - /* .MaxTransformFeedbackBuffers = */ 4, - /* .MaxTransformFeedbackInterleavedComponents = */ 64, - /* .MaxCullDistances = */ 8, - /* .MaxCombinedClipAndCullDistances = */ 8, - /* .MaxSamples = */ 32, - /* .maxMeshOutputVerticesNV = */ 256, - /* .maxMeshOutputPrimitivesNV = */ 512, - /* .maxMeshWorkGroupSizeX_NV = */ 32, - /* .maxMeshWorkGroupSizeY_NV = */ 1, - /* .maxMeshWorkGroupSizeZ_NV = */ 1, - /* .maxTaskWorkGroupSizeX_NV = */ 32, - /* .maxTaskWorkGroupSizeY_NV = */ 1, - /* .maxTaskWorkGroupSizeZ_NV = */ 1, - /* .maxMeshViewCountNV = */ 4, - /* .maxDualSourceDrawBuffersEXT = */ 1, - /* .limits = */ { - /* .nonInductiveForLoops = */ 1, - /* .whileLoops = */ 1, - /* .doWhileLoops = */ 1, - /* .generalUniformIndexing = */ 1, - /* .generalAttributeMatrixVectorIndexing = */ 1, - /* .generalVaryingIndexing = */ 1, - /* .generalSamplerIndexing = */ 1, - /* .generalVariableIndexing = */ 1, - /* .generalConstantMatrixVectorIndexing = */ 1, - } -}; +#include "libraries/glslang/glslang/Public/ResourceLimits.h" namespace love { @@ -169,7 +62,7 @@ ShaderStage::ShaderStage(Graphics *gfx, ShaderStageType stage, const std::string bool forwardcompat = supportsGLSL3 && !forcedefault; - if (!glslangShader->parse(&defaultTBuiltInResource, defaultversion, defaultprofile, forcedefault, forwardcompat, EShMsgSuppressWarnings)) + if (!glslangShader->parse(GetDefaultResources(), defaultversion, defaultprofile, forcedefault, forwardcompat, EShMsgSuppressWarnings)) { const char *stagename = "unknown"; getConstant(stage, stagename); diff --git a/src/modules/graphics/metal/Shader.mm b/src/modules/graphics/metal/Shader.mm index ce6770e61..2984ed1b6 100644 --- a/src/modules/graphics/metal/Shader.mm +++ b/src/modules/graphics/metal/Shader.mm @@ -24,6 +24,7 @@ // glslang #include "libraries/glslang/glslang/Public/ShaderLang.h" +#include "libraries/glslang/glslang/Public/ResourceLimits.h" #include "libraries/glslang/SPIRV/GlslangToSpv.h" #include "libraries/spirv_cross/spirv_msl.hpp" #include "libraries/spirv_cross/spirv_reflect.hpp" @@ -39,114 +40,6 @@ static_assert(MAX_COLOR_RENDER_TARGETS <= 8, "Metal pipeline cache key only stores 8 render target pixel formats."); -// TODO: Use love.graphics to determine actual limits? -static const TBuiltInResource defaultTBuiltInResource = { - /* .MaxLights = */ 32, - /* .MaxClipPlanes = */ 6, - /* .MaxTextureUnits = */ 32, - /* .MaxTextureCoords = */ 32, - /* .MaxVertexAttribs = */ 64, - /* .MaxVertexUniformComponents = */ 16384, - /* .MaxVaryingFloats = */ 128, - /* .MaxVertexTextureImageUnits = */ 32, - /* .MaxCombinedTextureImageUnits = */ 80, - /* .MaxTextureImageUnits = */ 32, - /* .MaxFragmentUniformComponents = */ 16384, - /* .MaxDrawBuffers = */ 8, - /* .MaxVertexUniformVectors = */ 4096, - /* .MaxVaryingVectors = */ 32, - /* .MaxFragmentUniformVectors = */ 4096, - /* .MaxVertexOutputVectors = */ 32, - /* .MaxFragmentInputVectors = */ 31, - /* .MinProgramTexelOffset = */ -8, - /* .MaxProgramTexelOffset = */ 7, - /* .MaxClipDistances = */ 8, - /* .MaxComputeWorkGroupCountX = */ 65535, - /* .MaxComputeWorkGroupCountY = */ 65535, - /* .MaxComputeWorkGroupCountZ = */ 65535, - /* .MaxComputeWorkGroupSizeX = */ 1024, - /* .MaxComputeWorkGroupSizeY = */ 1024, - /* .MaxComputeWorkGroupSizeZ = */ 64, - /* .MaxComputeUniformComponents = */ 1024, - /* .MaxComputeTextureImageUnits = */ 32, - /* .MaxComputeImageUniforms = */ 16, - /* .MaxComputeAtomicCounters = */ 4096, - /* .MaxComputeAtomicCounterBuffers = */ 8, - /* .MaxVaryingComponents = */ 128, - /* .MaxVertexOutputComponents = */ 128, - /* .MaxGeometryInputComponents = */ 128, - /* .MaxGeometryOutputComponents = */ 128, - /* .MaxFragmentInputComponents = */ 128, - /* .MaxImageUnits = */ 192, - /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 144, - /* .MaxCombinedShaderOutputResources = */ 144, - /* .MaxImageSamples = */ 32, - /* .MaxVertexImageUniforms = */ 16, - /* .MaxTessControlImageUniforms = */ 16, - /* .MaxTessEvaluationImageUniforms = */ 16, - /* .MaxGeometryImageUniforms = */ 16, - /* .MaxFragmentImageUniforms = */ 16, - /* .MaxCombinedImageUniforms = */ 80, - /* .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 = */ 4096, - /* .MaxTessControlAtomicCounters = */ 4096, - /* .MaxTessEvaluationAtomicCounters = */ 4096, - /* .MaxGeometryAtomicCounters = */ 4096, - /* .MaxFragmentAtomicCounters = */ 4096, - /* .MaxCombinedAtomicCounters = */ 4096, - /* .MaxAtomicCounterBindings = */ 8, - /* .MaxVertexAtomicCounterBuffers = */ 8, - /* .MaxTessControlAtomicCounterBuffers = */ 8, - /* .MaxTessEvaluationAtomicCounterBuffers = */ 8, - /* .MaxGeometryAtomicCounterBuffers = */ 8, - /* .MaxFragmentAtomicCounterBuffers = */ 8, - /* .MaxCombinedAtomicCounterBuffers = */ 8, - /* .MaxAtomicCounterBufferSize = */ 16384, - /* .MaxTransformFeedbackBuffers = */ 4, - /* .MaxTransformFeedbackInterleavedComponents = */ 64, - /* .MaxCullDistances = */ 8, - /* .MaxCombinedClipAndCullDistances = */ 8, - /* .MaxSamples = */ 32, - /* .maxMeshOutputVerticesNV = */ 256, - /* .maxMeshOutputPrimitivesNV = */ 512, - /* .maxMeshWorkGroupSizeX_NV = */ 32, - /* .maxMeshWorkGroupSizeY_NV = */ 1, - /* .maxMeshWorkGroupSizeZ_NV = */ 1, - /* .maxTaskWorkGroupSizeX_NV = */ 32, - /* .maxTaskWorkGroupSizeY_NV = */ 1, - /* .maxTaskWorkGroupSizeZ_NV = */ 1, - /* .maxMeshViewCountNV = */ 4, - /* .maxDualSourceDrawBuffersEXT = */ 1, - /* .limits = */ { - /* .nonInductiveForLoops = */ 1, - /* .whileLoops = */ 1, - /* .doWhileLoops = */ 1, - /* .generalUniformIndexing = */ 1, - /* .generalAttributeMatrixVectorIndexing = */ 1, - /* .generalVaryingIndexing = */ 1, - /* .generalSamplerIndexing = */ 1, - /* .generalVariableIndexing = */ 1, - /* .generalConstantMatrixVectorIndexing = */ 1, - } -}; - static MTLVertexFormat getMTLVertexFormat(DataFormat format) { switch (format) @@ -314,7 +207,7 @@ static EShLanguage getGLSLangStage(ShaderStageType stage) forcedefault = true; #endif - if (!tshader->parse(&defaultTBuiltInResource, defaultversion, defaultprofile, forcedefault, forwardcompat, EShMsgSuppressWarnings)) + if (!tshader->parse(GetDefaultResources(), defaultversion, defaultprofile, forcedefault, forwardcompat, EShMsgSuppressWarnings)) { const char *stagename = "unknown"; ShaderStage::getConstant(stage, stagename); diff --git a/src/modules/graphics/vulkan/Shader.cpp b/src/modules/graphics/vulkan/Shader.cpp index ce686cd42..c21e7f12f 100644 --- a/src/modules/graphics/vulkan/Shader.cpp +++ b/src/modules/graphics/vulkan/Shader.cpp @@ -23,6 +23,7 @@ #include "Graphics.h" #include "libraries/glslang/glslang/Public/ShaderLang.h" +#include "libraries/glslang/glslang/Public/ResourceLimits.h" #include "libraries/glslang/SPIRV/GlslangToSpv.h" @@ -33,113 +34,6 @@ namespace graphics namespace vulkan { -static const TBuiltInResource defaultTBuiltInResource = { - /* .MaxLights = */ 32, - /* .MaxClipPlanes = */ 6, - /* .MaxTextureUnits = */ 32, - /* .MaxTextureCoords = */ 32, - /* .MaxVertexAttribs = */ 64, - /* .MaxVertexUniformComponents = */ 16384, - /* .MaxVaryingFloats = */ 128, - /* .MaxVertexTextureImageUnits = */ 32, - /* .MaxCombinedTextureImageUnits = */ 80, - /* .MaxTextureImageUnits = */ 32, - /* .MaxFragmentUniformComponents = */ 16384, - /* .MaxDrawBuffers = */ 8, - /* .MaxVertexUniformVectors = */ 4096, - /* .MaxVaryingVectors = */ 32, - /* .MaxFragmentUniformVectors = */ 4096, - /* .MaxVertexOutputVectors = */ 32, - /* .MaxFragmentInputVectors = */ 31, - /* .MinProgramTexelOffset = */ -8, - /* .MaxProgramTexelOffset = */ 7, - /* .MaxClipDistances = */ 8, - /* .MaxComputeWorkGroupCountX = */ 65535, - /* .MaxComputeWorkGroupCountY = */ 65535, - /* .MaxComputeWorkGroupCountZ = */ 65535, - /* .MaxComputeWorkGroupSizeX = */ 1024, - /* .MaxComputeWorkGroupSizeY = */ 1024, - /* .MaxComputeWorkGroupSizeZ = */ 64, - /* .MaxComputeUniformComponents = */ 1024, - /* .MaxComputeTextureImageUnits = */ 32, - /* .MaxComputeImageUniforms = */ 16, - /* .MaxComputeAtomicCounters = */ 4096, - /* .MaxComputeAtomicCounterBuffers = */ 8, - /* .MaxVaryingComponents = */ 128, - /* .MaxVertexOutputComponents = */ 128, - /* .MaxGeometryInputComponents = */ 128, - /* .MaxGeometryOutputComponents = */ 128, - /* .MaxFragmentInputComponents = */ 128, - /* .MaxImageUnits = */ 192, - /* .MaxCombinedImageUnitsAndFragmentOutputs = */ 144, - /* .MaxCombinedShaderOutputResources = */ 144, - /* .MaxImageSamples = */ 32, - /* .MaxVertexImageUniforms = */ 16, - /* .MaxTessControlImageUniforms = */ 16, - /* .MaxTessEvaluationImageUniforms = */ 16, - /* .MaxGeometryImageUniforms = */ 16, - /* .MaxFragmentImageUniforms = */ 16, - /* .MaxCombinedImageUniforms = */ 80, - /* .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 = */ 4096, - /* .MaxTessControlAtomicCounters = */ 4096, - /* .MaxTessEvaluationAtomicCounters = */ 4096, - /* .MaxGeometryAtomicCounters = */ 4096, - /* .MaxFragmentAtomicCounters = */ 4096, - /* .MaxCombinedAtomicCounters = */ 4096, - /* .MaxAtomicCounterBindings = */ 8, - /* .MaxVertexAtomicCounterBuffers = */ 8, - /* .MaxTessControlAtomicCounterBuffers = */ 8, - /* .MaxTessEvaluationAtomicCounterBuffers = */ 8, - /* .MaxGeometryAtomicCounterBuffers = */ 8, - /* .MaxFragmentAtomicCounterBuffers = */ 8, - /* .MaxCombinedAtomicCounterBuffers = */ 8, - /* .MaxAtomicCounterBufferSize = */ 16384, - /* .MaxTransformFeedbackBuffers = */ 4, - /* .MaxTransformFeedbackInterleavedComponents = */ 64, - /* .MaxCullDistances = */ 8, - /* .MaxCombinedClipAndCullDistances = */ 8, - /* .MaxSamples = */ 32, - /* .maxMeshOutputVerticesNV = */ 256, - /* .maxMeshOutputPrimitivesNV = */ 512, - /* .maxMeshWorkGroupSizeX_NV = */ 32, - /* .maxMeshWorkGroupSizeY_NV = */ 1, - /* .maxMeshWorkGroupSizeZ_NV = */ 1, - /* .maxTaskWorkGroupSizeX_NV = */ 32, - /* .maxTaskWorkGroupSizeY_NV = */ 1, - /* .maxTaskWorkGroupSizeZ_NV = */ 1, - /* .maxMeshViewCountNV = */ 4, - /* .maxDualSourceDrawBuffersEXT = */ 1, - /* .limits = */ { - /* .nonInductiveForLoops = */ 1, - /* .whileLoops = */ 1, - /* .doWhileLoops = */ 1, - /* .generalUniformIndexing = */ 1, - /* .generalAttributeMatrixVectorIndexing = */ 1, - /* .generalVaryingIndexing = */ 1, - /* .generalSamplerIndexing = */ 1, - /* .generalVariableIndexing = */ 1, - /* .generalConstantMatrixVectorIndexing = */ 1, - } -}; - static const uint32_t STREAMBUFFER_DEFAULT_SIZE = 16; static const uint32_t DESCRIPTOR_POOL_SIZE = 1000; @@ -726,7 +620,7 @@ void Shader::compileShaders() bool forceDefault = false; bool forwardCompat = true; - if (!tshader->parse(&defaultTBuiltInResource, defaultVersion, defaultProfile, forceDefault, forwardCompat, EShMsgSuppressWarnings)) + if (!tshader->parse(GetDefaultResources(), defaultVersion, defaultProfile, forceDefault, forwardCompat, EShMsgSuppressWarnings)) { const char *stageName = "unknown"; ShaderStage::getConstant(stage, stageName); From 421cfd1a5ef9a979dd6837aef6ee47235b154cb4 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sun, 7 Jan 2024 21:17:43 -0400 Subject: [PATCH 15/29] update SPIRV-Cross --- src/libraries/spirv_cross/spirv.h | 392 +- src/libraries/spirv_cross/spirv.hpp | 392 +- src/libraries/spirv_cross/spirv_cfg.cpp | 33 +- src/libraries/spirv_cross/spirv_cfg.hpp | 5 + src/libraries/spirv_cross/spirv_common.hpp | 88 +- src/libraries/spirv_cross/spirv_cpp.cpp | 7 +- src/libraries/spirv_cross/spirv_cross.cpp | 482 +- src/libraries/spirv_cross/spirv_cross.hpp | 35 +- src/libraries/spirv_cross/spirv_cross_c.cpp | 280 +- src/libraries/spirv_cross/spirv_cross_c.h | 108 +- .../spirv_cross/spirv_cross_containers.hpp | 12 +- .../spirv_cross/spirv_cross_parsed_ir.cpp | 56 +- .../spirv_cross/spirv_cross_parsed_ir.hpp | 4 +- src/libraries/spirv_cross/spirv_glsl.cpp | 3611 ++++++++++++--- src/libraries/spirv_cross/spirv_glsl.hpp | 153 +- src/libraries/spirv_cross/spirv_hlsl.cpp | 1204 ++++- src/libraries/spirv_cross/spirv_hlsl.hpp | 49 +- src/libraries/spirv_cross/spirv_msl.cpp | 3903 +++++++++++++---- src/libraries/spirv_cross/spirv_msl.hpp | 252 +- src/libraries/spirv_cross/spirv_parser.cpp | 150 +- src/libraries/spirv_cross/spirv_parser.hpp | 2 + src/libraries/spirv_cross/spirv_reflect.cpp | 34 +- 22 files changed, 9245 insertions(+), 2007 deletions(-) diff --git a/src/libraries/spirv_cross/spirv.h b/src/libraries/spirv_cross/spirv.h index 949f1980e..5b6e8aaf4 100644 --- a/src/libraries/spirv_cross/spirv.h +++ b/src/libraries/spirv_cross/spirv.h @@ -31,7 +31,7 @@ /* ** Enumeration tokens for SPIR-V, in various styles: -** C, C++, C++11, JSON, Lua, Python, C#, D +** C, C++, C++11, JSON, Lua, Python, C#, D, Beef ** ** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL ** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL @@ -41,6 +41,8 @@ ** - C# will use enum classes in the Specification class located in the "Spv" namespace, ** e.g.: Spv.Specification.SourceLanguage.GLSL ** - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +** - Beef will use enum classes in the Specification class located in the "Spv" namespace, +** e.g.: Spv.Specification.SourceLanguage.GLSL ** ** Some tokens act like mask values, which can be OR'd together, ** while others are mutually exclusive. The mask-like ones have @@ -53,12 +55,12 @@ typedef unsigned int SpvId; -#define SPV_VERSION 0x10500 -#define SPV_REVISION 4 +#define SPV_VERSION 0x10600 +#define SPV_REVISION 1 static const unsigned int SpvMagicNumber = 0x07230203; -static const unsigned int SpvVersion = 0x00010500; -static const unsigned int SpvRevision = 4; +static const unsigned int SpvVersion = 0x00010600; +static const unsigned int SpvRevision = 1; static const unsigned int SpvOpCodeMask = 0xffff; static const unsigned int SpvWordCountShift = 16; @@ -69,6 +71,8 @@ typedef enum SpvSourceLanguage_ { SpvSourceLanguageOpenCL_C = 3, SpvSourceLanguageOpenCL_CPP = 4, SpvSourceLanguageHLSL = 5, + SpvSourceLanguageCPP_for_OpenCL = 6, + SpvSourceLanguageSYCL = 7, SpvSourceLanguageMax = 0x7fffffff, } SpvSourceLanguage; @@ -94,6 +98,8 @@ typedef enum SpvExecutionModel_ { SpvExecutionModelMissNV = 5317, SpvExecutionModelCallableKHR = 5318, SpvExecutionModelCallableNV = 5318, + SpvExecutionModelTaskEXT = 5364, + SpvExecutionModelMeshEXT = 5365, SpvExecutionModelMax = 0x7fffffff, } SpvExecutionModel; @@ -154,17 +160,28 @@ typedef enum SpvExecutionMode_ { SpvExecutionModeSubgroupsPerWorkgroupId = 37, SpvExecutionModeLocalSizeId = 38, SpvExecutionModeLocalSizeHintId = 39, + SpvExecutionModeSubgroupUniformControlFlowKHR = 4421, SpvExecutionModePostDepthCoverage = 4446, SpvExecutionModeDenormPreserve = 4459, SpvExecutionModeDenormFlushToZero = 4460, SpvExecutionModeSignedZeroInfNanPreserve = 4461, SpvExecutionModeRoundingModeRTE = 4462, SpvExecutionModeRoundingModeRTZ = 4463, + SpvExecutionModeEarlyAndLateFragmentTestsAMD = 5017, SpvExecutionModeStencilRefReplacingEXT = 5027, + SpvExecutionModeStencilRefUnchangedFrontAMD = 5079, + SpvExecutionModeStencilRefGreaterFrontAMD = 5080, + SpvExecutionModeStencilRefLessFrontAMD = 5081, + SpvExecutionModeStencilRefUnchangedBackAMD = 5082, + SpvExecutionModeStencilRefGreaterBackAMD = 5083, + SpvExecutionModeStencilRefLessBackAMD = 5084, + SpvExecutionModeOutputLinesEXT = 5269, SpvExecutionModeOutputLinesNV = 5269, + SpvExecutionModeOutputPrimitivesEXT = 5270, SpvExecutionModeOutputPrimitivesNV = 5270, SpvExecutionModeDerivativeGroupQuadsNV = 5289, SpvExecutionModeDerivativeGroupLinearNV = 5290, + SpvExecutionModeOutputTrianglesEXT = 5298, SpvExecutionModeOutputTrianglesNV = 5298, SpvExecutionModePixelInterlockOrderedEXT = 5366, SpvExecutionModePixelInterlockUnorderedEXT = 5367, @@ -172,10 +189,17 @@ typedef enum SpvExecutionMode_ { SpvExecutionModeSampleInterlockUnorderedEXT = 5369, SpvExecutionModeShadingRateInterlockOrderedEXT = 5370, SpvExecutionModeShadingRateInterlockUnorderedEXT = 5371, + SpvExecutionModeSharedLocalMemorySizeINTEL = 5618, + SpvExecutionModeRoundingModeRTPINTEL = 5620, + SpvExecutionModeRoundingModeRTNINTEL = 5621, + SpvExecutionModeFloatingPointModeALTINTEL = 5622, + SpvExecutionModeFloatingPointModeIEEEINTEL = 5623, SpvExecutionModeMaxWorkgroupSizeINTEL = 5893, SpvExecutionModeMaxWorkDimINTEL = 5894, SpvExecutionModeNoGlobalOffsetINTEL = 5895, SpvExecutionModeNumSIMDWorkitemsINTEL = 5896, + SpvExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, + SpvExecutionModeNamedBarrierCountINTEL = 6417, SpvExecutionModeMax = 0x7fffffff, } SpvExecutionMode; @@ -207,7 +231,10 @@ typedef enum SpvStorageClass_ { SpvStorageClassShaderRecordBufferNV = 5343, SpvStorageClassPhysicalStorageBuffer = 5349, SpvStorageClassPhysicalStorageBufferEXT = 5349, + SpvStorageClassTaskPayloadWorkgroupEXT = 5402, SpvStorageClassCodeSectionINTEL = 5605, + SpvStorageClassDeviceOnlyINTEL = 5936, + SpvStorageClassHostOnlyINTEL = 5937, SpvStorageClassMax = 0x7fffffff, } SpvStorageClass; @@ -347,6 +374,8 @@ typedef enum SpvImageOperandsShift_ { SpvImageOperandsVolatileTexelKHRShift = 11, SpvImageOperandsSignExtendShift = 12, SpvImageOperandsZeroExtendShift = 13, + SpvImageOperandsNontemporalShift = 14, + SpvImageOperandsOffsetsShift = 16, SpvImageOperandsMax = 0x7fffffff, } SpvImageOperandsShift; @@ -370,6 +399,8 @@ typedef enum SpvImageOperandsMask_ { SpvImageOperandsVolatileTexelKHRMask = 0x00000800, SpvImageOperandsSignExtendMask = 0x00001000, SpvImageOperandsZeroExtendMask = 0x00002000, + SpvImageOperandsNontemporalMask = 0x00004000, + SpvImageOperandsOffsetsMask = 0x00010000, } SpvImageOperandsMask; typedef enum SpvFPFastMathModeShift_ { @@ -378,6 +409,8 @@ typedef enum SpvFPFastMathModeShift_ { SpvFPFastMathModeNSZShift = 2, SpvFPFastMathModeAllowRecipShift = 3, SpvFPFastMathModeFastShift = 4, + SpvFPFastMathModeAllowContractFastINTELShift = 16, + SpvFPFastMathModeAllowReassocINTELShift = 17, SpvFPFastMathModeMax = 0x7fffffff, } SpvFPFastMathModeShift; @@ -388,6 +421,8 @@ typedef enum SpvFPFastMathModeMask_ { SpvFPFastMathModeNSZMask = 0x00000004, SpvFPFastMathModeAllowRecipMask = 0x00000008, SpvFPFastMathModeFastMask = 0x00000010, + SpvFPFastMathModeAllowContractFastINTELMask = 0x00010000, + SpvFPFastMathModeAllowReassocINTELMask = 0x00020000, } SpvFPFastMathModeMask; typedef enum SpvFPRoundingMode_ { @@ -401,6 +436,7 @@ typedef enum SpvFPRoundingMode_ { typedef enum SpvLinkageType_ { SpvLinkageTypeExport = 0, SpvLinkageTypeImport = 1, + SpvLinkageTypeLinkOnceODR = 2, SpvLinkageTypeMax = 0x7fffffff, } SpvLinkageType; @@ -478,9 +514,11 @@ typedef enum SpvDecoration_ { SpvDecorationPassthroughNV = 5250, SpvDecorationViewportRelativeNV = 5252, SpvDecorationSecondaryViewportRelativeNV = 5256, + SpvDecorationPerPrimitiveEXT = 5271, SpvDecorationPerPrimitiveNV = 5271, SpvDecorationPerViewNV = 5272, SpvDecorationPerTaskNV = 5273, + SpvDecorationPerVertexKHR = 5285, SpvDecorationPerVertexNV = 5285, SpvDecorationNonUniform = 5300, SpvDecorationNonUniformEXT = 5300, @@ -488,12 +526,26 @@ typedef enum SpvDecoration_ { SpvDecorationRestrictPointerEXT = 5355, SpvDecorationAliasedPointer = 5356, SpvDecorationAliasedPointerEXT = 5356, + SpvDecorationBindlessSamplerNV = 5398, + SpvDecorationBindlessImageNV = 5399, + SpvDecorationBoundSamplerNV = 5400, + SpvDecorationBoundImageNV = 5401, + SpvDecorationSIMTCallINTEL = 5599, SpvDecorationReferencedIndirectlyINTEL = 5602, + SpvDecorationClobberINTEL = 5607, + SpvDecorationSideEffectsINTEL = 5608, + SpvDecorationVectorComputeVariableINTEL = 5624, + SpvDecorationFuncParamIOKindINTEL = 5625, + SpvDecorationVectorComputeFunctionINTEL = 5626, + SpvDecorationStackCallINTEL = 5627, + SpvDecorationGlobalVariableOffsetINTEL = 5628, SpvDecorationCounterBuffer = 5634, SpvDecorationHlslCounterBufferGOOGLE = 5634, SpvDecorationHlslSemanticGOOGLE = 5635, SpvDecorationUserSemantic = 5635, SpvDecorationUserTypeGOOGLE = 5636, + SpvDecorationFunctionRoundingModeINTEL = 5822, + SpvDecorationFunctionDenormModeINTEL = 5823, SpvDecorationRegisterINTEL = 5825, SpvDecorationMemoryINTEL = 5826, SpvDecorationNumbanksINTEL = 5827, @@ -506,6 +558,20 @@ typedef enum SpvDecoration_ { SpvDecorationMergeINTEL = 5834, SpvDecorationBankBitsINTEL = 5835, SpvDecorationForcePow2DepthINTEL = 5836, + SpvDecorationBurstCoalesceINTEL = 5899, + SpvDecorationCacheSizeINTEL = 5900, + SpvDecorationDontStaticallyCoalesceINTEL = 5901, + SpvDecorationPrefetchINTEL = 5902, + SpvDecorationStallEnableINTEL = 5905, + SpvDecorationFuseLoopsInFunctionINTEL = 5907, + SpvDecorationAliasScopeINTEL = 5914, + SpvDecorationNoAliasINTEL = 5915, + SpvDecorationBufferLocationINTEL = 5921, + SpvDecorationIOPipeStorageINTEL = 5944, + SpvDecorationFunctionFloatingPointModeINTEL = 6080, + SpvDecorationSingleElementVectorINTEL = 6085, + SpvDecorationVectorComputeCallableFunctionINTEL = 6087, + SpvDecorationMediaBlockIOINTEL = 6140, SpvDecorationMax = 0x7fffffff, } SpvDecoration; @@ -590,12 +656,18 @@ typedef enum SpvBuiltIn_ { SpvBuiltInLayerPerViewNV = 5279, SpvBuiltInMeshViewCountNV = 5280, SpvBuiltInMeshViewIndicesNV = 5281, + SpvBuiltInBaryCoordKHR = 5286, SpvBuiltInBaryCoordNV = 5286, + SpvBuiltInBaryCoordNoPerspKHR = 5287, SpvBuiltInBaryCoordNoPerspNV = 5287, SpvBuiltInFragSizeEXT = 5292, SpvBuiltInFragmentSizeNV = 5292, SpvBuiltInFragInvocationCountEXT = 5293, SpvBuiltInInvocationsPerPixelNV = 5293, + SpvBuiltInPrimitivePointIndicesEXT = 5294, + SpvBuiltInPrimitiveLineIndicesEXT = 5295, + SpvBuiltInPrimitiveTriangleIndicesEXT = 5296, + SpvBuiltInCullPrimitiveEXT = 5299, SpvBuiltInLaunchIdKHR = 5319, SpvBuiltInLaunchIdNV = 5319, SpvBuiltInLaunchSizeKHR = 5320, @@ -621,6 +693,7 @@ typedef enum SpvBuiltIn_ { SpvBuiltInHitTNV = 5332, SpvBuiltInHitKindKHR = 5333, SpvBuiltInHitKindNV = 5333, + SpvBuiltInCurrentRayTimeNV = 5334, SpvBuiltInIncomingRayFlagsKHR = 5351, SpvBuiltInIncomingRayFlagsNV = 5351, SpvBuiltInRayGeometryIndexKHR = 5352, @@ -628,6 +701,7 @@ typedef enum SpvBuiltIn_ { SpvBuiltInSMCountNV = 5375, SpvBuiltInWarpIDNV = 5376, SpvBuiltInSMIDNV = 5377, + SpvBuiltInCullMaskKHR = 6021, SpvBuiltInMax = 0x7fffffff, } SpvBuiltIn; @@ -660,6 +734,7 @@ typedef enum SpvLoopControlShift_ { SpvLoopControlLoopCoalesceINTELShift = 20, SpvLoopControlMaxInterleavingINTELShift = 21, SpvLoopControlSpeculatedIterationsINTELShift = 22, + SpvLoopControlNoFusionINTELShift = 23, SpvLoopControlMax = 0x7fffffff, } SpvLoopControlShift; @@ -681,6 +756,7 @@ typedef enum SpvLoopControlMask_ { SpvLoopControlLoopCoalesceINTELMask = 0x00100000, SpvLoopControlMaxInterleavingINTELMask = 0x00200000, SpvLoopControlSpeculatedIterationsINTELMask = 0x00400000, + SpvLoopControlNoFusionINTELMask = 0x00800000, } SpvLoopControlMask; typedef enum SpvFunctionControlShift_ { @@ -688,6 +764,7 @@ typedef enum SpvFunctionControlShift_ { SpvFunctionControlDontInlineShift = 1, SpvFunctionControlPureShift = 2, SpvFunctionControlConstShift = 3, + SpvFunctionControlOptNoneINTELShift = 16, SpvFunctionControlMax = 0x7fffffff, } SpvFunctionControlShift; @@ -697,6 +774,7 @@ typedef enum SpvFunctionControlMask_ { SpvFunctionControlDontInlineMask = 0x00000002, SpvFunctionControlPureMask = 0x00000004, SpvFunctionControlConstMask = 0x00000008, + SpvFunctionControlOptNoneINTELMask = 0x00010000, } SpvFunctionControlMask; typedef enum SpvMemorySemanticsShift_ { @@ -751,6 +829,8 @@ typedef enum SpvMemoryAccessShift_ { SpvMemoryAccessMakePointerVisibleKHRShift = 4, SpvMemoryAccessNonPrivatePointerShift = 5, SpvMemoryAccessNonPrivatePointerKHRShift = 5, + SpvMemoryAccessAliasScopeINTELMaskShift = 16, + SpvMemoryAccessNoAliasINTELMaskShift = 17, SpvMemoryAccessMax = 0x7fffffff, } SpvMemoryAccessShift; @@ -765,6 +845,8 @@ typedef enum SpvMemoryAccessMask_ { SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010, SpvMemoryAccessNonPrivatePointerMask = 0x00000020, SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020, + SpvMemoryAccessAliasScopeINTELMaskMask = 0x00010000, + SpvMemoryAccessNoAliasINTELMaskMask = 0x00020000, } SpvMemoryAccessMask; typedef enum SpvScope_ { @@ -877,9 +959,13 @@ typedef enum SpvCapability_ { SpvCapabilityGroupNonUniformQuad = 68, SpvCapabilityShaderLayer = 69, SpvCapabilityShaderViewportIndex = 70, + SpvCapabilityUniformDecoration = 71, SpvCapabilityFragmentShadingRateKHR = 4422, SpvCapabilitySubgroupBallotKHR = 4423, SpvCapabilityDrawParameters = 4427, + SpvCapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, + SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, SpvCapabilitySubgroupVoteKHR = 4431, SpvCapabilityStorageBuffer16BitAccess = 4433, SpvCapabilityStorageUniformBufferBlock16 = 4433, @@ -922,6 +1008,8 @@ typedef enum SpvCapability_ { SpvCapabilityFragmentFullyCoveredEXT = 5265, SpvCapabilityMeshShadingNV = 5266, SpvCapabilityImageFootprintNV = 5282, + SpvCapabilityMeshShadingEXT = 5283, + SpvCapabilityFragmentBarycentricKHR = 5284, SpvCapabilityFragmentBarycentricNV = 5284, SpvCapabilityComputeDerivativeGroupQuadsNV = 5288, SpvCapabilityFragmentDensityEXT = 5291, @@ -952,6 +1040,7 @@ typedef enum SpvCapability_ { SpvCapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, SpvCapabilityRayTracingNV = 5340, + SpvCapabilityRayTracingMotionBlurNV = 5341, SpvCapabilityVulkanMemoryModel = 5345, SpvCapabilityVulkanMemoryModelKHR = 5345, SpvCapabilityVulkanMemoryModelDeviceScope = 5346, @@ -965,26 +1054,67 @@ typedef enum SpvCapability_ { SpvCapabilityFragmentShaderShadingRateInterlockEXT = 5372, SpvCapabilityShaderSMBuiltinsNV = 5373, SpvCapabilityFragmentShaderPixelInterlockEXT = 5378, + SpvCapabilityDemoteToHelperInvocation = 5379, SpvCapabilityDemoteToHelperInvocationEXT = 5379, + SpvCapabilityBindlessTextureNV = 5390, SpvCapabilitySubgroupShuffleINTEL = 5568, SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, SpvCapabilitySubgroupImageBlockIOINTEL = 5570, SpvCapabilitySubgroupImageMediaBlockIOINTEL = 5579, + SpvCapabilityRoundToInfinityINTEL = 5582, + SpvCapabilityFloatingPointModeINTEL = 5583, SpvCapabilityIntegerFunctions2INTEL = 5584, SpvCapabilityFunctionPointersINTEL = 5603, SpvCapabilityIndirectReferencesINTEL = 5604, + SpvCapabilityAsmINTEL = 5606, + SpvCapabilityAtomicFloat32MinMaxEXT = 5612, + SpvCapabilityAtomicFloat64MinMaxEXT = 5613, + SpvCapabilityAtomicFloat16MinMaxEXT = 5616, + SpvCapabilityVectorComputeINTEL = 5617, + SpvCapabilityVectorAnyINTEL = 5619, + SpvCapabilityExpectAssumeKHR = 5629, SpvCapabilitySubgroupAvcMotionEstimationINTEL = 5696, SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + SpvCapabilityVariableLengthArrayINTEL = 5817, + SpvCapabilityFunctionFloatControlINTEL = 5821, SpvCapabilityFPGAMemoryAttributesINTEL = 5824, + SpvCapabilityFPFastMathModeINTEL = 5837, + SpvCapabilityArbitraryPrecisionIntegersINTEL = 5844, + SpvCapabilityArbitraryPrecisionFloatingPointINTEL = 5845, SpvCapabilityUnstructuredLoopControlsINTEL = 5886, SpvCapabilityFPGALoopControlsINTEL = 5888, SpvCapabilityKernelAttributesINTEL = 5892, SpvCapabilityFPGAKernelAttributesINTEL = 5897, + SpvCapabilityFPGAMemoryAccessesINTEL = 5898, + SpvCapabilityFPGAClusterAttributesINTEL = 5904, + SpvCapabilityLoopFuseINTEL = 5906, + SpvCapabilityMemoryAccessAliasingINTEL = 5910, + SpvCapabilityFPGABufferLocationINTEL = 5920, + SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922, + SpvCapabilityUSMStorageClassesINTEL = 5935, + SpvCapabilityIOPipesINTEL = 5943, SpvCapabilityBlockingPipesINTEL = 5945, SpvCapabilityFPGARegINTEL = 5948, + SpvCapabilityDotProductInputAll = 6016, + SpvCapabilityDotProductInputAllKHR = 6016, + SpvCapabilityDotProductInput4x8Bit = 6017, + SpvCapabilityDotProductInput4x8BitKHR = 6017, + SpvCapabilityDotProductInput4x8BitPacked = 6018, + SpvCapabilityDotProductInput4x8BitPackedKHR = 6018, + SpvCapabilityDotProduct = 6019, + SpvCapabilityDotProductKHR = 6019, + SpvCapabilityRayCullMaskKHR = 6020, + SpvCapabilityBitInstructions = 6025, + SpvCapabilityGroupNonUniformRotateKHR = 6026, SpvCapabilityAtomicFloat32AddEXT = 6033, SpvCapabilityAtomicFloat64AddEXT = 6034, + SpvCapabilityLongConstantCompositeINTEL = 6089, + SpvCapabilityOptNoneINTEL = 6094, + SpvCapabilityAtomicFloat16AddEXT = 6095, + SpvCapabilityDebugInfoModuleINTEL = 6114, + SpvCapabilitySplitBarrierINTEL = 6141, + SpvCapabilityGroupUniformArithmeticKHR = 6400, SpvCapabilityMax = 0x7fffffff, } SpvCapability; @@ -1051,6 +1181,44 @@ typedef enum SpvFragmentShadingRateMask_ { SpvFragmentShadingRateHorizontal4PixelsMask = 0x00000008, } SpvFragmentShadingRateMask; +typedef enum SpvFPDenormMode_ { + SpvFPDenormModePreserve = 0, + SpvFPDenormModeFlushToZero = 1, + SpvFPDenormModeMax = 0x7fffffff, +} SpvFPDenormMode; + +typedef enum SpvFPOperationMode_ { + SpvFPOperationModeIEEE = 0, + SpvFPOperationModeALT = 1, + SpvFPOperationModeMax = 0x7fffffff, +} SpvFPOperationMode; + +typedef enum SpvQuantizationModes_ { + SpvQuantizationModesTRN = 0, + SpvQuantizationModesTRN_ZERO = 1, + SpvQuantizationModesRND = 2, + SpvQuantizationModesRND_ZERO = 3, + SpvQuantizationModesRND_INF = 4, + SpvQuantizationModesRND_MIN_INF = 5, + SpvQuantizationModesRND_CONV = 6, + SpvQuantizationModesRND_CONV_ODD = 7, + SpvQuantizationModesMax = 0x7fffffff, +} SpvQuantizationModes; + +typedef enum SpvOverflowModes_ { + SpvOverflowModesWRAP = 0, + SpvOverflowModesSAT = 1, + SpvOverflowModesSAT_ZERO = 2, + SpvOverflowModesSAT_SYM = 3, + SpvOverflowModesMax = 0x7fffffff, +} SpvOverflowModes; + +typedef enum SpvPackedVectorFormat_ { + SpvPackedVectorFormatPackedVectorFormat4x8Bit = 0, + SpvPackedVectorFormatPackedVectorFormat4x8BitKHR = 0, + SpvPackedVectorFormatMax = 0x7fffffff, +} SpvPackedVectorFormat; + typedef enum SpvOp_ { SpvOpNop = 0, SpvOpUndef = 1, @@ -1402,12 +1570,25 @@ typedef enum SpvOp_ { SpvOpSubgroupAllKHR = 4428, SpvOpSubgroupAnyKHR = 4429, SpvOpSubgroupAllEqualKHR = 4430, + SpvOpGroupNonUniformRotateKHR = 4431, SpvOpSubgroupReadInvocationKHR = 4432, SpvOpTraceRayKHR = 4445, SpvOpExecuteCallableKHR = 4446, SpvOpConvertUToAccelerationStructureKHR = 4447, SpvOpIgnoreIntersectionKHR = 4448, SpvOpTerminateRayKHR = 4449, + SpvOpSDot = 4450, + SpvOpSDotKHR = 4450, + SpvOpUDot = 4451, + SpvOpUDotKHR = 4451, + SpvOpSUDot = 4452, + SpvOpSUDotKHR = 4452, + SpvOpSDotAccSat = 4453, + SpvOpSDotAccSatKHR = 4453, + SpvOpUDotAccSat = 4454, + SpvOpUDotAccSatKHR = 4454, + SpvOpSUDotAccSat = 4455, + SpvOpSUDotAccSatKHR = 4455, SpvOpTypeRayQueryKHR = 4472, SpvOpRayQueryInitializeKHR = 4473, SpvOpRayQueryTerminateKHR = 4474, @@ -1427,6 +1608,8 @@ typedef enum SpvOp_ { SpvOpFragmentFetchAMD = 5012, SpvOpReadClockKHR = 5056, SpvOpImageSampleFootprintNV = 5283, + SpvOpEmitMeshTasksEXT = 5294, + SpvOpSetMeshOutputsEXT = 5295, SpvOpGroupNonUniformPartitionNV = 5296, SpvOpWritePackedPrimitiveIndices4x8NV = 5299, SpvOpReportIntersectionKHR = 5334, @@ -1434,6 +1617,8 @@ typedef enum SpvOp_ { SpvOpIgnoreIntersectionNV = 5335, SpvOpTerminateRayNV = 5336, SpvOpTraceNV = 5337, + SpvOpTraceMotionNV = 5338, + SpvOpTraceRayMotionNV = 5339, SpvOpTypeAccelerationStructureKHR = 5341, SpvOpTypeAccelerationStructureNV = 5341, SpvOpExecuteCallableNV = 5344, @@ -1444,8 +1629,16 @@ typedef enum SpvOp_ { SpvOpCooperativeMatrixLengthNV = 5362, SpvOpBeginInvocationInterlockEXT = 5364, SpvOpEndInvocationInterlockEXT = 5365, + SpvOpDemoteToHelperInvocation = 5380, SpvOpDemoteToHelperInvocationEXT = 5380, SpvOpIsHelperInvocationEXT = 5381, + SpvOpConvertUToImageNV = 5391, + SpvOpConvertUToSamplerNV = 5392, + SpvOpConvertImageToUNV = 5393, + SpvOpConvertSamplerToUNV = 5394, + SpvOpConvertUToSampledImageNV = 5395, + SpvOpConvertSampledImageToUNV = 5396, + SpvOpSamplerImageAddressingModeNV = 5397, SpvOpSubgroupShuffleINTEL = 5571, SpvOpSubgroupShuffleDownINTEL = 5572, SpvOpSubgroupShuffleUpINTEL = 5573, @@ -1470,8 +1663,15 @@ typedef enum SpvOp_ { SpvOpUSubSatINTEL = 5596, SpvOpIMul32x16INTEL = 5597, SpvOpUMul32x16INTEL = 5598, - SpvOpFunctionPointerINTEL = 5600, + SpvOpConstantFunctionPointerINTEL = 5600, SpvOpFunctionPointerCallINTEL = 5601, + SpvOpAsmTargetINTEL = 5609, + SpvOpAsmINTEL = 5610, + SpvOpAsmCallINTEL = 5611, + SpvOpAtomicFMinEXT = 5614, + SpvOpAtomicFMaxEXT = 5615, + SpvOpAssumeTrueKHR = 5630, + SpvOpExpectKHR = 5631, SpvOpDecorateString = 5632, SpvOpDecorateStringGOOGLE = 5632, SpvOpMemberDecorateString = 5633, @@ -1594,7 +1794,67 @@ typedef enum SpvOp_ { SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, SpvOpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + SpvOpVariableLengthArrayINTEL = 5818, + SpvOpSaveMemoryINTEL = 5819, + SpvOpRestoreMemoryINTEL = 5820, + SpvOpArbitraryFloatSinCosPiINTEL = 5840, + SpvOpArbitraryFloatCastINTEL = 5841, + SpvOpArbitraryFloatCastFromIntINTEL = 5842, + SpvOpArbitraryFloatCastToIntINTEL = 5843, + SpvOpArbitraryFloatAddINTEL = 5846, + SpvOpArbitraryFloatSubINTEL = 5847, + SpvOpArbitraryFloatMulINTEL = 5848, + SpvOpArbitraryFloatDivINTEL = 5849, + SpvOpArbitraryFloatGTINTEL = 5850, + SpvOpArbitraryFloatGEINTEL = 5851, + SpvOpArbitraryFloatLTINTEL = 5852, + SpvOpArbitraryFloatLEINTEL = 5853, + SpvOpArbitraryFloatEQINTEL = 5854, + SpvOpArbitraryFloatRecipINTEL = 5855, + SpvOpArbitraryFloatRSqrtINTEL = 5856, + SpvOpArbitraryFloatCbrtINTEL = 5857, + SpvOpArbitraryFloatHypotINTEL = 5858, + SpvOpArbitraryFloatSqrtINTEL = 5859, + SpvOpArbitraryFloatLogINTEL = 5860, + SpvOpArbitraryFloatLog2INTEL = 5861, + SpvOpArbitraryFloatLog10INTEL = 5862, + SpvOpArbitraryFloatLog1pINTEL = 5863, + SpvOpArbitraryFloatExpINTEL = 5864, + SpvOpArbitraryFloatExp2INTEL = 5865, + SpvOpArbitraryFloatExp10INTEL = 5866, + SpvOpArbitraryFloatExpm1INTEL = 5867, + SpvOpArbitraryFloatSinINTEL = 5868, + SpvOpArbitraryFloatCosINTEL = 5869, + SpvOpArbitraryFloatSinCosINTEL = 5870, + SpvOpArbitraryFloatSinPiINTEL = 5871, + SpvOpArbitraryFloatCosPiINTEL = 5872, + SpvOpArbitraryFloatASinINTEL = 5873, + SpvOpArbitraryFloatASinPiINTEL = 5874, + SpvOpArbitraryFloatACosINTEL = 5875, + SpvOpArbitraryFloatACosPiINTEL = 5876, + SpvOpArbitraryFloatATanINTEL = 5877, + SpvOpArbitraryFloatATanPiINTEL = 5878, + SpvOpArbitraryFloatATan2INTEL = 5879, + SpvOpArbitraryFloatPowINTEL = 5880, + SpvOpArbitraryFloatPowRINTEL = 5881, + SpvOpArbitraryFloatPowNINTEL = 5882, SpvOpLoopControlINTEL = 5887, + SpvOpAliasDomainDeclINTEL = 5911, + SpvOpAliasScopeDeclINTEL = 5912, + SpvOpAliasScopeListDeclINTEL = 5913, + SpvOpFixedSqrtINTEL = 5923, + SpvOpFixedRecipINTEL = 5924, + SpvOpFixedRsqrtINTEL = 5925, + SpvOpFixedSinINTEL = 5926, + SpvOpFixedCosINTEL = 5927, + SpvOpFixedSinCosINTEL = 5928, + SpvOpFixedSinPiINTEL = 5929, + SpvOpFixedCosPiINTEL = 5930, + SpvOpFixedSinCosPiINTEL = 5931, + SpvOpFixedLogINTEL = 5932, + SpvOpFixedExpINTEL = 5933, + SpvOpPtrCastToCrossWorkgroupINTEL = 5934, + SpvOpCrossWorkgroupCastToPtrINTEL = 5938, SpvOpReadPipeBlockingINTEL = 5946, SpvOpWritePipeBlockingINTEL = 5947, SpvOpFPGARegINTEL = 5949, @@ -1616,10 +1876,27 @@ typedef enum SpvOp_ { SpvOpRayQueryGetIntersectionObjectToWorldKHR = 6031, SpvOpRayQueryGetIntersectionWorldToObjectKHR = 6032, SpvOpAtomicFAddEXT = 6035, + SpvOpTypeBufferSurfaceINTEL = 6086, + SpvOpTypeStructContinuedINTEL = 6090, + SpvOpConstantCompositeContinuedINTEL = 6091, + SpvOpSpecConstantCompositeContinuedINTEL = 6092, + SpvOpControlBarrierArriveINTEL = 6142, + SpvOpControlBarrierWaitINTEL = 6143, + SpvOpGroupIMulKHR = 6401, + SpvOpGroupFMulKHR = 6402, + SpvOpGroupBitwiseAndKHR = 6403, + SpvOpGroupBitwiseOrKHR = 6404, + SpvOpGroupBitwiseXorKHR = 6405, + SpvOpGroupLogicalAndKHR = 6406, + SpvOpGroupLogicalOrKHR = 6407, + SpvOpGroupLogicalXorKHR = 6408, SpvOpMax = 0x7fffffff, } SpvOp; #ifdef SPV_ENABLE_UTILITY_CODE +#ifndef __cplusplus +#include +#endif inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) { *hasResult = *hasResultType = false; switch (opcode) { @@ -1974,12 +2251,19 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break; case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; case SpvOpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; case SpvOpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; case SpvOpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpSDot: *hasResult = true; *hasResultType = true; break; + case SpvOpUDot: *hasResult = true; *hasResultType = true; break; + case SpvOpSUDot: *hasResult = true; *hasResultType = true; break; + case SpvOpSDotAccSat: *hasResult = true; *hasResultType = true; break; + case SpvOpUDotAccSat: *hasResult = true; *hasResultType = true; break; + case SpvOpSUDotAccSat: *hasResult = true; *hasResultType = true; break; case SpvOpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; case SpvOpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; case SpvOpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; @@ -1999,12 +2283,16 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; case SpvOpReadClockKHR: *hasResult = true; *hasResultType = true; break; case SpvOpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case SpvOpEmitMeshTasksEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break; case SpvOpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; case SpvOpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; case SpvOpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; case SpvOpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; case SpvOpTerminateRayNV: *hasResult = false; *hasResultType = false; break; case SpvOpTraceNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTraceMotionNV: *hasResult = false; *hasResultType = false; break; + case SpvOpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; case SpvOpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; case SpvOpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; case SpvOpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; @@ -2014,8 +2302,15 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; case SpvOpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; case SpvOpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; - case SpvOpDemoteToHelperInvocationEXT: *hasResult = false; *hasResultType = false; break; + case SpvOpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; case SpvOpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; + case SpvOpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; + case SpvOpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; case SpvOpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; @@ -2040,8 +2335,15 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; case SpvOpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; + case SpvOpExpectKHR: *hasResult = true; *hasResultType = true; break; case SpvOpDecorateString: *hasResult = false; *hasResultType = false; break; case SpvOpMemberDecorateString: *hasResult = false; *hasResultType = false; break; case SpvOpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; @@ -2162,7 +2464,67 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case SpvOpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; case SpvOpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; @@ -2184,6 +2546,20 @@ inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultTy case SpvOpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; case SpvOpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; case SpvOpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case SpvOpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case SpvOpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; + case SpvOpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; + case SpvOpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; } } #endif /* SPV_ENABLE_UTILITY_CODE */ diff --git a/src/libraries/spirv_cross/spirv.hpp b/src/libraries/spirv_cross/spirv.hpp index 43dd2aaee..e25264af2 100644 --- a/src/libraries/spirv_cross/spirv.hpp +++ b/src/libraries/spirv_cross/spirv.hpp @@ -26,7 +26,7 @@ // the Binary Section of the SPIR-V specification. // Enumeration tokens for SPIR-V, in various styles: -// C, C++, C++11, JSON, Lua, Python, C#, D +// C, C++, C++11, JSON, Lua, Python, C#, D, Beef // // - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL // - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL @@ -36,6 +36,8 @@ // - C# will use enum classes in the Specification class located in the "Spv" namespace, // e.g.: Spv.Specification.SourceLanguage.GLSL // - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL +// - Beef will use enum classes in the Specification class located in the "Spv" namespace, +// e.g.: Spv.Specification.SourceLanguage.GLSL // // Some tokens act like mask values, which can be OR'd together, // while others are mutually exclusive. The mask-like ones have @@ -49,12 +51,12 @@ namespace spv { typedef unsigned int Id; -#define SPV_VERSION 0x10500 -#define SPV_REVISION 4 +#define SPV_VERSION 0x10600 +#define SPV_REVISION 1 static const unsigned int MagicNumber = 0x07230203; -static const unsigned int Version = 0x00010500; -static const unsigned int Revision = 4; +static const unsigned int Version = 0x00010600; +static const unsigned int Revision = 1; static const unsigned int OpCodeMask = 0xffff; static const unsigned int WordCountShift = 16; @@ -65,6 +67,8 @@ enum SourceLanguage { SourceLanguageOpenCL_C = 3, SourceLanguageOpenCL_CPP = 4, SourceLanguageHLSL = 5, + SourceLanguageCPP_for_OpenCL = 6, + SourceLanguageSYCL = 7, SourceLanguageMax = 0x7fffffff, }; @@ -90,6 +94,8 @@ enum ExecutionModel { ExecutionModelMissNV = 5317, ExecutionModelCallableKHR = 5318, ExecutionModelCallableNV = 5318, + ExecutionModelTaskEXT = 5364, + ExecutionModelMeshEXT = 5365, ExecutionModelMax = 0x7fffffff, }; @@ -150,17 +156,28 @@ enum ExecutionMode { ExecutionModeSubgroupsPerWorkgroupId = 37, ExecutionModeLocalSizeId = 38, ExecutionModeLocalSizeHintId = 39, + ExecutionModeSubgroupUniformControlFlowKHR = 4421, ExecutionModePostDepthCoverage = 4446, ExecutionModeDenormPreserve = 4459, ExecutionModeDenormFlushToZero = 4460, ExecutionModeSignedZeroInfNanPreserve = 4461, ExecutionModeRoundingModeRTE = 4462, ExecutionModeRoundingModeRTZ = 4463, + ExecutionModeEarlyAndLateFragmentTestsAMD = 5017, ExecutionModeStencilRefReplacingEXT = 5027, + ExecutionModeStencilRefUnchangedFrontAMD = 5079, + ExecutionModeStencilRefGreaterFrontAMD = 5080, + ExecutionModeStencilRefLessFrontAMD = 5081, + ExecutionModeStencilRefUnchangedBackAMD = 5082, + ExecutionModeStencilRefGreaterBackAMD = 5083, + ExecutionModeStencilRefLessBackAMD = 5084, + ExecutionModeOutputLinesEXT = 5269, ExecutionModeOutputLinesNV = 5269, + ExecutionModeOutputPrimitivesEXT = 5270, ExecutionModeOutputPrimitivesNV = 5270, ExecutionModeDerivativeGroupQuadsNV = 5289, ExecutionModeDerivativeGroupLinearNV = 5290, + ExecutionModeOutputTrianglesEXT = 5298, ExecutionModeOutputTrianglesNV = 5298, ExecutionModePixelInterlockOrderedEXT = 5366, ExecutionModePixelInterlockUnorderedEXT = 5367, @@ -168,10 +185,17 @@ enum ExecutionMode { ExecutionModeSampleInterlockUnorderedEXT = 5369, ExecutionModeShadingRateInterlockOrderedEXT = 5370, ExecutionModeShadingRateInterlockUnorderedEXT = 5371, + ExecutionModeSharedLocalMemorySizeINTEL = 5618, + ExecutionModeRoundingModeRTPINTEL = 5620, + ExecutionModeRoundingModeRTNINTEL = 5621, + ExecutionModeFloatingPointModeALTINTEL = 5622, + ExecutionModeFloatingPointModeIEEEINTEL = 5623, ExecutionModeMaxWorkgroupSizeINTEL = 5893, ExecutionModeMaxWorkDimINTEL = 5894, ExecutionModeNoGlobalOffsetINTEL = 5895, ExecutionModeNumSIMDWorkitemsINTEL = 5896, + ExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, + ExecutionModeNamedBarrierCountINTEL = 6417, ExecutionModeMax = 0x7fffffff, }; @@ -203,7 +227,10 @@ enum StorageClass { StorageClassShaderRecordBufferNV = 5343, StorageClassPhysicalStorageBuffer = 5349, StorageClassPhysicalStorageBufferEXT = 5349, + StorageClassTaskPayloadWorkgroupEXT = 5402, StorageClassCodeSectionINTEL = 5605, + StorageClassDeviceOnlyINTEL = 5936, + StorageClassHostOnlyINTEL = 5937, StorageClassMax = 0x7fffffff, }; @@ -343,6 +370,8 @@ enum ImageOperandsShift { ImageOperandsVolatileTexelKHRShift = 11, ImageOperandsSignExtendShift = 12, ImageOperandsZeroExtendShift = 13, + ImageOperandsNontemporalShift = 14, + ImageOperandsOffsetsShift = 16, ImageOperandsMax = 0x7fffffff, }; @@ -366,6 +395,8 @@ enum ImageOperandsMask { ImageOperandsVolatileTexelKHRMask = 0x00000800, ImageOperandsSignExtendMask = 0x00001000, ImageOperandsZeroExtendMask = 0x00002000, + ImageOperandsNontemporalMask = 0x00004000, + ImageOperandsOffsetsMask = 0x00010000, }; enum FPFastMathModeShift { @@ -374,6 +405,8 @@ enum FPFastMathModeShift { FPFastMathModeNSZShift = 2, FPFastMathModeAllowRecipShift = 3, FPFastMathModeFastShift = 4, + FPFastMathModeAllowContractFastINTELShift = 16, + FPFastMathModeAllowReassocINTELShift = 17, FPFastMathModeMax = 0x7fffffff, }; @@ -384,6 +417,8 @@ enum FPFastMathModeMask { FPFastMathModeNSZMask = 0x00000004, FPFastMathModeAllowRecipMask = 0x00000008, FPFastMathModeFastMask = 0x00000010, + FPFastMathModeAllowContractFastINTELMask = 0x00010000, + FPFastMathModeAllowReassocINTELMask = 0x00020000, }; enum FPRoundingMode { @@ -397,6 +432,7 @@ enum FPRoundingMode { enum LinkageType { LinkageTypeExport = 0, LinkageTypeImport = 1, + LinkageTypeLinkOnceODR = 2, LinkageTypeMax = 0x7fffffff, }; @@ -474,9 +510,11 @@ enum Decoration { DecorationPassthroughNV = 5250, DecorationViewportRelativeNV = 5252, DecorationSecondaryViewportRelativeNV = 5256, + DecorationPerPrimitiveEXT = 5271, DecorationPerPrimitiveNV = 5271, DecorationPerViewNV = 5272, DecorationPerTaskNV = 5273, + DecorationPerVertexKHR = 5285, DecorationPerVertexNV = 5285, DecorationNonUniform = 5300, DecorationNonUniformEXT = 5300, @@ -484,12 +522,26 @@ enum Decoration { DecorationRestrictPointerEXT = 5355, DecorationAliasedPointer = 5356, DecorationAliasedPointerEXT = 5356, + DecorationBindlessSamplerNV = 5398, + DecorationBindlessImageNV = 5399, + DecorationBoundSamplerNV = 5400, + DecorationBoundImageNV = 5401, + DecorationSIMTCallINTEL = 5599, DecorationReferencedIndirectlyINTEL = 5602, + DecorationClobberINTEL = 5607, + DecorationSideEffectsINTEL = 5608, + DecorationVectorComputeVariableINTEL = 5624, + DecorationFuncParamIOKindINTEL = 5625, + DecorationVectorComputeFunctionINTEL = 5626, + DecorationStackCallINTEL = 5627, + DecorationGlobalVariableOffsetINTEL = 5628, DecorationCounterBuffer = 5634, DecorationHlslCounterBufferGOOGLE = 5634, DecorationHlslSemanticGOOGLE = 5635, DecorationUserSemantic = 5635, DecorationUserTypeGOOGLE = 5636, + DecorationFunctionRoundingModeINTEL = 5822, + DecorationFunctionDenormModeINTEL = 5823, DecorationRegisterINTEL = 5825, DecorationMemoryINTEL = 5826, DecorationNumbanksINTEL = 5827, @@ -502,6 +554,20 @@ enum Decoration { DecorationMergeINTEL = 5834, DecorationBankBitsINTEL = 5835, DecorationForcePow2DepthINTEL = 5836, + DecorationBurstCoalesceINTEL = 5899, + DecorationCacheSizeINTEL = 5900, + DecorationDontStaticallyCoalesceINTEL = 5901, + DecorationPrefetchINTEL = 5902, + DecorationStallEnableINTEL = 5905, + DecorationFuseLoopsInFunctionINTEL = 5907, + DecorationAliasScopeINTEL = 5914, + DecorationNoAliasINTEL = 5915, + DecorationBufferLocationINTEL = 5921, + DecorationIOPipeStorageINTEL = 5944, + DecorationFunctionFloatingPointModeINTEL = 6080, + DecorationSingleElementVectorINTEL = 6085, + DecorationVectorComputeCallableFunctionINTEL = 6087, + DecorationMediaBlockIOINTEL = 6140, DecorationMax = 0x7fffffff, }; @@ -586,12 +652,18 @@ enum BuiltIn { BuiltInLayerPerViewNV = 5279, BuiltInMeshViewCountNV = 5280, BuiltInMeshViewIndicesNV = 5281, + BuiltInBaryCoordKHR = 5286, BuiltInBaryCoordNV = 5286, + BuiltInBaryCoordNoPerspKHR = 5287, BuiltInBaryCoordNoPerspNV = 5287, BuiltInFragSizeEXT = 5292, BuiltInFragmentSizeNV = 5292, BuiltInFragInvocationCountEXT = 5293, BuiltInInvocationsPerPixelNV = 5293, + BuiltInPrimitivePointIndicesEXT = 5294, + BuiltInPrimitiveLineIndicesEXT = 5295, + BuiltInPrimitiveTriangleIndicesEXT = 5296, + BuiltInCullPrimitiveEXT = 5299, BuiltInLaunchIdKHR = 5319, BuiltInLaunchIdNV = 5319, BuiltInLaunchSizeKHR = 5320, @@ -617,6 +689,7 @@ enum BuiltIn { BuiltInHitTNV = 5332, BuiltInHitKindKHR = 5333, BuiltInHitKindNV = 5333, + BuiltInCurrentRayTimeNV = 5334, BuiltInIncomingRayFlagsKHR = 5351, BuiltInIncomingRayFlagsNV = 5351, BuiltInRayGeometryIndexKHR = 5352, @@ -624,6 +697,7 @@ enum BuiltIn { BuiltInSMCountNV = 5375, BuiltInWarpIDNV = 5376, BuiltInSMIDNV = 5377, + BuiltInCullMaskKHR = 6021, BuiltInMax = 0x7fffffff, }; @@ -656,6 +730,7 @@ enum LoopControlShift { LoopControlLoopCoalesceINTELShift = 20, LoopControlMaxInterleavingINTELShift = 21, LoopControlSpeculatedIterationsINTELShift = 22, + LoopControlNoFusionINTELShift = 23, LoopControlMax = 0x7fffffff, }; @@ -677,6 +752,7 @@ enum LoopControlMask { LoopControlLoopCoalesceINTELMask = 0x00100000, LoopControlMaxInterleavingINTELMask = 0x00200000, LoopControlSpeculatedIterationsINTELMask = 0x00400000, + LoopControlNoFusionINTELMask = 0x00800000, }; enum FunctionControlShift { @@ -684,6 +760,7 @@ enum FunctionControlShift { FunctionControlDontInlineShift = 1, FunctionControlPureShift = 2, FunctionControlConstShift = 3, + FunctionControlOptNoneINTELShift = 16, FunctionControlMax = 0x7fffffff, }; @@ -693,6 +770,7 @@ enum FunctionControlMask { FunctionControlDontInlineMask = 0x00000002, FunctionControlPureMask = 0x00000004, FunctionControlConstMask = 0x00000008, + FunctionControlOptNoneINTELMask = 0x00010000, }; enum MemorySemanticsShift { @@ -747,6 +825,8 @@ enum MemoryAccessShift { MemoryAccessMakePointerVisibleKHRShift = 4, MemoryAccessNonPrivatePointerShift = 5, MemoryAccessNonPrivatePointerKHRShift = 5, + MemoryAccessAliasScopeINTELMaskShift = 16, + MemoryAccessNoAliasINTELMaskShift = 17, MemoryAccessMax = 0x7fffffff, }; @@ -761,6 +841,8 @@ enum MemoryAccessMask { MemoryAccessMakePointerVisibleKHRMask = 0x00000010, MemoryAccessNonPrivatePointerMask = 0x00000020, MemoryAccessNonPrivatePointerKHRMask = 0x00000020, + MemoryAccessAliasScopeINTELMaskMask = 0x00010000, + MemoryAccessNoAliasINTELMaskMask = 0x00020000, }; enum Scope { @@ -873,9 +955,13 @@ enum Capability { CapabilityGroupNonUniformQuad = 68, CapabilityShaderLayer = 69, CapabilityShaderViewportIndex = 70, + CapabilityUniformDecoration = 71, CapabilityFragmentShadingRateKHR = 4422, CapabilitySubgroupBallotKHR = 4423, CapabilityDrawParameters = 4427, + CapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, + CapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, + CapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, CapabilitySubgroupVoteKHR = 4431, CapabilityStorageBuffer16BitAccess = 4433, CapabilityStorageUniformBufferBlock16 = 4433, @@ -918,6 +1004,8 @@ enum Capability { CapabilityFragmentFullyCoveredEXT = 5265, CapabilityMeshShadingNV = 5266, CapabilityImageFootprintNV = 5282, + CapabilityMeshShadingEXT = 5283, + CapabilityFragmentBarycentricKHR = 5284, CapabilityFragmentBarycentricNV = 5284, CapabilityComputeDerivativeGroupQuadsNV = 5288, CapabilityFragmentDensityEXT = 5291, @@ -948,6 +1036,7 @@ enum Capability { CapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, CapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, CapabilityRayTracingNV = 5340, + CapabilityRayTracingMotionBlurNV = 5341, CapabilityVulkanMemoryModel = 5345, CapabilityVulkanMemoryModelKHR = 5345, CapabilityVulkanMemoryModelDeviceScope = 5346, @@ -961,26 +1050,67 @@ enum Capability { CapabilityFragmentShaderShadingRateInterlockEXT = 5372, CapabilityShaderSMBuiltinsNV = 5373, CapabilityFragmentShaderPixelInterlockEXT = 5378, + CapabilityDemoteToHelperInvocation = 5379, CapabilityDemoteToHelperInvocationEXT = 5379, + CapabilityBindlessTextureNV = 5390, CapabilitySubgroupShuffleINTEL = 5568, CapabilitySubgroupBufferBlockIOINTEL = 5569, CapabilitySubgroupImageBlockIOINTEL = 5570, CapabilitySubgroupImageMediaBlockIOINTEL = 5579, + CapabilityRoundToInfinityINTEL = 5582, + CapabilityFloatingPointModeINTEL = 5583, CapabilityIntegerFunctions2INTEL = 5584, CapabilityFunctionPointersINTEL = 5603, CapabilityIndirectReferencesINTEL = 5604, + CapabilityAsmINTEL = 5606, + CapabilityAtomicFloat32MinMaxEXT = 5612, + CapabilityAtomicFloat64MinMaxEXT = 5613, + CapabilityAtomicFloat16MinMaxEXT = 5616, + CapabilityVectorComputeINTEL = 5617, + CapabilityVectorAnyINTEL = 5619, + CapabilityExpectAssumeKHR = 5629, CapabilitySubgroupAvcMotionEstimationINTEL = 5696, CapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, CapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, + CapabilityVariableLengthArrayINTEL = 5817, + CapabilityFunctionFloatControlINTEL = 5821, CapabilityFPGAMemoryAttributesINTEL = 5824, + CapabilityFPFastMathModeINTEL = 5837, + CapabilityArbitraryPrecisionIntegersINTEL = 5844, + CapabilityArbitraryPrecisionFloatingPointINTEL = 5845, CapabilityUnstructuredLoopControlsINTEL = 5886, CapabilityFPGALoopControlsINTEL = 5888, CapabilityKernelAttributesINTEL = 5892, CapabilityFPGAKernelAttributesINTEL = 5897, + CapabilityFPGAMemoryAccessesINTEL = 5898, + CapabilityFPGAClusterAttributesINTEL = 5904, + CapabilityLoopFuseINTEL = 5906, + CapabilityMemoryAccessAliasingINTEL = 5910, + CapabilityFPGABufferLocationINTEL = 5920, + CapabilityArbitraryPrecisionFixedPointINTEL = 5922, + CapabilityUSMStorageClassesINTEL = 5935, + CapabilityIOPipesINTEL = 5943, CapabilityBlockingPipesINTEL = 5945, CapabilityFPGARegINTEL = 5948, + CapabilityDotProductInputAll = 6016, + CapabilityDotProductInputAllKHR = 6016, + CapabilityDotProductInput4x8Bit = 6017, + CapabilityDotProductInput4x8BitKHR = 6017, + CapabilityDotProductInput4x8BitPacked = 6018, + CapabilityDotProductInput4x8BitPackedKHR = 6018, + CapabilityDotProduct = 6019, + CapabilityDotProductKHR = 6019, + CapabilityRayCullMaskKHR = 6020, + CapabilityBitInstructions = 6025, + CapabilityGroupNonUniformRotateKHR = 6026, CapabilityAtomicFloat32AddEXT = 6033, CapabilityAtomicFloat64AddEXT = 6034, + CapabilityLongConstantCompositeINTEL = 6089, + CapabilityOptNoneINTEL = 6094, + CapabilityAtomicFloat16AddEXT = 6095, + CapabilityDebugInfoModuleINTEL = 6114, + CapabilitySplitBarrierINTEL = 6141, + CapabilityGroupUniformArithmeticKHR = 6400, CapabilityMax = 0x7fffffff, }; @@ -1047,6 +1177,44 @@ enum FragmentShadingRateMask { FragmentShadingRateHorizontal4PixelsMask = 0x00000008, }; +enum FPDenormMode { + FPDenormModePreserve = 0, + FPDenormModeFlushToZero = 1, + FPDenormModeMax = 0x7fffffff, +}; + +enum FPOperationMode { + FPOperationModeIEEE = 0, + FPOperationModeALT = 1, + FPOperationModeMax = 0x7fffffff, +}; + +enum QuantizationModes { + QuantizationModesTRN = 0, + QuantizationModesTRN_ZERO = 1, + QuantizationModesRND = 2, + QuantizationModesRND_ZERO = 3, + QuantizationModesRND_INF = 4, + QuantizationModesRND_MIN_INF = 5, + QuantizationModesRND_CONV = 6, + QuantizationModesRND_CONV_ODD = 7, + QuantizationModesMax = 0x7fffffff, +}; + +enum OverflowModes { + OverflowModesWRAP = 0, + OverflowModesSAT = 1, + OverflowModesSAT_ZERO = 2, + OverflowModesSAT_SYM = 3, + OverflowModesMax = 0x7fffffff, +}; + +enum PackedVectorFormat { + PackedVectorFormatPackedVectorFormat4x8Bit = 0, + PackedVectorFormatPackedVectorFormat4x8BitKHR = 0, + PackedVectorFormatMax = 0x7fffffff, +}; + enum Op { OpNop = 0, OpUndef = 1, @@ -1398,12 +1566,25 @@ enum Op { OpSubgroupAllKHR = 4428, OpSubgroupAnyKHR = 4429, OpSubgroupAllEqualKHR = 4430, + OpGroupNonUniformRotateKHR = 4431, OpSubgroupReadInvocationKHR = 4432, OpTraceRayKHR = 4445, OpExecuteCallableKHR = 4446, OpConvertUToAccelerationStructureKHR = 4447, OpIgnoreIntersectionKHR = 4448, OpTerminateRayKHR = 4449, + OpSDot = 4450, + OpSDotKHR = 4450, + OpUDot = 4451, + OpUDotKHR = 4451, + OpSUDot = 4452, + OpSUDotKHR = 4452, + OpSDotAccSat = 4453, + OpSDotAccSatKHR = 4453, + OpUDotAccSat = 4454, + OpUDotAccSatKHR = 4454, + OpSUDotAccSat = 4455, + OpSUDotAccSatKHR = 4455, OpTypeRayQueryKHR = 4472, OpRayQueryInitializeKHR = 4473, OpRayQueryTerminateKHR = 4474, @@ -1423,6 +1604,8 @@ enum Op { OpFragmentFetchAMD = 5012, OpReadClockKHR = 5056, OpImageSampleFootprintNV = 5283, + OpEmitMeshTasksEXT = 5294, + OpSetMeshOutputsEXT = 5295, OpGroupNonUniformPartitionNV = 5296, OpWritePackedPrimitiveIndices4x8NV = 5299, OpReportIntersectionKHR = 5334, @@ -1430,6 +1613,8 @@ enum Op { OpIgnoreIntersectionNV = 5335, OpTerminateRayNV = 5336, OpTraceNV = 5337, + OpTraceMotionNV = 5338, + OpTraceRayMotionNV = 5339, OpTypeAccelerationStructureKHR = 5341, OpTypeAccelerationStructureNV = 5341, OpExecuteCallableNV = 5344, @@ -1440,8 +1625,16 @@ enum Op { OpCooperativeMatrixLengthNV = 5362, OpBeginInvocationInterlockEXT = 5364, OpEndInvocationInterlockEXT = 5365, + OpDemoteToHelperInvocation = 5380, OpDemoteToHelperInvocationEXT = 5380, OpIsHelperInvocationEXT = 5381, + OpConvertUToImageNV = 5391, + OpConvertUToSamplerNV = 5392, + OpConvertImageToUNV = 5393, + OpConvertSamplerToUNV = 5394, + OpConvertUToSampledImageNV = 5395, + OpConvertSampledImageToUNV = 5396, + OpSamplerImageAddressingModeNV = 5397, OpSubgroupShuffleINTEL = 5571, OpSubgroupShuffleDownINTEL = 5572, OpSubgroupShuffleUpINTEL = 5573, @@ -1466,8 +1659,15 @@ enum Op { OpUSubSatINTEL = 5596, OpIMul32x16INTEL = 5597, OpUMul32x16INTEL = 5598, - OpFunctionPointerINTEL = 5600, + OpConstantFunctionPointerINTEL = 5600, OpFunctionPointerCallINTEL = 5601, + OpAsmTargetINTEL = 5609, + OpAsmINTEL = 5610, + OpAsmCallINTEL = 5611, + OpAtomicFMinEXT = 5614, + OpAtomicFMaxEXT = 5615, + OpAssumeTrueKHR = 5630, + OpExpectKHR = 5631, OpDecorateString = 5632, OpDecorateStringGOOGLE = 5632, OpMemberDecorateString = 5633, @@ -1590,7 +1790,67 @@ enum Op { OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, OpSubgroupAvcSicGetInterRawSadsINTEL = 5816, + OpVariableLengthArrayINTEL = 5818, + OpSaveMemoryINTEL = 5819, + OpRestoreMemoryINTEL = 5820, + OpArbitraryFloatSinCosPiINTEL = 5840, + OpArbitraryFloatCastINTEL = 5841, + OpArbitraryFloatCastFromIntINTEL = 5842, + OpArbitraryFloatCastToIntINTEL = 5843, + OpArbitraryFloatAddINTEL = 5846, + OpArbitraryFloatSubINTEL = 5847, + OpArbitraryFloatMulINTEL = 5848, + OpArbitraryFloatDivINTEL = 5849, + OpArbitraryFloatGTINTEL = 5850, + OpArbitraryFloatGEINTEL = 5851, + OpArbitraryFloatLTINTEL = 5852, + OpArbitraryFloatLEINTEL = 5853, + OpArbitraryFloatEQINTEL = 5854, + OpArbitraryFloatRecipINTEL = 5855, + OpArbitraryFloatRSqrtINTEL = 5856, + OpArbitraryFloatCbrtINTEL = 5857, + OpArbitraryFloatHypotINTEL = 5858, + OpArbitraryFloatSqrtINTEL = 5859, + OpArbitraryFloatLogINTEL = 5860, + OpArbitraryFloatLog2INTEL = 5861, + OpArbitraryFloatLog10INTEL = 5862, + OpArbitraryFloatLog1pINTEL = 5863, + OpArbitraryFloatExpINTEL = 5864, + OpArbitraryFloatExp2INTEL = 5865, + OpArbitraryFloatExp10INTEL = 5866, + OpArbitraryFloatExpm1INTEL = 5867, + OpArbitraryFloatSinINTEL = 5868, + OpArbitraryFloatCosINTEL = 5869, + OpArbitraryFloatSinCosINTEL = 5870, + OpArbitraryFloatSinPiINTEL = 5871, + OpArbitraryFloatCosPiINTEL = 5872, + OpArbitraryFloatASinINTEL = 5873, + OpArbitraryFloatASinPiINTEL = 5874, + OpArbitraryFloatACosINTEL = 5875, + OpArbitraryFloatACosPiINTEL = 5876, + OpArbitraryFloatATanINTEL = 5877, + OpArbitraryFloatATanPiINTEL = 5878, + OpArbitraryFloatATan2INTEL = 5879, + OpArbitraryFloatPowINTEL = 5880, + OpArbitraryFloatPowRINTEL = 5881, + OpArbitraryFloatPowNINTEL = 5882, OpLoopControlINTEL = 5887, + OpAliasDomainDeclINTEL = 5911, + OpAliasScopeDeclINTEL = 5912, + OpAliasScopeListDeclINTEL = 5913, + OpFixedSqrtINTEL = 5923, + OpFixedRecipINTEL = 5924, + OpFixedRsqrtINTEL = 5925, + OpFixedSinINTEL = 5926, + OpFixedCosINTEL = 5927, + OpFixedSinCosINTEL = 5928, + OpFixedSinPiINTEL = 5929, + OpFixedCosPiINTEL = 5930, + OpFixedSinCosPiINTEL = 5931, + OpFixedLogINTEL = 5932, + OpFixedExpINTEL = 5933, + OpPtrCastToCrossWorkgroupINTEL = 5934, + OpCrossWorkgroupCastToPtrINTEL = 5938, OpReadPipeBlockingINTEL = 5946, OpWritePipeBlockingINTEL = 5947, OpFPGARegINTEL = 5949, @@ -1612,10 +1872,27 @@ enum Op { OpRayQueryGetIntersectionObjectToWorldKHR = 6031, OpRayQueryGetIntersectionWorldToObjectKHR = 6032, OpAtomicFAddEXT = 6035, + OpTypeBufferSurfaceINTEL = 6086, + OpTypeStructContinuedINTEL = 6090, + OpConstantCompositeContinuedINTEL = 6091, + OpSpecConstantCompositeContinuedINTEL = 6092, + OpControlBarrierArriveINTEL = 6142, + OpControlBarrierWaitINTEL = 6143, + OpGroupIMulKHR = 6401, + OpGroupFMulKHR = 6402, + OpGroupBitwiseAndKHR = 6403, + OpGroupBitwiseOrKHR = 6404, + OpGroupBitwiseXorKHR = 6405, + OpGroupLogicalAndKHR = 6406, + OpGroupLogicalOrKHR = 6407, + OpGroupLogicalXorKHR = 6408, OpMax = 0x7fffffff, }; #ifdef SPV_ENABLE_UTILITY_CODE +#ifndef __cplusplus +#include +#endif inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { *hasResult = *hasResultType = false; switch (opcode) { @@ -1970,12 +2247,19 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; case OpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; case OpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; case OpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; case OpTraceRayKHR: *hasResult = false; *hasResultType = false; break; case OpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; case OpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; case OpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; case OpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; + case OpSDot: *hasResult = true; *hasResultType = true; break; + case OpUDot: *hasResult = true; *hasResultType = true; break; + case OpSUDot: *hasResult = true; *hasResultType = true; break; + case OpSDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpUDotAccSat: *hasResult = true; *hasResultType = true; break; + case OpSUDotAccSat: *hasResult = true; *hasResultType = true; break; case OpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; case OpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; case OpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; @@ -1995,12 +2279,16 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; case OpReadClockKHR: *hasResult = true; *hasResultType = true; break; case OpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; + case OpEmitMeshTasksEXT: *hasResult = false; *hasResultType = false; break; + case OpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break; case OpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; case OpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; case OpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; case OpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; case OpTerminateRayNV: *hasResult = false; *hasResultType = false; break; case OpTraceNV: *hasResult = false; *hasResultType = false; break; + case OpTraceMotionNV: *hasResult = false; *hasResultType = false; break; + case OpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; case OpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; case OpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; case OpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; @@ -2010,8 +2298,15 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; case OpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; case OpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; - case OpDemoteToHelperInvocationEXT: *hasResult = false; *hasResultType = false; break; + case OpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; case OpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; + case OpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; + case OpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; + case OpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; + case OpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; + case OpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; + case OpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; + case OpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; case OpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; @@ -2036,8 +2331,15 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; case OpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; case OpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; - case OpFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; + case OpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; case OpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmINTEL: *hasResult = true; *hasResultType = true; break; + case OpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; + case OpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; + case OpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; + case OpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; + case OpExpectKHR: *hasResult = true; *hasResultType = true; break; case OpDecorateString: *hasResult = false; *hasResultType = false; break; case OpMemberDecorateString: *hasResult = false; *hasResultType = false; break; case OpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; @@ -2158,7 +2460,67 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; case OpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; + case OpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; + case OpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; + case OpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; + case OpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; + case OpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; case OpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; + case OpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; + case OpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; + case OpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; + case OpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; + case OpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; case OpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; case OpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; case OpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; @@ -2180,6 +2542,20 @@ inline void HasResultAndType(Op opcode, bool *hasResult, bool *hasResultType) { case OpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; case OpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; case OpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; + case OpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; + case OpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; + case OpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; + case OpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; + case OpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; + case OpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; } } #endif /* SPV_ENABLE_UTILITY_CODE */ diff --git a/src/libraries/spirv_cross/spirv_cfg.cpp b/src/libraries/spirv_cross/spirv_cfg.cpp index a938634e2..932994798 100644 --- a/src/libraries/spirv_cross/spirv_cfg.cpp +++ b/src/libraries/spirv_cross/spirv_cfg.cpp @@ -306,15 +306,36 @@ bool CFG::node_terminates_control_flow_in_sub_graph(BlockID from, BlockID to) co bool true_path_ignore = false; bool false_path_ignore = false; - if (ignore_block_id && dom.terminator == SPIRBlock::Select) + + bool merges_to_nothing = dom.merge == SPIRBlock::MergeNone || + (dom.merge == SPIRBlock::MergeSelection && dom.next_block && + compiler.get(dom.next_block).terminator == SPIRBlock::Unreachable) || + (dom.merge == SPIRBlock::MergeLoop && dom.merge_block && + compiler.get(dom.merge_block).terminator == SPIRBlock::Unreachable); + + if (dom.self == from || merges_to_nothing) { - auto &true_block = compiler.get(dom.true_block); - auto &false_block = compiler.get(dom.false_block); - auto &ignore_block = compiler.get(ignore_block_id); - true_path_ignore = compiler.execution_is_branchless(true_block, ignore_block); - false_path_ignore = compiler.execution_is_branchless(false_block, ignore_block); + // We can only ignore inner branchy paths if there is no merge, + // i.e. no code is generated afterwards. E.g. this allows us to elide continue: + // for (;;) { if (cond) { continue; } else { break; } }. + // Codegen here in SPIR-V will be something like either no merge if one path directly breaks, or + // we merge to Unreachable. + if (ignore_block_id && dom.terminator == SPIRBlock::Select) + { + auto &true_block = compiler.get(dom.true_block); + auto &false_block = compiler.get(dom.false_block); + auto &ignore_block = compiler.get(ignore_block_id); + true_path_ignore = compiler.execution_is_branchless(true_block, ignore_block); + false_path_ignore = compiler.execution_is_branchless(false_block, ignore_block); + } } + // Cases where we allow traversal. This serves as a proxy for post-dominance in a loop body. + // TODO: Might want to do full post-dominance analysis, but it's a lot of churn for something like this ... + // - We're the merge block of a selection construct. Jump to header. + // - We're the merge block of a loop. Jump to header. + // - Direct branch. Trivial. + // - Allow cases inside a branch if the header cannot merge execution before loop exit. if ((dom.merge == SPIRBlock::MergeSelection && dom.next_block == to) || (dom.merge == SPIRBlock::MergeLoop && dom.merge_block == to) || (dom.terminator == SPIRBlock::Direct && dom.next_block == to) || diff --git a/src/libraries/spirv_cross/spirv_cfg.hpp b/src/libraries/spirv_cross/spirv_cfg.hpp index 90973b567..1d85fe0a9 100644 --- a/src/libraries/spirv_cross/spirv_cfg.hpp +++ b/src/libraries/spirv_cross/spirv_cfg.hpp @@ -59,6 +59,11 @@ class CFG return 0; } + bool is_reachable(uint32_t block) const + { + return visit_order.count(block) != 0; + } + uint32_t get_visit_order(uint32_t block) const { auto itr = visit_order.find(block); diff --git a/src/libraries/spirv_cross/spirv_common.hpp b/src/libraries/spirv_cross/spirv_common.hpp index bb2260e4d..7fce7ae7e 100644 --- a/src/libraries/spirv_cross/spirv_common.hpp +++ b/src/libraries/spirv_cross/spirv_common.hpp @@ -24,7 +24,11 @@ #ifndef SPIRV_CROSS_COMMON_HPP #define SPIRV_CROSS_COMMON_HPP +#ifndef SPV_ENABLE_UTILITY_CODE +#define SPV_ENABLE_UTILITY_CODE +#endif #include "spirv.hpp" + #include "spirv_cross_containers.hpp" #include "spirv_cross_error_handling.hpp" #include @@ -291,6 +295,20 @@ inline std::string convert_to_string(double t, char locale_radix_point) return buf; } +#if defined(__clang__) || defined(__GNUC__) +#pragma GCC diagnostic pop +#elif defined(_MSC_VER) +#pragma warning(pop) +#endif + +class FloatFormatter +{ +public: + virtual ~FloatFormatter() = default; + virtual std::string format_float(float value) = 0; + virtual std::string format_double(double value) = 0; +}; + template struct ValueSaver { @@ -314,12 +332,6 @@ struct ValueSaver T saved; }; -#if defined(__clang__) || defined(__GNUC__) -#pragma GCC diagnostic pop -#elif defined(_MSC_VER) -#pragma warning(pop) -#endif - struct Instruction { uint16_t op = 0; @@ -536,6 +548,9 @@ struct SPIRType : IVariant type = TypeType }; + spv::Op op = spv::Op::OpNop; + explicit SPIRType(spv::Op op_) : op(op_) {} + enum BaseType { Unknown, @@ -606,7 +621,7 @@ struct SPIRType : IVariant uint32_t sampled; spv::ImageFormat format; spv::AccessQualifier access; - } image; + } image = {}; // Structs can be declared multiple times if they are used as part of interface blocks. // We want to detect this so that we only emit the struct definition once. @@ -638,7 +653,10 @@ struct SPIRExtension : IVariant SPV_AMD_shader_ballot, SPV_AMD_shader_explicit_vertex_parameter, SPV_AMD_shader_trinary_minmax, - SPV_AMD_gcn_shader + SPV_AMD_gcn_shader, + NonSemanticDebugPrintf, + NonSemanticShaderDebugInfo, + NonSemanticGeneric }; explicit SPIRExtension(Extension ext_) @@ -672,10 +690,12 @@ struct SPIREntryPoint struct WorkgroupSize { uint32_t x = 0, y = 0, z = 0; + uint32_t id_x = 0, id_y = 0, id_z = 0; uint32_t constant = 0; // Workgroup size can be expressed as a constant/spec-constant instead. } workgroup_size; uint32_t invocations = 0; uint32_t output_vertices = 0; + uint32_t output_primitives = 0; spv::ExecutionModel model = spv::ExecutionModelMax; bool geometry_passthrough = false; }; @@ -689,7 +709,7 @@ struct SPIRExpression : IVariant // Only created by the backend target to avoid creating tons of temporaries. SPIRExpression(std::string expr, TypeID expression_type_, bool immutable_) - : expression(move(expr)) + : expression(std::move(expr)) , expression_type(expression_type_) , immutable(immutable_) { @@ -720,6 +740,9 @@ struct SPIRExpression : IVariant // Whether or not this is an access chain expression. bool access_chain = false; + // Whether or not gl_MeshVerticesEXT[].gl_Position (as a whole or .y) is referenced + bool access_meshlet_position_y = false; + // A list of expressions which this expression depends on. SmallVector expression_dependencies; @@ -770,7 +793,8 @@ struct SPIRBlock : IVariant Unreachable, // Noop Kill, // Discard IgnoreIntersection, // Ray Tracing - TerminateRay // Ray Tracing + TerminateRay, // Ray Tracing + EmitMeshTasks // Mesh shaders }; enum Merge @@ -832,6 +856,13 @@ struct SPIRBlock : IVariant BlockID false_block = 0; BlockID default_block = 0; + // If terminator is EmitMeshTasksEXT. + struct + { + ID groups[3]; + ID payload; + } mesh = {}; + SmallVector ops; struct Phi @@ -1071,7 +1102,6 @@ struct SPIRVariable : IVariant // Temporaries which can remain forwarded as long as this variable is not modified. SmallVector dependees; - bool forwardable = true; bool deferred_declaration = false; bool phi_variable = false; @@ -1563,6 +1593,8 @@ struct AccessChainMeta bool storage_is_packed = false; bool storage_is_invariant = false; bool flattened_struct = false; + bool relaxed_precision = false; + bool access_meshlet_position_y = false; }; enum ExtendedDecorations @@ -1630,6 +1662,12 @@ enum ExtendedDecorations // results of interpolation can. SPIRVCrossDecorationInterpolantComponentExpr, + // Apply to any struct type that is used in the Workgroup storage class. + // This causes matrices in MSL prior to Metal 3.0 to be emitted using a special + // class that is convertible to the standard matrix type, to work around the + // lack of constructors in the 'threadgroup' address space. + SPIRVCrossDecorationWorkgroupStruct, + SPIRVCrossDecorationCount }; @@ -1640,6 +1678,7 @@ struct Meta std::string alias; std::string qualified_alias; std::string hlsl_semantic; + std::string user_type; Bitset decoration_flags; spv::BuiltIn builtin_type = spv::BuiltInMax; uint32_t location = 0; @@ -1775,6 +1814,33 @@ static inline bool opcode_is_sign_invariant(spv::Op opcode) } } +static inline bool opcode_can_promote_integer_implicitly(spv::Op opcode) +{ + switch (opcode) + { + case spv::OpSNegate: + case spv::OpNot: + case spv::OpBitwiseAnd: + case spv::OpBitwiseOr: + case spv::OpBitwiseXor: + case spv::OpShiftLeftLogical: + case spv::OpShiftRightLogical: + case spv::OpShiftRightArithmetic: + case spv::OpIAdd: + case spv::OpISub: + case spv::OpIMul: + case spv::OpSDiv: + case spv::OpUDiv: + case spv::OpSRem: + case spv::OpUMod: + case spv::OpSMod: + return true; + + default: + return false; + } +} + struct SetBindingPair { uint32_t desc_set; diff --git a/src/libraries/spirv_cross/spirv_cpp.cpp b/src/libraries/spirv_cross/spirv_cpp.cpp index b7946bf33..dd0a84c83 100644 --- a/src/libraries/spirv_cross/spirv_cpp.cpp +++ b/src/libraries/spirv_cross/spirv_cpp.cpp @@ -274,8 +274,6 @@ void CompilerCPP::emit_resources() if (emitted) statement(""); - declare_undefined_values(); - statement("inline void init(spirv_cross_shader& s)"); begin_scope(); statement(resource_type, "::init(s);"); @@ -338,11 +336,8 @@ string CompilerCPP::compile() uint32_t pass_count = 0; do { - if (pass_count >= 3) - SPIRV_CROSS_THROW("Over 3 compilation loops detected. Must be a bug!"); - resource_registrations.clear(); - reset(); + reset(pass_count); // Move constructor for this type is broken on GCC 4.9 ... buffer.reset(); diff --git a/src/libraries/spirv_cross/spirv_cross.cpp b/src/libraries/spirv_cross/spirv_cross.cpp index dc8360663..4ab985efd 100644 --- a/src/libraries/spirv_cross/spirv_cross.cpp +++ b/src/libraries/spirv_cross/spirv_cross.cpp @@ -36,16 +36,16 @@ using namespace SPIRV_CROSS_NAMESPACE; Compiler::Compiler(vector ir_) { - Parser parser(move(ir_)); + Parser parser(std::move(ir_)); parser.parse(); - set_ir(move(parser.get_parsed_ir())); + set_ir(std::move(parser.get_parsed_ir())); } Compiler::Compiler(const uint32_t *ir_, size_t word_count) { Parser parser(ir_, word_count); parser.parse(); - set_ir(move(parser.get_parsed_ir())); + set_ir(std::move(parser.get_parsed_ir())); } Compiler::Compiler(const ParsedIR &ir_) @@ -55,12 +55,12 @@ Compiler::Compiler(const ParsedIR &ir_) Compiler::Compiler(ParsedIR &&ir_) { - set_ir(move(ir_)); + set_ir(std::move(ir_)); } void Compiler::set_ir(ParsedIR &&ir_) { - ir = move(ir_); + ir = std::move(ir_); parse_fixup(); } @@ -98,7 +98,8 @@ bool Compiler::block_is_pure(const SPIRBlock &block) // This is a global side effect of the function. if (block.terminator == SPIRBlock::Kill || block.terminator == SPIRBlock::TerminateRay || - block.terminator == SPIRBlock::IgnoreIntersection) + block.terminator == SPIRBlock::IgnoreIntersection || + block.terminator == SPIRBlock::EmitMeshTasks) return false; for (auto &i : block.ops) @@ -154,6 +155,11 @@ bool Compiler::block_is_pure(const SPIRBlock &block) case OpEmitVertex: return false; + // Mesh shader functions modify global state. + // (EmitMeshTasks is a terminator). + case OpSetMeshOutputsEXT: + return false; + // Barriers disallow any reordering, so we should treat blocks with barrier as writing. case OpControlBarrier: case OpMemoryBarrier: @@ -621,7 +627,22 @@ bool Compiler::is_matrix(const SPIRType &type) const bool Compiler::is_array(const SPIRType &type) const { - return !type.array.empty(); + return type.op == OpTypeArray || type.op == OpTypeRuntimeArray; +} + +bool Compiler::is_pointer(const SPIRType &type) const +{ + return type.op == OpTypePointer && type.basetype != SPIRType::Unknown; // Ignore function pointers. +} + +bool Compiler::is_physical_pointer(const SPIRType &type) const +{ + return type.op == OpTypePointer && type.storage == StorageClassPhysicalStorageBuffer; +} + +bool Compiler::is_runtime_size_array(const SPIRType &type) +{ + return type.op == OpTypeRuntimeArray; } ShaderResources Compiler::get_shader_resources() const @@ -719,7 +740,7 @@ bool Compiler::InterfaceVariableAccessHandler::handle(Op opcode, const uint32_t case OpExtInst: { - if (length < 5) + if (length < 3) return false; auto &extension_set = compiler.get(args[2]); switch (extension_set.ext) @@ -852,7 +873,7 @@ unordered_set Compiler::get_active_interface_variables() const void Compiler::set_enabled_interface_variables(std::unordered_set active_variables) { - active_interface_variables = move(active_variables); + active_interface_variables = std::move(active_variables); check_active_interface_variables = true; } @@ -985,57 +1006,74 @@ ShaderResources Compiler::get_shader_resources(const unordered_set * // in the future. res.push_constant_buffers.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); } - // Images - else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::Image && - type.image.sampled == 2) - { - res.storage_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); - } - // Separate images - else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::Image && - type.image.sampled == 1) - { - res.separate_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); - } - // Separate samplers - else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::Sampler) - { - res.separate_samplers.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); - } - // Textures - else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::SampledImage) + else if (type.storage == StorageClassShaderRecordBufferKHR) { - res.sampled_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); + res.shader_record_buffers.push_back({ var.self, var.basetype, type.self, get_remapped_declared_block_name(var.self, ssbo_instance_name) }); } // Atomic counters else if (type.storage == StorageClassAtomicCounter) { res.atomic_counters.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); } - // Acceleration structures - else if (type.storage == StorageClassUniformConstant && type.basetype == SPIRType::AccelerationStructure) + else if (type.storage == StorageClassUniformConstant) { - res.acceleration_structures.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); + if (type.basetype == SPIRType::Image) + { + // Images + if (type.image.sampled == 2) + { + res.storage_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); + } + // Separate images + else if (type.image.sampled == 1) + { + res.separate_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); + } + } + // Separate samplers + else if (type.basetype == SPIRType::Sampler) + { + res.separate_samplers.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); + } + // Textures + else if (type.basetype == SPIRType::SampledImage) + { + res.sampled_images.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); + } + // Acceleration structures + else if (type.basetype == SPIRType::AccelerationStructure) + { + res.acceleration_structures.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); + } + else + { + res.gl_plain_uniforms.push_back({ var.self, var.basetype, type.self, get_name(var.self) }); + } } }); return res; } -bool Compiler::type_is_block_like(const SPIRType &type) const +bool Compiler::type_is_top_level_block(const SPIRType &type) const { if (type.basetype != SPIRType::Struct) return false; + return has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock); +} - if (has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock)) - { +bool Compiler::type_is_block_like(const SPIRType &type) const +{ + if (type_is_top_level_block(type)) return true; - } - // Block-like types may have Offset decorations. - for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++) - if (has_member_decoration(type.self, i, DecorationOffset)) - return true; + if (type.basetype == SPIRType::Struct) + { + // Block-like types may have Offset decorations. + for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++) + if (has_member_decoration(type.self, i, DecorationOffset)) + return true; + } return false; } @@ -1050,10 +1088,12 @@ void Compiler::parse_fixup() if (id.get_type() == TypeConstant) { auto &c = id.get(); - if (ir.meta[c.self].decoration.builtin && ir.meta[c.self].decoration.builtin_type == BuiltInWorkgroupSize) + if (has_decoration(c.self, DecorationBuiltIn) && + BuiltIn(get_decoration(c.self, DecorationBuiltIn)) == BuiltInWorkgroupSize) { // In current SPIR-V, there can be just one constant like this. // All entry points will receive the constant value. + // WorkgroupSize take precedence over LocalSizeId. for (auto &entry : ir.entry_points) { entry.second.workgroup_size.constant = c.self; @@ -1067,8 +1107,11 @@ void Compiler::parse_fixup() { auto &var = id.get(); if (var.storage == StorageClassPrivate || var.storage == StorageClassWorkgroup || + var.storage == StorageClassTaskPayloadWorkgroupEXT || var.storage == StorageClassOutput) + { global_variables.push_back(var.self); + } if (variable_storage_is_aliased(var)) aliased_variables.push_back(var.self); } @@ -1453,6 +1496,58 @@ bool Compiler::get_binary_offset_for_decoration(VariableID id, spv::Decoration d return true; } +bool Compiler::block_is_noop(const SPIRBlock &block) const +{ + if (block.terminator != SPIRBlock::Direct) + return false; + + auto &child = get(block.next_block); + + // If this block participates in PHI, the block isn't really noop. + for (auto &phi : block.phi_variables) + if (phi.parent == block.self || phi.parent == child.self) + return false; + + for (auto &phi : child.phi_variables) + if (phi.parent == block.self) + return false; + + // Verify all instructions have no semantic impact. + for (auto &i : block.ops) + { + auto op = static_cast(i.op); + + switch (op) + { + // Non-Semantic instructions. + case OpLine: + case OpNoLine: + break; + + case OpExtInst: + { + auto *ops = stream(i); + auto ext = get(ops[2]).ext; + + bool ext_is_nonsemantic_only = + ext == SPIRExtension::NonSemanticShaderDebugInfo || + ext == SPIRExtension::SPV_debug_info || + ext == SPIRExtension::NonSemanticGeneric; + + if (!ext_is_nonsemantic_only) + return false; + + break; + } + + default: + return false; + } + } + + return true; +} + bool Compiler::block_is_loop_candidate(const SPIRBlock &block, SPIRBlock::Method method) const { // Tried and failed. @@ -1510,7 +1605,7 @@ bool Compiler::block_is_loop_candidate(const SPIRBlock &block, SPIRBlock::Method { // Empty loop header that just sets up merge target // and branches to loop body. - bool ret = block.terminator == SPIRBlock::Direct && block.merge == SPIRBlock::MergeLoop && block.ops.empty(); + bool ret = block.terminator == SPIRBlock::Direct && block.merge == SPIRBlock::MergeLoop && block_is_noop(block); if (!ret) return false; @@ -1536,19 +1631,8 @@ bool Compiler::block_is_loop_candidate(const SPIRBlock &block, SPIRBlock::Method ret = child.terminator == SPIRBlock::Select && child.merge == SPIRBlock::MergeNone && (positive_candidate || negative_candidate); - // If we have OpPhi which depends on branches which came from our own block, - // we need to flush phi variables in else block instead of a trivial break, - // so we cannot assume this is a for loop candidate. if (ret) { - for (auto &phi : block.phi_variables) - if (phi.parent == block.self || phi.parent == child.self) - return false; - - for (auto &phi : child.phi_variables) - if (phi.parent == block.self) - return false; - auto *merge = maybe_get(block.merge_block); if (merge) for (auto &phi : merge->phi_variables) @@ -1573,15 +1657,10 @@ bool Compiler::execution_is_noop(const SPIRBlock &from, const SPIRBlock &to) con if (start->self == to.self) return true; - if (!start->ops.empty()) + if (!block_is_noop(*start)) return false; auto &next = get(start->next_block); - // Flushing phi variables does not count as noop. - for (auto &phi : next.phi_variables) - if (phi.parent == start->self) - return false; - start = &next; } } @@ -1675,6 +1754,11 @@ const SmallVector &Compiler::get_case_list(const SPIRBlock &blo const auto &type = get(var->basetype); width = type.width; } + else if (const auto *undef = maybe_get(block.condition)) + { + const auto &type = get(undef->basetype); + width = type.width; + } else { auto search = ir.load_type_width.find(block.condition); @@ -2156,6 +2240,12 @@ void Compiler::set_execution_mode(ExecutionMode mode, uint32_t arg0, uint32_t ar execution.workgroup_size.z = arg2; break; + case ExecutionModeLocalSizeId: + execution.workgroup_size.id_x = arg0; + execution.workgroup_size.id_y = arg1; + execution.workgroup_size.id_z = arg2; + break; + case ExecutionModeInvocations: execution.invocations = arg0; break; @@ -2164,6 +2254,10 @@ void Compiler::set_execution_mode(ExecutionMode mode, uint32_t arg0, uint32_t ar execution.output_vertices = arg0; break; + case ExecutionModeOutputPrimitivesEXT: + execution.output_primitives = arg0; + break; + default: break; } @@ -2183,6 +2277,7 @@ uint32_t Compiler::get_work_group_size_specialization_constants(SpecializationCo y = { 0, 0 }; z = { 0, 0 }; + // WorkgroupSize builtin takes precedence over LocalSize / LocalSizeId. if (execution.workgroup_size.constant != 0) { auto &c = get(execution.workgroup_size.constant); @@ -2205,6 +2300,29 @@ uint32_t Compiler::get_work_group_size_specialization_constants(SpecializationCo z.constant_id = get_decoration(c.m.c[0].id[2], DecorationSpecId); } } + else if (execution.flags.get(ExecutionModeLocalSizeId)) + { + auto &cx = get(execution.workgroup_size.id_x); + if (cx.specialization) + { + x.id = execution.workgroup_size.id_x; + x.constant_id = get_decoration(execution.workgroup_size.id_x, DecorationSpecId); + } + + auto &cy = get(execution.workgroup_size.id_y); + if (cy.specialization) + { + y.id = execution.workgroup_size.id_y; + y.constant_id = get_decoration(execution.workgroup_size.id_y, DecorationSpecId); + } + + auto &cz = get(execution.workgroup_size.id_z); + if (cz.specialization) + { + z.id = execution.workgroup_size.id_z; + z.constant_id = get_decoration(execution.workgroup_size.id_z, DecorationSpecId); + } + } return execution.workgroup_size.constant; } @@ -2214,15 +2332,42 @@ uint32_t Compiler::get_execution_mode_argument(spv::ExecutionMode mode, uint32_t auto &execution = get_entry_point(); switch (mode) { + case ExecutionModeLocalSizeId: + if (execution.flags.get(ExecutionModeLocalSizeId)) + { + switch (index) + { + case 0: + return execution.workgroup_size.id_x; + case 1: + return execution.workgroup_size.id_y; + case 2: + return execution.workgroup_size.id_z; + default: + return 0; + } + } + else + return 0; + case ExecutionModeLocalSize: switch (index) { case 0: - return execution.workgroup_size.x; + if (execution.flags.get(ExecutionModeLocalSizeId) && execution.workgroup_size.id_x != 0) + return get(execution.workgroup_size.id_x).scalar(); + else + return execution.workgroup_size.x; case 1: - return execution.workgroup_size.y; + if (execution.flags.get(ExecutionModeLocalSizeId) && execution.workgroup_size.id_y != 0) + return get(execution.workgroup_size.id_y).scalar(); + else + return execution.workgroup_size.y; case 2: - return execution.workgroup_size.z; + if (execution.flags.get(ExecutionModeLocalSizeId) && execution.workgroup_size.id_z != 0) + return get(execution.workgroup_size.id_z).scalar(); + else + return execution.workgroup_size.z; default: return 0; } @@ -2233,6 +2378,9 @@ uint32_t Compiler::get_execution_mode_argument(spv::ExecutionMode mode, uint32_t case ExecutionModeOutputVertices: return execution.output_vertices; + case ExecutionModeOutputPrimitivesEXT: + return execution.output_primitives; + default: return 0; } @@ -2261,6 +2409,11 @@ bool Compiler::is_tessellation_shader() const return is_tessellation_shader(get_execution_model()); } +bool Compiler::is_tessellating_triangles() const +{ + return get_execution_mode_bitset().get(ExecutionModeTriangles); +} + void Compiler::set_remapped_variable_state(VariableID id, bool remap_enable) { get(id).remapped_variable = remap_enable; @@ -2295,6 +2448,19 @@ void Compiler::add_implied_read_expression(SPIRAccessChain &e, uint32_t source) e.implied_read_expressions.push_back(source); } +void Compiler::add_active_interface_variable(uint32_t var_id) +{ + active_interface_variables.insert(var_id); + + // In SPIR-V 1.4 and up we must also track the interface variable in the entry point. + if (ir.get_spirv_version() >= 0x10400) + { + auto &vars = get_entry_point().interface_variables; + if (find(begin(vars), end(vars), VariableID(var_id)) == end(vars)) + vars.push_back(var_id); + } +} + void Compiler::inherit_expression_dependencies(uint32_t dst, uint32_t source_expression) { // Don't inherit any expression dependencies if the expression in dst @@ -2449,7 +2615,7 @@ void Compiler::CombinedImageSamplerHandler::push_remap_parameters(const SPIRFunc unordered_map remapping; for (uint32_t i = 0; i < length; i++) remapping[func.arguments[i].id] = remap_parameter(args[i]); - parameter_remapping.push(move(remapping)); + parameter_remapping.push(std::move(remapping)); } void Compiler::CombinedImageSamplerHandler::pop_remap_parameters() @@ -2579,8 +2745,8 @@ void Compiler::CombinedImageSamplerHandler::register_combined_image_sampler(SPIR auto ptr_type_id = id + 1; auto combined_id = id + 2; auto &base = compiler.expression_type(image_id); - auto &type = compiler.set(type_id); - auto &ptr_type = compiler.set(ptr_type_id); + auto &type = compiler.set(type_id, OpTypeSampledImage); + auto &ptr_type = compiler.set(ptr_type_id, OpTypePointer); type = base; type.self = type_id; @@ -2839,7 +3005,7 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar { // Have to invent the sampled image type. sampled_type = compiler.ir.increase_bound_by(1); - auto &type = compiler.set(sampled_type); + auto &type = compiler.set(sampled_type, OpTypeSampledImage); type = compiler.expression_type(args[2]); type.self = sampled_type; type.basetype = SPIRType::SampledImage; @@ -2858,7 +3024,7 @@ bool Compiler::CombinedImageSamplerHandler::handle(Op opcode, const uint32_t *ar // Make a new type, pointer to OpTypeSampledImage, so we can make a variable of this type. // We will probably have this type lying around, but it doesn't hurt to make duplicates for internal purposes. - auto &type = compiler.set(type_id); + auto &type = compiler.set(type_id, OpTypePointer); auto &base = compiler.get(sampled_type); type = base; type.pointer = true; @@ -2904,11 +3070,10 @@ VariableID Compiler::build_dummy_sampler_for_combined_images() auto ptr_type_id = offset + 1; auto var_id = offset + 2; - SPIRType sampler_type; - auto &sampler = set(type_id); + auto &sampler = set(type_id, OpTypeSampler); sampler.basetype = SPIRType::Sampler; - auto &ptr_sampler = set(ptr_type_id); + auto &ptr_sampler = set(ptr_type_id, OpTypePointer); ptr_sampler = sampler; ptr_sampler.self = type_id; ptr_sampler.storage = StorageClassUniformConstant; @@ -3111,8 +3276,8 @@ void Compiler::AnalyzeVariableScopeAccessHandler::notify_variable_access(uint32_ return; // Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. - auto itr = access_chain_children.find(id); - if (itr != end(access_chain_children)) + auto itr = rvalue_forward_children.find(id); + if (itr != end(rvalue_forward_children)) for (auto child_id : itr->second) notify_variable_access(child_id, block); @@ -3165,7 +3330,20 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3 // Keep track of the types of temporaries, so we can hoist them out as necessary. uint32_t result_type, result_id; if (compiler.instruction_to_result_type(result_type, result_id, op, args, length)) + { + // For some opcodes, we will need to override the result id. + // If we need to hoist the temporary, the temporary type is the input, not the result. + // FIXME: This will likely break with OpCopyObject + hoisting, but we'll have to + // solve it if we ever get there ... + if (op == OpConvertUToAccelerationStructureKHR) + { + auto itr = result_id_to_type.find(args[2]); + if (itr != result_id_to_type.end()) + result_type = itr->second; + } + result_id_to_type[result_id] = result_type; + } switch (op) { @@ -3207,14 +3385,14 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3 if (var) { accessed_variables_to_block[var->self].insert(current_block->self); - access_chain_children[args[1]].insert(var->self); + rvalue_forward_children[args[1]].insert(var->self); } // args[2] might be another access chain we have to track use of. for (uint32_t i = 2; i < length; i++) { notify_variable_access(args[i], current_block->self); - access_chain_children[args[1]].insert(args[i]); + rvalue_forward_children[args[1]].insert(args[i]); } // Also keep track of the access chain pointer itself. @@ -3296,6 +3474,12 @@ bool Compiler::AnalyzeVariableScopeAccessHandler::handle(spv::Op op, const uint3 // Might be an access chain we have to track use of. notify_variable_access(args[2], current_block->self); + + // If we're loading an opaque type we cannot lower it to a temporary, + // we must defer access of args[2] until it's used. + auto &type = compiler.get(args[0]); + if (compiler.type_is_opaque_value(type)) + rvalue_forward_children[args[1]].insert(args[2]); break; } @@ -3667,6 +3851,7 @@ void Compiler::analyze_variable_scope(SPIRFunction &entry, AnalyzeVariableScopeA DominatorBuilder builder(cfg); auto &blocks = var.second; auto &type = expression_type(var.first); + BlockID potential_continue_block = 0; // Figure out which block is dominating all accesses of those variables. for (auto &block : blocks) @@ -3688,14 +3873,13 @@ void Compiler::analyze_variable_scope(SPIRFunction &entry, AnalyzeVariableScopeA { // The variable is used in multiple continue blocks, this is not a loop // candidate, signal that by setting block to -1u. - auto &potential = potential_loop_variables[var.first]; - - if (potential == 0) - potential = block; + if (potential_continue_block == 0) + potential_continue_block = block; else - potential = ~(0u); + potential_continue_block = ~(0u); } } + builder.add_block(block); } @@ -3704,6 +3888,34 @@ void Compiler::analyze_variable_scope(SPIRFunction &entry, AnalyzeVariableScopeA // Add it to a per-block list of variables. BlockID dominating_block = builder.get_dominator(); + if (dominating_block && potential_continue_block != 0 && potential_continue_block != ~0u) + { + auto &inner_block = get(dominating_block); + + BlockID merge_candidate = 0; + + // Analyze the dominator. If it lives in a different loop scope than the candidate continue + // block, reject the loop variable candidate. + if (inner_block.merge == SPIRBlock::MergeLoop) + merge_candidate = inner_block.merge_block; + else if (inner_block.loop_dominator != SPIRBlock::NoDominator) + merge_candidate = get(inner_block.loop_dominator).merge_block; + + if (merge_candidate != 0 && cfg.is_reachable(merge_candidate)) + { + // If the merge block has a higher post-visit order, we know that continue candidate + // cannot reach the merge block, and we have two separate scopes. + if (!cfg.is_reachable(potential_continue_block) || + cfg.get_visit_order(merge_candidate) > cfg.get_visit_order(potential_continue_block)) + { + potential_continue_block = 0; + } + } + } + + if (potential_continue_block != 0 && potential_continue_block != ~0u) + potential_loop_variables[var.first] = potential_continue_block; + // For variables whose dominating block is inside a loop, there is a risk that these variables // actually need to be preserved across loop iterations. We can express this by adding // a "read" access to the loop header. @@ -4303,8 +4515,9 @@ void Compiler::analyze_image_and_sampler_usage() handler.dependency_hierarchy.clear(); traverse_all_reachable_opcodes(get(ir.default_entry_point), handler); - comparison_ids = move(handler.comparison_ids); + comparison_ids = std::move(handler.comparison_ids); need_subpass_input = handler.need_subpass_input; + need_subpass_input_ms = handler.need_subpass_input_ms; // Forward information from separate images and samplers into combined image samplers. for (auto &combined : combined_image_samplers) @@ -4356,7 +4569,7 @@ void Compiler::build_function_control_flow_graphs_and_analyze() CFGBuilder handler(*this); handler.function_cfgs[ir.default_entry_point].reset(new CFG(*this, get(ir.default_entry_point))); traverse_all_reachable_opcodes(get(ir.default_entry_point), handler); - function_cfgs = move(handler.function_cfgs); + function_cfgs = std::move(handler.function_cfgs); bool single_function = function_cfgs.size() <= 1; for (auto &f : function_cfgs) @@ -4471,7 +4684,11 @@ bool Compiler::CombinedImageSamplerUsageHandler::handle(Op opcode, const uint32_ // If we load an image, we're going to use it and there is little harm in declaring an unused gl_FragCoord. auto &type = compiler.get(args[0]); if (type.image.dim == DimSubpassData) + { need_subpass_input = true; + if (type.image.ms) + need_subpass_input_ms = true; + } // If we load a SampledImage and it will be used with Dref, propagate the state up. if (dref_combined_samplers.count(args[1]) != 0) @@ -4646,46 +4863,22 @@ bool Compiler::reflection_ssbo_instance_name_is_significant() const return aliased_ssbo_types; } -bool Compiler::instruction_to_result_type(uint32_t &result_type, uint32_t &result_id, spv::Op op, const uint32_t *args, - uint32_t length) +bool Compiler::instruction_to_result_type(uint32_t &result_type, uint32_t &result_id, spv::Op op, + const uint32_t *args, uint32_t length) { - // Most instructions follow the pattern of . - // There are some exceptions. - switch (op) - { - case OpStore: - case OpCopyMemory: - case OpCopyMemorySized: - case OpImageWrite: - case OpAtomicStore: - case OpAtomicFlagClear: - case OpEmitStreamVertex: - case OpEndStreamPrimitive: - case OpControlBarrier: - case OpMemoryBarrier: - case OpGroupWaitEvents: - case OpRetainEvent: - case OpReleaseEvent: - case OpSetUserEventStatus: - case OpCaptureEventProfilingInfo: - case OpCommitReadPipe: - case OpCommitWritePipe: - case OpGroupCommitReadPipe: - case OpGroupCommitWritePipe: - case OpLine: - case OpNoLine: + if (length < 2) return false; - default: - if (length > 1 && maybe_get(args[0]) != nullptr) - { - result_type = args[0]; - result_id = args[1]; - return true; - } - else - return false; + bool has_result_id = false, has_result_type = false; + HasResultAndType(op, &has_result_id, &has_result_type); + if (has_result_id && has_result_type) + { + result_type = args[0]; + result_id = args[1]; + return true; } + else + return false; } Bitset Compiler::combined_decoration_for_member(const SPIRType &type, uint32_t index) const @@ -4769,6 +4962,12 @@ void Compiler::force_recompile() is_force_recompile = true; } +void Compiler::force_recompile_guarantee_forward_progress() +{ + force_recompile(); + is_force_recompile_forward_progress = true; +} + bool Compiler::is_forcing_recompilation() const { return is_force_recompile; @@ -4777,6 +4976,7 @@ bool Compiler::is_forcing_recompilation() const void Compiler::clear_force_recompile() { is_force_recompile = false; + is_force_recompile_forward_progress = false; } Compiler::PhysicalStorageBufferPointerHandler::PhysicalStorageBufferPointerHandler(Compiler &compiler_) @@ -4958,7 +5158,7 @@ void Compiler::analyze_non_block_pointer_types() for (auto type : handler.non_block_types) physical_storage_non_block_pointer_types.push_back(type); sort(begin(physical_storage_non_block_pointer_types), end(physical_storage_non_block_pointer_types)); - physical_storage_type_to_alignment = move(handler.physical_block_type_meta); + physical_storage_type_to_alignment = std::move(handler.physical_block_type_meta); } bool Compiler::InterlockedResourceAccessPrepassHandler::handle(Op op, const uint32_t *, uint32_t) @@ -5271,19 +5471,51 @@ void Compiler::analyze_interlocked_resource_usage() } } -bool Compiler::type_is_array_of_pointers(const SPIRType &type) const +// Helper function +bool Compiler::check_internal_recursion(const SPIRType &type, std::unordered_set &checked_ids) { - if (!type.pointer) + if (type.basetype != SPIRType::Struct) return false; - // If parent type has same pointer depth, we must have an array of pointers. - return type.pointer_depth == get(type.parent_type).pointer_depth; + if (checked_ids.count(type.self)) + return true; + + // Recurse into struct members + bool is_recursive = false; + checked_ids.insert(type.self); + uint32_t mbr_cnt = uint32_t(type.member_types.size()); + for (uint32_t mbr_idx = 0; !is_recursive && mbr_idx < mbr_cnt; mbr_idx++) + { + uint32_t mbr_type_id = type.member_types[mbr_idx]; + auto &mbr_type = get(mbr_type_id); + is_recursive |= check_internal_recursion(mbr_type, checked_ids); + } + checked_ids.erase(type.self); + return is_recursive; +} + +// Return whether the struct type contains a structural recursion nested somewhere within its content. +bool Compiler::type_contains_recursion(const SPIRType &type) +{ + std::unordered_set checked_ids; + return check_internal_recursion(type, checked_ids); } -bool Compiler::type_is_top_level_physical_pointer(const SPIRType &type) const +bool Compiler::type_is_array_of_pointers(const SPIRType &type) const { - return type.pointer && type.storage == StorageClassPhysicalStorageBuffer && - type.pointer_depth > get(type.parent_type).pointer_depth; + if (!is_array(type)) + return false; + + // BDA types must have parent type hierarchy. + if (!type.parent_type) + return false; + + // Punch through all array layers. + auto *parent = &get(type.parent_type); + while (is_array(*parent)) + parent = &get(parent->parent_type); + + return is_pointer(*parent); } bool Compiler::flush_phi_required(BlockID from, BlockID to) const diff --git a/src/libraries/spirv_cross/spirv_cross.hpp b/src/libraries/spirv_cross/spirv_cross.hpp index c945401d8..9fe6c41c4 100644 --- a/src/libraries/spirv_cross/spirv_cross.hpp +++ b/src/libraries/spirv_cross/spirv_cross.hpp @@ -24,6 +24,9 @@ #ifndef SPIRV_CROSS_HPP #define SPIRV_CROSS_HPP +#ifndef SPV_ENABLE_UTILITY_CODE +#define SPV_ENABLE_UTILITY_CODE +#endif #include "spirv.hpp" #include "spirv_cfg.hpp" #include "spirv_cross_parsed_ir.hpp" @@ -91,11 +94,14 @@ struct ShaderResources SmallVector sampled_images; SmallVector atomic_counters; SmallVector acceleration_structures; + SmallVector gl_plain_uniforms; // There can only be one push constant block, // but keep the vector in case this restriction is lifted in the future. SmallVector push_constant_buffers; + SmallVector shader_record_buffers; + // For Vulkan GLSL and HLSL source, // these correspond to separate texture2D and samplers respectively. SmallVector separate_images; @@ -357,12 +363,16 @@ class Compiler void set_execution_mode(spv::ExecutionMode mode, uint32_t arg0 = 0, uint32_t arg1 = 0, uint32_t arg2 = 0); // Gets argument for an execution mode (LocalSize, Invocations, OutputVertices). - // For LocalSize, the index argument is used to select the dimension (X = 0, Y = 1, Z = 2). + // For LocalSize or LocalSizeId, the index argument is used to select the dimension (X = 0, Y = 1, Z = 2). // For execution modes which do not have arguments, 0 is returned. + // LocalSizeId query returns an ID. If LocalSizeId execution mode is not used, it returns 0. + // LocalSize always returns a literal. If execution mode is LocalSizeId, + // the literal (spec constant or not) is still returned. uint32_t get_execution_mode_argument(spv::ExecutionMode mode, uint32_t index = 0) const; spv::ExecutionModel get_execution_model() const; bool is_tessellation_shader() const; + bool is_tessellating_triangles() const; // In SPIR-V, the compute work group size can be represented by a constant vector, in which case // the LocalSize execution mode is ignored. @@ -380,6 +390,8 @@ class Compiler // If the component is not a specialization constant, a zeroed out struct will be written. // The return value is the constant ID of the builtin WorkGroupSize, but this is not expected to be useful // for most use cases. + // If LocalSizeId is used, there is no uvec3 value representing the workgroup size, so the return value is 0, + // but x, y and z are written as normal if the components are specialization constants. uint32_t get_work_group_size_specialization_constants(SpecializationConstant &x, SpecializationConstant &y, SpecializationConstant &z) const; @@ -551,6 +563,11 @@ class Compiler } } + uint32_t *stream_mutable(const Instruction &instr) const + { + return const_cast(stream(instr)); + } + ParsedIR ir; // Marks variables which have global scope and variables which can alias with other variables // (SSBO, image load store, etc) @@ -666,6 +683,9 @@ class Compiler bool is_vector(const SPIRType &type) const; bool is_matrix(const SPIRType &type) const; bool is_array(const SPIRType &type) const; + bool is_pointer(const SPIRType &type) const; + bool is_physical_pointer(const SPIRType &type) const; + static bool is_runtime_size_array(const SPIRType &type); uint32_t expression_type_id(uint32_t id) const; const SPIRType &expression_type(uint32_t id) const; bool expression_is_lvalue(uint32_t id) const; @@ -730,16 +750,20 @@ class Compiler SPIRBlock::ContinueBlockType continue_block_type(const SPIRBlock &continue_block) const; void force_recompile(); + void force_recompile_guarantee_forward_progress(); void clear_force_recompile(); bool is_forcing_recompilation() const; bool is_force_recompile = false; + bool is_force_recompile_forward_progress = false; + bool block_is_noop(const SPIRBlock &block) const; bool block_is_loop_candidate(const SPIRBlock &block, SPIRBlock::Method method) const; bool types_are_logically_equivalent(const SPIRType &a, const SPIRType &b) const; void inherit_expression_dependencies(uint32_t dst, uint32_t source); void add_implied_read_expression(SPIRExpression &e, uint32_t source); void add_implied_read_expression(SPIRAccessChain &e, uint32_t source); + void add_active_interface_variable(uint32_t var_id); // For proper multiple entry point support, allow querying if an Input or Output // variable is part of that entry points interface. @@ -915,6 +939,7 @@ class Compiler // Similar is implemented for images, as well as if subpass inputs are needed. std::unordered_set comparison_ids; bool need_subpass_input = false; + bool need_subpass_input_ms = false; // In certain backends, we will need to use a dummy sampler to be able to emit code. // GLSL does not support texelFetch on texture2D objects, but SPIR-V does, @@ -954,6 +979,7 @@ class Compiler void add_hierarchy_to_comparison_ids(uint32_t ids); bool need_subpass_input = false; + bool need_subpass_input_ms = false; void add_dependency(uint32_t dst, uint32_t src); }; @@ -994,7 +1020,8 @@ class Compiler std::unordered_map> partial_write_variables_to_block; std::unordered_set access_chain_expressions; // Access chains used in multiple blocks mean hoisting all the variables used to construct the access chain as not all backends can use pointers. - std::unordered_map> access_chain_children; + // This is also relevant when forwarding opaque objects since we cannot lower these to temporaries. + std::unordered_map> rvalue_forward_children; const SPIRBlock *current_block = nullptr; }; @@ -1120,9 +1147,11 @@ class Compiler bool has_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration) const; void unset_extended_member_decoration(uint32_t type, uint32_t index, ExtendedDecorations decoration); + bool check_internal_recursion(const SPIRType &type, std::unordered_set &checked_ids); + bool type_contains_recursion(const SPIRType &type); bool type_is_array_of_pointers(const SPIRType &type) const; - bool type_is_top_level_physical_pointer(const SPIRType &type) const; bool type_is_block_like(const SPIRType &type) const; + bool type_is_top_level_block(const SPIRType &type) const; bool type_is_opaque_value(const SPIRType &type) const; bool reflection_ssbo_instance_name_is_significant() const; diff --git a/src/libraries/spirv_cross/spirv_cross_c.cpp b/src/libraries/spirv_cross/spirv_cross_c.cpp index 4d5615404..dc2e5ea81 100644 --- a/src/libraries/spirv_cross/spirv_cross_c.cpp +++ b/src/libraries/spirv_cross/spirv_cross_c.cpp @@ -194,6 +194,7 @@ struct spvc_resources_s : ScratchMemoryAllocation SmallVector sampled_images; SmallVector atomic_counters; SmallVector push_constant_buffers; + SmallVector shader_record_buffers; SmallVector separate_images; SmallVector separate_samplers; SmallVector acceleration_structures; @@ -251,7 +252,7 @@ spvc_result spvc_context_parse_spirv(spvc_context context, const SpvId *spirv, s pir->context = context; Parser parser(spirv, word_count); parser.parse(); - pir->parsed = move(parser.get_parsed_ir()); + pir->parsed = std::move(parser.get_parsed_ir()); *parsed_ir = pir.get(); context->allocations.push_back(std::move(pir)); } @@ -283,7 +284,7 @@ spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend back { case SPVC_BACKEND_NONE: if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP) - comp->compiler.reset(new Compiler(move(parsed_ir->parsed))); + comp->compiler.reset(new Compiler(std::move(parsed_ir->parsed))); else if (mode == SPVC_CAPTURE_MODE_COPY) comp->compiler.reset(new Compiler(parsed_ir->parsed)); break; @@ -291,7 +292,7 @@ spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend back #if SPIRV_CROSS_C_API_GLSL case SPVC_BACKEND_GLSL: if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP) - comp->compiler.reset(new CompilerGLSL(move(parsed_ir->parsed))); + comp->compiler.reset(new CompilerGLSL(std::move(parsed_ir->parsed))); else if (mode == SPVC_CAPTURE_MODE_COPY) comp->compiler.reset(new CompilerGLSL(parsed_ir->parsed)); break; @@ -300,7 +301,7 @@ spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend back #if SPIRV_CROSS_C_API_HLSL case SPVC_BACKEND_HLSL: if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP) - comp->compiler.reset(new CompilerHLSL(move(parsed_ir->parsed))); + comp->compiler.reset(new CompilerHLSL(std::move(parsed_ir->parsed))); else if (mode == SPVC_CAPTURE_MODE_COPY) comp->compiler.reset(new CompilerHLSL(parsed_ir->parsed)); break; @@ -309,7 +310,7 @@ spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend back #if SPIRV_CROSS_C_API_MSL case SPVC_BACKEND_MSL: if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP) - comp->compiler.reset(new CompilerMSL(move(parsed_ir->parsed))); + comp->compiler.reset(new CompilerMSL(std::move(parsed_ir->parsed))); else if (mode == SPVC_CAPTURE_MODE_COPY) comp->compiler.reset(new CompilerMSL(parsed_ir->parsed)); break; @@ -318,7 +319,7 @@ spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend back #if SPIRV_CROSS_C_API_CPP case SPVC_BACKEND_CPP: if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP) - comp->compiler.reset(new CompilerCPP(move(parsed_ir->parsed))); + comp->compiler.reset(new CompilerCPP(std::move(parsed_ir->parsed))); else if (mode == SPVC_CAPTURE_MODE_COPY) comp->compiler.reset(new CompilerCPP(parsed_ir->parsed)); break; @@ -327,7 +328,7 @@ spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend back #if SPIRV_CROSS_C_API_REFLECT case SPVC_BACKEND_JSON: if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP) - comp->compiler.reset(new CompilerReflection(move(parsed_ir->parsed))); + comp->compiler.reset(new CompilerReflection(std::move(parsed_ir->parsed))); else if (mode == SPVC_CAPTURE_MODE_COPY) comp->compiler.reset(new CompilerReflection(parsed_ir->parsed)); break; @@ -475,6 +476,12 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c case SPVC_COMPILER_OPTION_GLSL_OVR_MULTIVIEW_VIEW_COUNT: options->glsl.ovr_multiview_view_count = value; break; + case SPVC_COMPILER_OPTION_RELAX_NAN_CHECKS: + options->glsl.relax_nan_checks = value != 0; + break; + case SPVC_COMPILER_OPTION_GLSL_ENABLE_ROW_MAJOR_LOAD_WORKAROUND: + options->glsl.enable_row_major_load_workaround = value != 0; + break; #endif #if SPIRV_CROSS_C_API_HLSL @@ -711,6 +718,42 @@ spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_c case SPVC_COMPILER_OPTION_MSL_IOS_SUPPORT_BASE_VERTEX_INSTANCE: options->msl.ios_support_base_vertex_instance = value != 0; break; + + case SPVC_COMPILER_OPTION_MSL_RAW_BUFFER_TESE_INPUT: + options->msl.raw_buffer_tese_input = value != 0; + break; + + case SPVC_COMPILER_OPTION_MSL_SHADER_PATCH_INPUT_BUFFER_INDEX: + options->msl.shader_patch_input_buffer_index = value; + break; + + case SPVC_COMPILER_OPTION_MSL_MANUAL_HELPER_INVOCATION_UPDATES: + options->msl.manual_helper_invocation_updates = value != 0; + break; + + case SPVC_COMPILER_OPTION_MSL_CHECK_DISCARDED_FRAG_STORES: + options->msl.check_discarded_frag_stores = value != 0; + break; + + case SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS_TIER: + options->msl.argument_buffers_tier = static_cast(value); + break; + + case SPVC_COMPILER_OPTION_MSL_SAMPLE_DREF_LOD_ARRAY_AS_GRAD: + options->msl.sample_dref_lod_array_as_grad = value != 0; + break; + + case SPVC_COMPILER_OPTION_MSL_READWRITE_TEXTURE_FENCES: + options->msl.readwrite_texture_fences = value != 0; + break; + + case SPVC_COMPILER_OPTION_MSL_REPLACE_RECURSIVE_INPUTS: + options->msl.replace_recursive_inputs = value != 0; + break; + + case SPVC_COMPILER_OPTION_MSL_AGX_MANUAL_CUBE_GRAD_FIXUP: + options->msl.agx_manual_cube_grad_fixup = value != 0; + break; #endif default: @@ -789,6 +832,43 @@ spvc_result spvc_compiler_require_extension(spvc_compiler compiler, const char * #endif } +size_t spvc_compiler_get_num_required_extensions(spvc_compiler compiler) +{ +#if SPIRV_CROSS_C_API_GLSL + if (compiler->backend != SPVC_BACKEND_GLSL) + { + compiler->context->report_error("Enabled extensions can only be queried on GLSL backend."); + return SPVC_ERROR_INVALID_ARGUMENT; + } + + return static_cast(compiler->compiler.get())->get_required_extensions().size(); +#else + compiler->context->report_error("Enabled extensions can only be queried on GLSL backend."); + return 0; +#endif +} + +const char *spvc_compiler_get_required_extension(spvc_compiler compiler, size_t index) +{ +#if SPIRV_CROSS_C_API_GLSL + if (compiler->backend != SPVC_BACKEND_GLSL) + { + compiler->context->report_error("Enabled extensions can only be queried on GLSL backend."); + return nullptr; + } + + auto &exts = static_cast(compiler->compiler.get())->get_required_extensions(); + if (index < exts.size()) + return exts[index].c_str(); + else + return nullptr; +#else + (void)index; + compiler->context->report_error("Enabled extensions can only be queried on GLSL backend."); + return nullptr; +#endif +} + spvc_result spvc_compiler_flatten_buffer_block(spvc_compiler compiler, spvc_variable_id id) { #if SPIRV_CROSS_C_API_GLSL @@ -1133,9 +1213,9 @@ spvc_result spvc_compiler_msl_add_vertex_attribute(spvc_compiler compiler, const } auto &msl = *static_cast(compiler->compiler.get()); - MSLShaderInput attr; + MSLShaderInterfaceVariable attr; attr.location = va->location; - attr.format = static_cast(va->format); + attr.format = static_cast(va->format); attr.builtin = static_cast(va->builtin); msl.add_msl_shader_input(attr); return SPVC_SUCCESS; @@ -1146,7 +1226,7 @@ spvc_result spvc_compiler_msl_add_vertex_attribute(spvc_compiler compiler, const #endif } -spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler, const spvc_msl_shader_input *si) +spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler, const spvc_msl_shader_interface_var *si) { #if SPIRV_CROSS_C_API_MSL if (compiler->backend != SPVC_BACKEND_MSL) @@ -1156,9 +1236,9 @@ spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler, const spv } auto &msl = *static_cast(compiler->compiler.get()); - MSLShaderInput input; + MSLShaderInterfaceVariable input; input.location = si->location; - input.format = static_cast(si->format); + input.format = static_cast(si->format); input.builtin = static_cast(si->builtin); input.vecsize = si->vecsize; msl.add_msl_shader_input(input); @@ -1170,6 +1250,80 @@ spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler, const spv #endif } +spvc_result spvc_compiler_msl_add_shader_input_2(spvc_compiler compiler, const spvc_msl_shader_interface_var_2 *si) +{ +#if SPIRV_CROSS_C_API_MSL + if (compiler->backend != SPVC_BACKEND_MSL) + { + compiler->context->report_error("MSL function used on a non-MSL backend."); + return SPVC_ERROR_INVALID_ARGUMENT; + } + + auto &msl = *static_cast(compiler->compiler.get()); + MSLShaderInterfaceVariable input; + input.location = si->location; + input.format = static_cast(si->format); + input.builtin = static_cast(si->builtin); + input.vecsize = si->vecsize; + input.rate = static_cast(si->rate); + msl.add_msl_shader_input(input); + return SPVC_SUCCESS; +#else + (void)si; + compiler->context->report_error("MSL function used on a non-MSL backend."); + return SPVC_ERROR_INVALID_ARGUMENT; +#endif +} + +spvc_result spvc_compiler_msl_add_shader_output(spvc_compiler compiler, const spvc_msl_shader_interface_var *so) +{ +#if SPIRV_CROSS_C_API_MSL + if (compiler->backend != SPVC_BACKEND_MSL) + { + compiler->context->report_error("MSL function used on a non-MSL backend."); + return SPVC_ERROR_INVALID_ARGUMENT; + } + + auto &msl = *static_cast(compiler->compiler.get()); + MSLShaderInterfaceVariable output; + output.location = so->location; + output.format = static_cast(so->format); + output.builtin = static_cast(so->builtin); + output.vecsize = so->vecsize; + msl.add_msl_shader_output(output); + return SPVC_SUCCESS; +#else + (void)so; + compiler->context->report_error("MSL function used on a non-MSL backend."); + return SPVC_ERROR_INVALID_ARGUMENT; +#endif +} + +spvc_result spvc_compiler_msl_add_shader_output_2(spvc_compiler compiler, const spvc_msl_shader_interface_var_2 *so) +{ +#if SPIRV_CROSS_C_API_MSL + if (compiler->backend != SPVC_BACKEND_MSL) + { + compiler->context->report_error("MSL function used on a non-MSL backend."); + return SPVC_ERROR_INVALID_ARGUMENT; + } + + auto &msl = *static_cast(compiler->compiler.get()); + MSLShaderInterfaceVariable output; + output.location = so->location; + output.format = static_cast(so->format); + output.builtin = static_cast(so->builtin); + output.vecsize = so->vecsize; + output.rate = static_cast(so->rate); + msl.add_msl_shader_output(output); + return SPVC_SUCCESS; +#else + (void)so; + compiler->context->report_error("MSL function used on a non-MSL backend."); + return SPVC_ERROR_INVALID_ARGUMENT; +#endif +} + spvc_result spvc_compiler_msl_add_resource_binding(spvc_compiler compiler, const spvc_msl_resource_binding *binding) { @@ -1295,6 +1449,24 @@ spvc_bool spvc_compiler_msl_is_shader_input_used(spvc_compiler compiler, unsigne #endif } +spvc_bool spvc_compiler_msl_is_shader_output_used(spvc_compiler compiler, unsigned location) +{ +#if SPIRV_CROSS_C_API_MSL + if (compiler->backend != SPVC_BACKEND_MSL) + { + compiler->context->report_error("MSL function used on a non-MSL backend."); + return SPVC_FALSE; + } + + auto &msl = *static_cast(compiler->compiler.get()); + return msl.is_msl_shader_output_used(location) ? SPVC_TRUE : SPVC_FALSE; +#else + (void)location; + compiler->context->report_error("MSL function used on a non-MSL backend."); + return SPVC_FALSE; +#endif +} + spvc_bool spvc_compiler_msl_is_vertex_attribute_used(spvc_compiler compiler, unsigned location) { return spvc_compiler_msl_is_shader_input_used(compiler, location); @@ -1639,6 +1811,8 @@ bool spvc_resources_s::copy_resources(const ShaderResources &resources) return false; if (!copy_resources(push_constant_buffers, resources.push_constant_buffers)) return false; + if (!copy_resources(shader_record_buffers, resources.shader_record_buffers)) + return false; if (!copy_resources(separate_images, resources.separate_images)) return false; if (!copy_resources(separate_samplers, resources.separate_samplers)) @@ -1792,6 +1966,10 @@ spvc_result spvc_resources_get_resource_list_for_type(spvc_resources resources, list = &resources->acceleration_structures; break; + case SPVC_RESOURCE_TYPE_SHADER_RECORD_BUFFER: + list = &resources->shader_record_buffers; + break; + default: break; } @@ -2406,6 +2584,51 @@ spvc_type_id spvc_constant_get_type(spvc_constant constant) return constant->constant_type; } +void spvc_constant_set_scalar_fp16(spvc_constant constant, unsigned column, unsigned row, unsigned short value) +{ + constant->m.c[column].r[row].u32 = value; +} + +void spvc_constant_set_scalar_fp32(spvc_constant constant, unsigned column, unsigned row, float value) +{ + constant->m.c[column].r[row].f32 = value; +} + +void spvc_constant_set_scalar_fp64(spvc_constant constant, unsigned column, unsigned row, double value) +{ + constant->m.c[column].r[row].f64 = value; +} + +void spvc_constant_set_scalar_u32(spvc_constant constant, unsigned column, unsigned row, unsigned value) +{ + constant->m.c[column].r[row].u32 = value; +} + +void spvc_constant_set_scalar_i32(spvc_constant constant, unsigned column, unsigned row, int value) +{ + constant->m.c[column].r[row].i32 = value; +} + +void spvc_constant_set_scalar_u16(spvc_constant constant, unsigned column, unsigned row, unsigned short value) +{ + constant->m.c[column].r[row].u32 = uint32_t(value); +} + +void spvc_constant_set_scalar_i16(spvc_constant constant, unsigned column, unsigned row, signed short value) +{ + constant->m.c[column].r[row].u32 = uint32_t(value); +} + +void spvc_constant_set_scalar_u8(spvc_constant constant, unsigned column, unsigned row, unsigned char value) +{ + constant->m.c[column].r[row].u32 = uint32_t(value); +} + +void spvc_constant_set_scalar_i8(spvc_constant constant, unsigned column, unsigned row, signed char value) +{ + constant->m.c[column].r[row].u32 = uint32_t(value); +} + spvc_bool spvc_compiler_get_binary_offset_for_decoration(spvc_compiler compiler, spvc_variable_id id, SpvDecoration decoration, unsigned *word_offset) @@ -2508,7 +2731,7 @@ void spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute *attr) { #if SPIRV_CROSS_C_API_MSL // Crude, but works. - MSLShaderInput attr_default; + MSLShaderInterfaceVariable attr_default; attr->location = attr_default.location; attr->format = static_cast(attr_default.format); attr->builtin = static_cast(attr_default.builtin); @@ -2517,16 +2740,35 @@ void spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute *attr) #endif } +void spvc_msl_shader_interface_var_init(spvc_msl_shader_interface_var *var) +{ +#if SPIRV_CROSS_C_API_MSL + MSLShaderInterfaceVariable var_default; + var->location = var_default.location; + var->format = static_cast(var_default.format); + var->builtin = static_cast(var_default.builtin); + var->vecsize = var_default.vecsize; +#else + memset(var, 0, sizeof(*var)); +#endif +} + void spvc_msl_shader_input_init(spvc_msl_shader_input *input) +{ + spvc_msl_shader_interface_var_init(input); +} + +void spvc_msl_shader_interface_var_init_2(spvc_msl_shader_interface_var_2 *var) { #if SPIRV_CROSS_C_API_MSL - MSLShaderInput input_default; - input->location = input_default.location; - input->format = static_cast(input_default.format); - input->builtin = static_cast(input_default.builtin); - input->vecsize = input_default.vecsize; + MSLShaderInterfaceVariable var_default; + var->location = var_default.location; + var->format = static_cast(var_default.format); + var->builtin = static_cast(var_default.builtin); + var->vecsize = var_default.vecsize; + var->rate = static_cast(var_default.rate); #else - memset(input, 0, sizeof(*input)); + memset(var, 0, sizeof(*var)); #endif } diff --git a/src/libraries/spirv_cross/spirv_cross_c.h b/src/libraries/spirv_cross/spirv_cross_c.h index a590c805a..dd9884f5d 100644 --- a/src/libraries/spirv_cross/spirv_cross_c.h +++ b/src/libraries/spirv_cross/spirv_cross_c.h @@ -40,7 +40,7 @@ extern "C" { /* Bumped if ABI or API breaks backwards compatibility. */ #define SPVC_C_API_VERSION_MAJOR 0 /* Bumped if APIs or enumerations are added in a backwards compatible way. */ -#define SPVC_C_API_VERSION_MINOR 48 +#define SPVC_C_API_VERSION_MINOR 58 /* Bumped if internal implementation details change. */ #define SPVC_C_API_VERSION_PATCH 0 @@ -225,6 +225,7 @@ typedef enum spvc_resource_type SPVC_RESOURCE_TYPE_SEPARATE_SAMPLERS = 11, SPVC_RESOURCE_TYPE_ACCELERATION_STRUCTURE = 12, SPVC_RESOURCE_TYPE_RAY_QUERY = 13, + SPVC_RESOURCE_TYPE_SHADER_RECORD_BUFFER = 14, SPVC_RESOURCE_TYPE_INT_MAX = 0x7fffffff } spvc_resource_type; @@ -290,23 +291,29 @@ typedef enum spvc_msl_index_type } spvc_msl_index_type; /* Maps to C++ API. */ -typedef enum spvc_msl_shader_input_format +typedef enum spvc_msl_shader_variable_format { - SPVC_MSL_SHADER_INPUT_FORMAT_OTHER = 0, - SPVC_MSL_SHADER_INPUT_FORMAT_UINT8 = 1, - SPVC_MSL_SHADER_INPUT_FORMAT_UINT16 = 2, - SPVC_MSL_SHADER_INPUT_FORMAT_ANY16 = 3, - SPVC_MSL_SHADER_INPUT_FORMAT_ANY32 = 4, + SPVC_MSL_SHADER_VARIABLE_FORMAT_OTHER = 0, + SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT8 = 1, + SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT16 = 2, + SPVC_MSL_SHADER_VARIABLE_FORMAT_ANY16 = 3, + SPVC_MSL_SHADER_VARIABLE_FORMAT_ANY32 = 4, /* Deprecated names. */ - SPVC_MSL_VERTEX_FORMAT_OTHER = SPVC_MSL_SHADER_INPUT_FORMAT_OTHER, - SPVC_MSL_VERTEX_FORMAT_UINT8 = SPVC_MSL_SHADER_INPUT_FORMAT_UINT8, - SPVC_MSL_VERTEX_FORMAT_UINT16 = SPVC_MSL_SHADER_INPUT_FORMAT_UINT16, + SPVC_MSL_VERTEX_FORMAT_OTHER = SPVC_MSL_SHADER_VARIABLE_FORMAT_OTHER, + SPVC_MSL_VERTEX_FORMAT_UINT8 = SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT8, + SPVC_MSL_VERTEX_FORMAT_UINT16 = SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT16, + SPVC_MSL_SHADER_INPUT_FORMAT_OTHER = SPVC_MSL_SHADER_VARIABLE_FORMAT_OTHER, + SPVC_MSL_SHADER_INPUT_FORMAT_UINT8 = SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT8, + SPVC_MSL_SHADER_INPUT_FORMAT_UINT16 = SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT16, + SPVC_MSL_SHADER_INPUT_FORMAT_ANY16 = SPVC_MSL_SHADER_VARIABLE_FORMAT_ANY16, + SPVC_MSL_SHADER_INPUT_FORMAT_ANY32 = SPVC_MSL_SHADER_VARIABLE_FORMAT_ANY32, + SPVC_MSL_SHADER_INPUT_FORMAT_INT_MAX = 0x7fffffff -} spvc_msl_shader_input_format, spvc_msl_vertex_format; +} spvc_msl_shader_variable_format, spvc_msl_shader_input_format, spvc_msl_vertex_format; -/* Maps to C++ API. Deprecated; use spvc_msl_shader_input. */ +/* Maps to C++ API. Deprecated; use spvc_msl_shader_interface_var. */ typedef struct spvc_msl_vertex_attribute { unsigned location; @@ -329,20 +336,50 @@ typedef struct spvc_msl_vertex_attribute */ SPVC_PUBLIC_API void spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute *attr); -/* Maps to C++ API. */ -typedef struct spvc_msl_shader_input +/* Maps to C++ API. Deprecated; use spvc_msl_shader_interface_var_2. */ +typedef struct spvc_msl_shader_interface_var { unsigned location; spvc_msl_vertex_format format; SpvBuiltIn builtin; unsigned vecsize; -} spvc_msl_shader_input; +} spvc_msl_shader_interface_var, spvc_msl_shader_input; /* * Initializes the shader input struct. + * Deprecated. Use spvc_msl_shader_interface_var_init_2(). + */ +SPVC_PUBLIC_API void spvc_msl_shader_interface_var_init(spvc_msl_shader_interface_var *var); +/* + * Deprecated. Use spvc_msl_shader_interface_var_init_2(). */ SPVC_PUBLIC_API void spvc_msl_shader_input_init(spvc_msl_shader_input *input); +/* Maps to C++ API. */ +typedef enum spvc_msl_shader_variable_rate +{ + SPVC_MSL_SHADER_VARIABLE_RATE_PER_VERTEX = 0, + SPVC_MSL_SHADER_VARIABLE_RATE_PER_PRIMITIVE = 1, + SPVC_MSL_SHADER_VARIABLE_RATE_PER_PATCH = 2, + + SPVC_MSL_SHADER_VARIABLE_RATE_INT_MAX = 0x7fffffff, +} spvc_msl_shader_variable_rate; + +/* Maps to C++ API. */ +typedef struct spvc_msl_shader_interface_var_2 +{ + unsigned location; + spvc_msl_shader_variable_format format; + SpvBuiltIn builtin; + unsigned vecsize; + spvc_msl_shader_variable_rate rate; +} spvc_msl_shader_interface_var_2; + +/* + * Initializes the shader interface variable struct. + */ +SPVC_PUBLIC_API void spvc_msl_shader_interface_var_init_2(spvc_msl_shader_interface_var_2 *var); + /* Maps to C++ API. */ typedef struct spvc_msl_resource_binding { @@ -677,6 +714,21 @@ typedef enum spvc_compiler_option SPVC_COMPILER_OPTION_GLSL_OVR_MULTIVIEW_VIEW_COUNT = 77 | SPVC_COMPILER_OPTION_GLSL_BIT, + SPVC_COMPILER_OPTION_RELAX_NAN_CHECKS = 78 | SPVC_COMPILER_OPTION_COMMON_BIT, + + SPVC_COMPILER_OPTION_MSL_RAW_BUFFER_TESE_INPUT = 79 | SPVC_COMPILER_OPTION_MSL_BIT, + SPVC_COMPILER_OPTION_MSL_SHADER_PATCH_INPUT_BUFFER_INDEX = 80 | SPVC_COMPILER_OPTION_MSL_BIT, + SPVC_COMPILER_OPTION_MSL_MANUAL_HELPER_INVOCATION_UPDATES = 81 | SPVC_COMPILER_OPTION_MSL_BIT, + SPVC_COMPILER_OPTION_MSL_CHECK_DISCARDED_FRAG_STORES = 82 | SPVC_COMPILER_OPTION_MSL_BIT, + + SPVC_COMPILER_OPTION_GLSL_ENABLE_ROW_MAJOR_LOAD_WORKAROUND = 83 | SPVC_COMPILER_OPTION_GLSL_BIT, + + SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS_TIER = 84 | SPVC_COMPILER_OPTION_MSL_BIT, + SPVC_COMPILER_OPTION_MSL_SAMPLE_DREF_LOD_ARRAY_AS_GRAD = 85 | SPVC_COMPILER_OPTION_MSL_BIT, + SPVC_COMPILER_OPTION_MSL_READWRITE_TEXTURE_FENCES = 86 | SPVC_COMPILER_OPTION_MSL_BIT, + SPVC_COMPILER_OPTION_MSL_REPLACE_RECURSIVE_INPUTS = 87 | SPVC_COMPILER_OPTION_MSL_BIT, + SPVC_COMPILER_OPTION_MSL_AGX_MANUAL_CUBE_GRAD_FIXUP = 88 | SPVC_COMPILER_OPTION_MSL_BIT, + SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff } spvc_compiler_option; @@ -735,6 +787,8 @@ SPVC_PUBLIC_API spvc_result spvc_compiler_compile(spvc_compiler compiler, const /* Maps to C++ API. */ SPVC_PUBLIC_API spvc_result spvc_compiler_add_header_line(spvc_compiler compiler, const char *line); SPVC_PUBLIC_API spvc_result spvc_compiler_require_extension(spvc_compiler compiler, const char *ext); +SPVC_PUBLIC_API size_t spvc_compiler_get_num_required_extensions(spvc_compiler compiler); +SPVC_PUBLIC_API const char *spvc_compiler_get_required_extension(spvc_compiler compiler, size_t index); SPVC_PUBLIC_API spvc_result spvc_compiler_flatten_buffer_block(spvc_compiler compiler, spvc_variable_id id); SPVC_PUBLIC_API spvc_bool spvc_compiler_variable_is_depth_or_compare(spvc_compiler compiler, spvc_variable_id id); @@ -783,14 +837,23 @@ SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_vertex_attribute(spvc_compiler const spvc_msl_vertex_attribute *attrs); SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_resource_binding(spvc_compiler compiler, const spvc_msl_resource_binding *binding); +/* Deprecated; use spvc_compiler_msl_add_shader_input_2(). */ SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler, - const spvc_msl_shader_input *input); + const spvc_msl_shader_interface_var *input); +SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_input_2(spvc_compiler compiler, + const spvc_msl_shader_interface_var_2 *input); +/* Deprecated; use spvc_compiler_msl_add_shader_output_2(). */ +SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_output(spvc_compiler compiler, + const spvc_msl_shader_interface_var *output); +SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_output_2(spvc_compiler compiler, + const spvc_msl_shader_interface_var_2 *output); SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_discrete_descriptor_set(spvc_compiler compiler, unsigned desc_set); SPVC_PUBLIC_API spvc_result spvc_compiler_msl_set_argument_buffer_device_address_space(spvc_compiler compiler, unsigned desc_set, spvc_bool device_address); /* Obsolete, use is_shader_input_used. */ SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_vertex_attribute_used(spvc_compiler compiler, unsigned location); SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_shader_input_used(spvc_compiler compiler, unsigned location); +SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_shader_output_used(spvc_compiler compiler, unsigned location); SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_resource_used(spvc_compiler compiler, SpvExecutionModel model, @@ -991,6 +1054,19 @@ SPVC_PUBLIC_API int spvc_constant_get_scalar_i8(spvc_constant constant, unsigned SPVC_PUBLIC_API void spvc_constant_get_subconstants(spvc_constant constant, const spvc_constant_id **constituents, size_t *count); SPVC_PUBLIC_API spvc_type_id spvc_constant_get_type(spvc_constant constant); +/* + * C implementation of the C++ api. + */ +SPVC_PUBLIC_API void spvc_constant_set_scalar_fp16(spvc_constant constant, unsigned column, unsigned row, unsigned short value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_fp32(spvc_constant constant, unsigned column, unsigned row, float value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_fp64(spvc_constant constant, unsigned column, unsigned row, double value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_u32(spvc_constant constant, unsigned column, unsigned row, unsigned value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_i32(spvc_constant constant, unsigned column, unsigned row, int value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_u16(spvc_constant constant, unsigned column, unsigned row, unsigned short value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_i16(spvc_constant constant, unsigned column, unsigned row, signed short value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_u8(spvc_constant constant, unsigned column, unsigned row, unsigned char value); +SPVC_PUBLIC_API void spvc_constant_set_scalar_i8(spvc_constant constant, unsigned column, unsigned row, signed char value); + /* * Misc reflection * Maps to C++ API. diff --git a/src/libraries/spirv_cross/spirv_cross_containers.hpp b/src/libraries/spirv_cross/spirv_cross_containers.hpp index 506b069c7..e79b32093 100644 --- a/src/libraries/spirv_cross/spirv_cross_containers.hpp +++ b/src/libraries/spirv_cross/spirv_cross_containers.hpp @@ -26,6 +26,7 @@ #include "spirv_cross_error_handling.hpp" #include +#include #include #include #include @@ -210,7 +211,8 @@ class SmallVector : public VectorView buffer_capacity = N; } - SmallVector(const T *arg_list_begin, const T *arg_list_end) SPIRV_CROSS_NOEXCEPT : SmallVector() + template + SmallVector(const U *arg_list_begin, const U *arg_list_end) SPIRV_CROSS_NOEXCEPT : SmallVector() { auto count = size_t(arg_list_end - arg_list_begin); reserve(count); @@ -219,7 +221,13 @@ class SmallVector : public VectorView this->buffer_size = count; } - SmallVector(std::initializer_list init) SPIRV_CROSS_NOEXCEPT : SmallVector(init.begin(), init.end()) + template + SmallVector(std::initializer_list init) SPIRV_CROSS_NOEXCEPT : SmallVector(init.begin(), init.end()) + { + } + + template + explicit SmallVector(const U (&init)[M]) SPIRV_CROSS_NOEXCEPT : SmallVector(init, init + M) { } diff --git a/src/libraries/spirv_cross/spirv_cross_parsed_ir.cpp b/src/libraries/spirv_cross/spirv_cross_parsed_ir.cpp index e7fcdff04..c6ddb6a45 100644 --- a/src/libraries/spirv_cross/spirv_cross_parsed_ir.cpp +++ b/src/libraries/spirv_cross/spirv_cross_parsed_ir.cpp @@ -54,26 +54,26 @@ ParsedIR::ParsedIR() // Should have been default-implemented, but need this on MSVC 2013. ParsedIR::ParsedIR(ParsedIR &&other) SPIRV_CROSS_NOEXCEPT { - *this = move(other); + *this = std::move(other); } ParsedIR &ParsedIR::operator=(ParsedIR &&other) SPIRV_CROSS_NOEXCEPT { if (this != &other) { - pool_group = move(other.pool_group); - spirv = move(other.spirv); - meta = move(other.meta); + pool_group = std::move(other.pool_group); + spirv = std::move(other.spirv); + meta = std::move(other.meta); for (int i = 0; i < TypeCount; i++) - ids_for_type[i] = move(other.ids_for_type[i]); - ids_for_constant_or_type = move(other.ids_for_constant_or_type); - ids_for_constant_or_variable = move(other.ids_for_constant_or_variable); - declared_capabilities = move(other.declared_capabilities); - declared_extensions = move(other.declared_extensions); - block_meta = move(other.block_meta); - continue_block_to_loop_header = move(other.continue_block_to_loop_header); - entry_points = move(other.entry_points); - ids = move(other.ids); + ids_for_type[i] = std::move(other.ids_for_type[i]); + ids_for_constant_undef_or_type = std::move(other.ids_for_constant_undef_or_type); + ids_for_constant_or_variable = std::move(other.ids_for_constant_or_variable); + declared_capabilities = std::move(other.declared_capabilities); + declared_extensions = std::move(other.declared_extensions); + block_meta = std::move(other.block_meta); + continue_block_to_loop_header = std::move(other.continue_block_to_loop_header); + entry_points = std::move(other.entry_points); + ids = std::move(other.ids); addressing_model = other.addressing_model; memory_model = other.memory_model; @@ -102,7 +102,7 @@ ParsedIR &ParsedIR::operator=(const ParsedIR &other) meta = other.meta; for (int i = 0; i < TypeCount; i++) ids_for_type[i] = other.ids_for_type[i]; - ids_for_constant_or_type = other.ids_for_constant_or_type; + ids_for_constant_undef_or_type = other.ids_for_constant_undef_or_type; ids_for_constant_or_variable = other.ids_for_constant_or_variable; declared_capabilities = other.declared_capabilities; declared_extensions = other.declared_extensions; @@ -330,6 +330,10 @@ void ParsedIR::fixup_reserved_names() { for (uint32_t id : meta_needing_name_fixup) { + // Don't rename remapped variables like 'gl_LastFragDepthARM'. + if (ids[id].get_type() == TypeVariable && get(id).remapped_variable) + continue; + auto &m = meta[id]; sanitize_identifier(m.decoration.alias, false, false); for (auto &memb : m.members) @@ -349,7 +353,7 @@ void ParsedIR::set_name(ID id, const string &name) void ParsedIR::set_member_name(TypeID id, uint32_t index, const string &name) { auto &m = meta[id]; - m.members.resize(max(meta[id].members.size(), size_t(index) + 1)); + m.members.resize(max(m.members.size(), size_t(index) + 1)); m.members[index].alias = name; if (!is_valid_identifier(name) || is_reserved_identifier(name, true, false)) meta_needing_name_fixup.insert(id); @@ -366,6 +370,10 @@ void ParsedIR::set_decoration_string(ID id, Decoration decoration, const string dec.hlsl_semantic = argument; break; + case DecorationUserTypeGOOGLE: + dec.user_type = argument; + break; + default: break; } @@ -451,8 +459,9 @@ void ParsedIR::set_decoration(ID id, Decoration decoration, uint32_t argument) void ParsedIR::set_member_decoration(TypeID id, uint32_t index, Decoration decoration, uint32_t argument) { - meta[id].members.resize(max(meta[id].members.size(), size_t(index) + 1)); - auto &dec = meta[id].members[index]; + auto &m = meta[id]; + m.members.resize(max(m.members.size(), size_t(index) + 1)); + auto &dec = m.members[index]; dec.decoration_flags.set(decoration); switch (decoration) @@ -654,6 +663,9 @@ const string &ParsedIR::get_decoration_string(ID id, Decoration decoration) cons case DecorationHlslSemanticGOOGLE: return dec.hlsl_semantic; + case DecorationUserTypeGOOGLE: + return dec.user_type; + default: return empty_string; } @@ -792,7 +804,8 @@ const Bitset &ParsedIR::get_decoration_bitset(ID id) const void ParsedIR::set_member_decoration_string(TypeID id, uint32_t index, Decoration decoration, const string &argument) { - meta[id].members.resize(max(meta[id].members.size(), size_t(index) + 1)); + auto &m = meta[id]; + m.members.resize(max(m.members.size(), size_t(index) + 1)); auto &dec = meta[id].members[index]; dec.decoration_flags.set(decoration); @@ -928,7 +941,7 @@ void ParsedIR::add_typed_id(Types type, ID id) { case TypeConstant: ids_for_constant_or_variable.push_back(id); - ids_for_constant_or_type.push_back(id); + ids_for_constant_undef_or_type.push_back(id); break; case TypeVariable: @@ -937,7 +950,8 @@ void ParsedIR::add_typed_id(Types type, ID id) case TypeType: case TypeConstantOp: - ids_for_constant_or_type.push_back(id); + case TypeUndef: + ids_for_constant_undef_or_type.push_back(id); break; default: @@ -999,7 +1013,7 @@ ParsedIR::LoopLock::LoopLock(uint32_t *lock_) ParsedIR::LoopLock::LoopLock(LoopLock &&other) SPIRV_CROSS_NOEXCEPT { - *this = move(other); + *this = std::move(other); } ParsedIR::LoopLock &ParsedIR::LoopLock::operator=(LoopLock &&other) SPIRV_CROSS_NOEXCEPT diff --git a/src/libraries/spirv_cross/spirv_cross_parsed_ir.hpp b/src/libraries/spirv_cross/spirv_cross_parsed_ir.hpp index 138d9dd43..7f35c3815 100644 --- a/src/libraries/spirv_cross/spirv_cross_parsed_ir.hpp +++ b/src/libraries/spirv_cross/spirv_cross_parsed_ir.hpp @@ -74,8 +74,8 @@ class ParsedIR // Special purpose lists which contain a union of types. // This is needed so we can declare specialization constants and structs in an interleaved fashion, // among other things. - // Constants can be of struct type, and struct array sizes can use specialization constants. - SmallVector ids_for_constant_or_type; + // Constants can be undef or of struct type, and struct array sizes can use specialization constants. + SmallVector ids_for_constant_undef_or_type; SmallVector ids_for_constant_or_variable; // We need to keep track of the width the Ops that contains a type for the diff --git a/src/libraries/spirv_cross/spirv_glsl.cpp b/src/libraries/spirv_cross/spirv_glsl.cpp index cdc1c6b6e..f200b424d 100644 --- a/src/libraries/spirv_cross/spirv_glsl.cpp +++ b/src/libraries/spirv_cross/spirv_glsl.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #ifndef _WIN32 #include @@ -222,7 +223,7 @@ static const char *to_pls_layout(PlsFormat format) } } -static SPIRType::BaseType pls_format_to_basetype(PlsFormat format) +static std::pair pls_format_to_basetype(PlsFormat format) { switch (format) { @@ -233,17 +234,17 @@ static SPIRType::BaseType pls_format_to_basetype(PlsFormat format) case PlsRGB10A2: case PlsRGBA8: case PlsRG16: - return SPIRType::Float; + return std::make_pair(spv::OpTypeFloat, SPIRType::Float); case PlsRGBA8I: case PlsRG16I: - return SPIRType::Int; + return std::make_pair(spv::OpTypeInt, SPIRType::Int); case PlsRGB10A2UI: case PlsRGBA8UI: case PlsRG16UI: case PlsR32UI: - return SPIRType::UInt; + return std::make_pair(spv::OpTypeInt, SPIRType::UInt); } } @@ -296,8 +297,19 @@ const char *CompilerGLSL::vector_swizzle(int vecsize, int index) return swizzle[vecsize - 1][index]; } -void CompilerGLSL::reset() +void CompilerGLSL::reset(uint32_t iteration_count) { + // Sanity check the iteration count to be robust against a certain class of bugs where + // we keep forcing recompilations without making clear forward progress. + // In buggy situations we will loop forever, or loop for an unbounded number of iterations. + // Certain types of recompilations are considered to make forward progress, + // but in almost all situations, we'll never see more than 3 iterations. + // It is highly context-sensitive when we need to force recompilation, + // and it is not practical with the current architecture + // to resolve everything up front. + if (iteration_count >= options.force_recompile_max_debug_iterations && !is_force_recompile_forward_progress) + SPIRV_CROSS_THROW("Maximum compilation loops detected and no forward progress was made. Must be a SPIRV-Cross bug!"); + // We do some speculative optimizations which should pretty much always work out, // but just in case the SPIR-V is rather weird, recompile until it's happy. // This typically only means one extra pass. @@ -305,6 +317,7 @@ void CompilerGLSL::reset() // Clear invalid expression tracking. invalid_expressions.clear(); + composite_insert_overwritten.clear(); current_function = nullptr; // Clear temporary usage tracking. @@ -315,6 +328,8 @@ void CompilerGLSL::reset() // Ensure that we declare phi-variable copies even if the original declaration isn't deferred flushed_phi_variables.clear(); + current_emitting_switch_stack.clear(); + reset_name_caches(); ir.for_each_typed_id([&](uint32_t, SPIRFunction &func) { @@ -393,10 +408,9 @@ void CompilerGLSL::find_static_extensions() } else if (type.basetype == SPIRType::Int64 || type.basetype == SPIRType::UInt64) { - if (options.es) - SPIRV_CROSS_THROW("64-bit integers not supported in ES profile."); - if (!options.es) - require_extension_internal("GL_ARB_gpu_shader_int64"); + if (options.es && options.version < 310) // GL_NV_gpu_shader5 fallback requires 310. + SPIRV_CROSS_THROW("64-bit integers not supported in ES profile before version 310."); + require_extension_internal("GL_ARB_gpu_shader_int64"); } else if (type.basetype == SPIRType::Half) { @@ -484,6 +498,15 @@ void CompilerGLSL::find_static_extensions() require_extension_internal("GL_NV_ray_tracing"); break; + case ExecutionModelMeshEXT: + case ExecutionModelTaskEXT: + if (options.es || options.version < 450) + SPIRV_CROSS_THROW("Mesh shaders require GLSL 450 or above."); + if (!options.vulkan_semantics) + SPIRV_CROSS_THROW("Mesh shaders require Vulkan semantics."); + require_extension_internal("GL_EXT_mesh_shader"); + break; + default: break; } @@ -530,7 +553,7 @@ void CompilerGLSL::find_static_extensions() SPIRV_CROSS_THROW("GL_EXT_buffer_reference requires ESSL 320."); else if (!options.es && options.version < 450) SPIRV_CROSS_THROW("GL_EXT_buffer_reference requires GLSL 450."); - require_extension_internal("GL_EXT_buffer_reference"); + require_extension_internal("GL_EXT_buffer_reference2"); } else if (ir.addressing_model != AddressingModelLogical) { @@ -607,6 +630,22 @@ void CompilerGLSL::find_static_extensions() SPIRV_CROSS_THROW("OVR_multiview2 can only be used with Vertex shaders."); require_extension_internal("GL_OVR_multiview2"); } + + // KHR one is likely to get promoted at some point, so if we don't see an explicit SPIR-V extension, assume KHR. + for (auto &ext : ir.declared_extensions) + if (ext == "SPV_NV_fragment_shader_barycentric") + barycentric_is_nv = true; +} + +void CompilerGLSL::require_polyfill(Polyfill polyfill, bool relaxed) +{ + uint32_t &polyfills = (relaxed && options.es) ? required_polyfills_relaxed : required_polyfills; + + if ((polyfills & polyfill) == 0) + { + polyfills |= polyfill; + force_recompile(); + } } void CompilerGLSL::ray_tracing_khr_fixup_locations() @@ -631,19 +670,22 @@ string CompilerGLSL::compile() { // only NV_gpu_shader5 supports divergent indexing on OpenGL, and it does so without extra qualifiers backend.nonuniform_qualifier = ""; - backend.needs_row_major_load_workaround = true; + backend.needs_row_major_load_workaround = options.enable_row_major_load_workaround; } backend.allow_precision_qualifiers = options.vulkan_semantics || options.es; backend.force_gl_in_out_block = true; backend.supports_extensions = true; backend.use_array_constructor = true; - - backend.support_precise_qualifier = (!options.es && options.version >= 400) || (options.es && options.version >= 320); + backend.workgroup_size_is_hidden = true; + backend.requires_relaxed_precision_analysis = options.es || options.vulkan_semantics; + backend.support_precise_qualifier = + (!options.es && options.version >= 400) || (options.es && options.version >= 320); if (is_legacy_es()) backend.support_case_fallthrough = false; // Scan the SPIR-V to find trivial uses of extensions. + fixup_anonymous_struct_names(); fixup_type_alias(); reorder_type_alias(); build_function_control_flow_graphs_and_analyze(); @@ -663,10 +705,7 @@ string CompilerGLSL::compile() uint32_t pass_count = 0; do { - if (pass_count >= 3) - SPIRV_CROSS_THROW("Over 3 compilation loops detected. Must be a bug!"); - - reset(); + reset(pass_count); buffer.reset(); @@ -674,6 +713,11 @@ string CompilerGLSL::compile() emit_resources(); emit_extension_workarounds(get_execution_model()); + if (required_polyfills != 0) + emit_polyfills(required_polyfills, false); + if (options.es && required_polyfills_relaxed != 0) + emit_polyfills(required_polyfills_relaxed, true); + emit_function(get(ir.default_entry_point), Bitset()); pass_count++; @@ -707,6 +751,8 @@ void CompilerGLSL::build_workgroup_size(SmallVector &arguments, const Sp const SpecializationConstant &wg_y, const SpecializationConstant &wg_z) { auto &execution = get_entry_point(); + bool builtin_workgroup = execution.workgroup_size.constant != 0; + bool use_local_size_id = !builtin_workgroup && execution.flags.get(ExecutionModeLocalSizeId); if (wg_x.id) { @@ -715,6 +761,8 @@ void CompilerGLSL::build_workgroup_size(SmallVector &arguments, const Sp else arguments.push_back(join("local_size_x = ", get(wg_x.id).specialization_constant_macro_name)); } + else if (use_local_size_id && execution.workgroup_size.id_x) + arguments.push_back(join("local_size_x = ", get(execution.workgroup_size.id_x).scalar())); else arguments.push_back(join("local_size_x = ", execution.workgroup_size.x)); @@ -725,6 +773,8 @@ void CompilerGLSL::build_workgroup_size(SmallVector &arguments, const Sp else arguments.push_back(join("local_size_y = ", get(wg_y.id).specialization_constant_macro_name)); } + else if (use_local_size_id && execution.workgroup_size.id_y) + arguments.push_back(join("local_size_y = ", get(execution.workgroup_size.id_y).scalar())); else arguments.push_back(join("local_size_y = ", execution.workgroup_size.y)); @@ -735,6 +785,8 @@ void CompilerGLSL::build_workgroup_size(SmallVector &arguments, const Sp else arguments.push_back(join("local_size_z = ", get(wg_z.id).specialization_constant_macro_name)); } + else if (use_local_size_id && execution.workgroup_size.id_z) + arguments.push_back(join("local_size_z = ", get(execution.workgroup_size.id_z).scalar())); else arguments.push_back(join("local_size_z = ", execution.workgroup_size.z)); } @@ -801,7 +853,20 @@ void CompilerGLSL::emit_header() for (auto &ext : forced_extensions) { - if (ext == "GL_EXT_shader_explicit_arithmetic_types_float16") + if (ext == "GL_ARB_gpu_shader_int64") + { + statement("#if defined(GL_ARB_gpu_shader_int64)"); + statement("#extension GL_ARB_gpu_shader_int64 : require"); + if (!options.vulkan_semantics || options.es) + { + statement("#elif defined(GL_NV_gpu_shader5)"); + statement("#extension GL_NV_gpu_shader5 : require"); + } + statement("#else"); + statement("#error No extension available for 64-bit integers."); + statement("#endif"); + } + else if (ext == "GL_EXT_shader_explicit_arithmetic_types_float16") { // Special case, this extension has a potential fallback to another vendor extension in normal GLSL. // GL_AMD_gpu_shader_half_float is a superset, so try that first. @@ -821,13 +886,30 @@ void CompilerGLSL::emit_header() statement("#error No extension available for FP16."); statement("#endif"); } + else if (ext == "GL_EXT_shader_explicit_arithmetic_types_int8") + { + if (options.vulkan_semantics) + statement("#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require"); + else + { + statement("#if defined(GL_EXT_shader_explicit_arithmetic_types_int8)"); + statement("#extension GL_EXT_shader_explicit_arithmetic_types_int8 : require"); + statement("#elif defined(GL_NV_gpu_shader5)"); + statement("#extension GL_NV_gpu_shader5 : require"); + statement("#else"); + statement("#error No extension available for Int8."); + statement("#endif"); + } + } else if (ext == "GL_EXT_shader_explicit_arithmetic_types_int16") { if (options.vulkan_semantics) statement("#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require"); else { - statement("#if defined(GL_AMD_gpu_shader_int16)"); + statement("#if defined(GL_EXT_shader_explicit_arithmetic_types_int16)"); + statement("#extension GL_EXT_shader_explicit_arithmetic_types_int16 : require"); + statement("#elif defined(GL_AMD_gpu_shader_int16)"); statement("#extension GL_AMD_gpu_shader_int16 : require"); statement("#elif defined(GL_NV_gpu_shader5)"); statement("#extension GL_NV_gpu_shader5 : require"); @@ -1004,8 +1086,10 @@ void CompilerGLSL::emit_header() break; case ExecutionModelGLCompute: + case ExecutionModelTaskEXT: + case ExecutionModelMeshEXT: { - if (execution.workgroup_size.constant != 0) + if (execution.workgroup_size.constant != 0 || execution.flags.get(ExecutionModeLocalSizeId)) { SpecializationConstant wg_x, wg_y, wg_z; get_work_group_size_specialization_constants(wg_x, wg_y, wg_z); @@ -1022,6 +1106,18 @@ void CompilerGLSL::emit_header() inputs.push_back(join("local_size_y = ", execution.workgroup_size.y)); inputs.push_back(join("local_size_z = ", execution.workgroup_size.z)); } + + if (execution.model == ExecutionModelMeshEXT) + { + outputs.push_back(join("max_vertices = ", execution.output_vertices)); + outputs.push_back(join("max_primitives = ", execution.output_primitives)); + if (execution.flags.get(ExecutionModeOutputTrianglesEXT)) + outputs.push_back("triangles"); + else if (execution.flags.get(ExecutionModeOutputLinesEXT)) + outputs.push_back("lines"); + else if (execution.flags.get(ExecutionModeOutputPoints)) + outputs.push_back("points"); + } break; } @@ -1170,15 +1266,39 @@ string CompilerGLSL::to_interpolation_qualifiers(const Bitset &flags) if (flags.get(DecorationFlat)) res += "flat "; if (flags.get(DecorationNoPerspective)) + { + if (options.es) + { + if (options.version < 300) + SPIRV_CROSS_THROW("noperspective requires ESSL 300."); + require_extension_internal("GL_NV_shader_noperspective_interpolation"); + } + else if (is_legacy_desktop()) + require_extension_internal("GL_EXT_gpu_shader4"); res += "noperspective "; + } if (flags.get(DecorationCentroid)) res += "centroid "; if (flags.get(DecorationPatch)) res += "patch "; if (flags.get(DecorationSample)) + { + if (options.es) + { + if (options.version < 300) + SPIRV_CROSS_THROW("sample requires ESSL 300."); + else if (options.version < 320) + require_extension_internal("GL_OES_shader_multisample_interpolation"); + } res += "sample "; - if (flags.get(DecorationInvariant)) + } + if (flags.get(DecorationInvariant) && (options.es || options.version >= 120)) res += "invariant "; + if (flags.get(DecorationPerPrimitiveEXT)) + { + res += "perprimitiveEXT "; + require_extension_internal("GL_EXT_mesh_shader"); + } if (flags.get(DecorationExplicitInterpAMD)) { @@ -1186,14 +1306,23 @@ string CompilerGLSL::to_interpolation_qualifiers(const Bitset &flags) res += "__explicitInterpAMD "; } - if (flags.get(DecorationPerVertexNV)) + if (flags.get(DecorationPerVertexKHR)) { if (options.es && options.version < 320) - SPIRV_CROSS_THROW("pervertexNV requires ESSL 320."); + SPIRV_CROSS_THROW("pervertexEXT requires ESSL 320."); else if (!options.es && options.version < 450) - SPIRV_CROSS_THROW("pervertexNV requires GLSL 450."); - require_extension_internal("GL_NV_fragment_shader_barycentric"); - res += "pervertexNV "; + SPIRV_CROSS_THROW("pervertexEXT requires GLSL 450."); + + if (barycentric_is_nv) + { + require_extension_internal("GL_NV_fragment_shader_barycentric"); + res += "pervertexNV "; + } + else + { + require_extension_internal("GL_EXT_fragment_shader_barycentric"); + res += "pervertexEXT "; + } } return res; @@ -1360,6 +1489,10 @@ const char *CompilerGLSL::format_to_glsl(spv::ImageFormat format) return "rg8i"; case ImageFormatR16i: return "r16i"; + case ImageFormatR64i: + return "r64i"; + case ImageFormatR64ui: + return "r64ui"; default: case ImageFormatUnknown: return nullptr; @@ -1396,7 +1529,7 @@ uint32_t CompilerGLSL::type_to_packed_alignment(const SPIRType &type, const Bits { // If using PhysicalStorageBufferEXT storage class, this is a pointer, // and is 64-bit. - if (type.storage == StorageClassPhysicalStorageBufferEXT) + if (is_physical_pointer(type)) { if (!type.pointer) SPIRV_CROSS_THROW("Types in PhysicalStorageBufferEXT must be pointers."); @@ -1411,8 +1544,7 @@ uint32_t CompilerGLSL::type_to_packed_alignment(const SPIRType &type, const Bits else SPIRV_CROSS_THROW("AddressingModelPhysicalStorageBuffer64EXT must be used for PhysicalStorageBufferEXT."); } - - if (!type.array.empty()) + else if (is_array(type)) { uint32_t minimum_alignment = 1; if (packing_is_vec4_padded(packing)) @@ -1439,7 +1571,7 @@ uint32_t CompilerGLSL::type_to_packed_alignment(const SPIRType &type, const Bits // In std140, struct alignment is rounded up to 16. if (packing_is_vec4_padded(packing)) - alignment = max(alignment, 16u); + alignment = max(alignment, 16u); return alignment; } @@ -1518,21 +1650,9 @@ uint32_t CompilerGLSL::type_to_packed_array_stride(const SPIRType &type, const B uint32_t CompilerGLSL::type_to_packed_size(const SPIRType &type, const Bitset &flags, BufferPackingStandard packing) { - if (!type.array.empty()) - { - uint32_t packed_size = to_array_size_literal(type) * type_to_packed_array_stride(type, flags, packing); - - // For arrays of vectors and matrices in HLSL, the last element has a size which depends on its vector size, - // so that it is possible to pack other vectors into the last element. - if (packing_is_hlsl(packing) && type.basetype != SPIRType::Struct) - packed_size -= (4 - type.vecsize) * (type.width / 8); - - return packed_size; - } - // If using PhysicalStorageBufferEXT storage class, this is a pointer, // and is 64-bit. - if (type.storage == StorageClassPhysicalStorageBufferEXT) + if (is_physical_pointer(type)) { if (!type.pointer) SPIRV_CROSS_THROW("Types in PhysicalStorageBufferEXT must be pointers."); @@ -1542,6 +1662,17 @@ uint32_t CompilerGLSL::type_to_packed_size(const SPIRType &type, const Bitset &f else SPIRV_CROSS_THROW("AddressingModelPhysicalStorageBuffer64EXT must be used for PhysicalStorageBufferEXT."); } + else if (is_array(type)) + { + uint32_t packed_size = to_array_size_literal(type) * type_to_packed_array_stride(type, flags, packing); + + // For arrays of vectors and matrices in HLSL, the last element has a size which depends on its vector size, + // so that it is possible to pack other vectors into the last element. + if (packing_is_hlsl(packing) && type.basetype != SPIRType::Struct) + packed_size -= (4 - type.vecsize) * (type.width / 8); + + return packed_size; + } uint32_t size = 0; @@ -1661,16 +1792,29 @@ bool CompilerGLSL::buffer_is_packing_standard(const SPIRType &type, BufferPackin packed_size = type_to_packed_size(memb_type, member_flags, packing); // We only need to care about this if we have non-array types which can straddle the vec4 boundary. + uint32_t actual_offset = type_struct_member_offset(type, i); + if (packing_is_hlsl(packing)) { // If a member straddles across a vec4 boundary, alignment is actually vec4. - uint32_t begin_word = offset / 16; - uint32_t end_word = (offset + packed_size - 1) / 16; + uint32_t target_offset; + + // If we intend to use explicit packing, we must check for improper straddle with that offset. + // In implicit packing, we must check with implicit offset, since the explicit offset + // might have already accounted for the straddle, and we'd miss the alignment promotion to vec4. + // This is important when packing sub-structs that don't support packoffset(). + if (packing_has_flexible_offset(packing)) + target_offset = actual_offset; + else + target_offset = offset; + + uint32_t begin_word = target_offset / 16; + uint32_t end_word = (target_offset + packed_size - 1) / 16; + if (begin_word != end_word) - packed_alignment = max(packed_alignment, 16u); + packed_alignment = max(packed_alignment, 16u); } - uint32_t actual_offset = type_struct_member_offset(type, i); // Field is not in the specified range anymore and we can ignore any further fields. if (actual_offset >= end_offset) break; @@ -1708,8 +1852,9 @@ bool CompilerGLSL::buffer_is_packing_standard(const SPIRType &type, BufferPackin } // Verify array stride rules. - if (!memb_type.array.empty() && type_to_packed_array_stride(memb_type, member_flags, packing) != - type_struct_member_array_stride(type, i)) + if (is_array(memb_type) && + type_to_packed_array_stride(memb_type, member_flags, packing) != + type_struct_member_array_stride(type, i)) { if (failed_validation_index) *failed_validation_index = i; @@ -2112,9 +2257,8 @@ void CompilerGLSL::emit_push_constant_block_glsl(const SPIRVariable &var) // OpenGL has no concept of push constant blocks, implement it as a uniform struct. auto &type = get(var.basetype); - auto &flags = ir.meta[var.self].decoration.decoration_flags; - flags.clear(DecorationBinding); - flags.clear(DecorationDescriptorSet); + unset_decoration(var.self, DecorationBinding); + unset_decoration(var.self, DecorationDescriptorSet); #if 0 if (flags & ((1ull << DecorationBinding) | (1ull << DecorationDescriptorSet))) @@ -2124,14 +2268,13 @@ void CompilerGLSL::emit_push_constant_block_glsl(const SPIRVariable &var) // We're emitting the push constant block as a regular struct, so disable the block qualifier temporarily. // Otherwise, we will end up emitting layout() qualifiers on naked structs which is not allowed. - auto &block_flags = ir.meta[type.self].decoration.decoration_flags; - bool block_flag = block_flags.get(DecorationBlock); - block_flags.clear(DecorationBlock); + bool block_flag = has_decoration(type.self, DecorationBlock); + unset_decoration(type.self, DecorationBlock); emit_struct(type); if (block_flag) - block_flags.set(DecorationBlock); + set_decoration(type.self, DecorationBlock); emit_uniform(var); statement(""); @@ -2334,6 +2477,10 @@ void CompilerGLSL::emit_buffer_block_native(const SPIRVariable &var) i++; } + // Don't declare empty blocks in GLSL, this is not allowed. + if (type_is_empty(type) && !backend.supports_empty_struct) + statement("int empty_struct_member;"); + // var.self can be used as a backup name for the block name, // so we need to make sure we don't disturb the name here on a recompile. // It will need to be reset if we have to recompile. @@ -2354,7 +2501,7 @@ void CompilerGLSL::emit_buffer_block_flattened(const SPIRVariable &var) SPIRType::BaseType basic_type; if (get_common_basic_type(type, basic_type)) { - SPIRType tmp; + SPIRType tmp { OpTypeVector }; tmp.basetype = basic_type; tmp.vecsize = 4; if (basic_type != SPIRType::Float && basic_type != SPIRType::Int && basic_type != SPIRType::UInt) @@ -2561,7 +2708,7 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var) } // Workaround to make sure we can emit "patch in/out" correctly. - fixup_io_block_patch_qualifiers(var); + fixup_io_block_patch_primitive_qualifiers(var); // Block names should never alias. auto block_name = to_name(type.self, false); @@ -2584,8 +2731,15 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var) // Instance names cannot alias block names. resource_names.insert(block_name); - bool is_patch = has_decoration(var.self, DecorationPatch); - statement(layout_for_variable(var), (is_patch ? "patch " : ""), qual, block_name); + const char *block_qualifier; + if (has_decoration(var.self, DecorationPatch)) + block_qualifier = "patch "; + else if (has_decoration(var.self, DecorationPerPrimitiveEXT)) + block_qualifier = "perprimitiveEXT "; + else + block_qualifier = ""; + + statement(layout_for_variable(var), block_qualifier, qual, block_name); begin_scope(); type.member_name_cache.clear(); @@ -2618,30 +2772,26 @@ void CompilerGLSL::emit_interface_block(const SPIRVariable &var) { add_resource_name(var.self); - // Tessellation control and evaluation shaders must have either gl_MaxPatchVertices or unsized arrays for input arrays. - // Opt for unsized as it's the more "correct" variant to use. - bool control_point_input_array = type.storage == StorageClassInput && !type.array.empty() && - !has_decoration(var.self, DecorationPatch) && - (get_entry_point().model == ExecutionModelTessellationControl || - get_entry_point().model == ExecutionModelTessellationEvaluation); - - uint32_t old_array_size = 0; - bool old_array_size_literal = true; + // Legacy GLSL did not support int attributes, we automatically + // declare them as float and cast them on load/store + SPIRType newtype = type; + if (is_legacy() && var.storage == StorageClassInput && type.basetype == SPIRType::Int) + newtype.basetype = SPIRType::Float; - if (control_point_input_array) + // Tessellation control and evaluation shaders must have either + // gl_MaxPatchVertices or unsized arrays for input arrays. + // Opt for unsized as it's the more "correct" variant to use. + if (type.storage == StorageClassInput && !type.array.empty() && + !has_decoration(var.self, DecorationPatch) && + (get_entry_point().model == ExecutionModelTessellationControl || + get_entry_point().model == ExecutionModelTessellationEvaluation)) { - swap(type.array.back(), old_array_size); - swap(type.array_size_literal.back(), old_array_size_literal); + newtype.array.back() = 0; + newtype.array_size_literal.back() = true; } statement(layout_for_variable(var), to_qualifiers_glsl(var.self), - variable_decl(type, to_name(var.self), var.self), ";"); - - if (control_point_input_array) - { - swap(type.array.back(), old_array_size); - swap(type.array_size_literal.back(), old_array_size_literal); - } + variable_decl(newtype, to_name(var.self), var.self), ";"); } } } @@ -2669,14 +2819,41 @@ string CompilerGLSL::constant_value_macro_name(uint32_t id) void CompilerGLSL::emit_specialization_constant_op(const SPIRConstantOp &constant) { auto &type = get(constant.basetype); + // This will break. It is bogus and should not be legal. + if (type_is_top_level_block(type)) + return; + add_resource_name(constant.self); auto name = to_name(constant.self); statement("const ", variable_decl(type, name), " = ", constant_op_expression(constant), ";"); } +int CompilerGLSL::get_constant_mapping_to_workgroup_component(const SPIRConstant &c) const +{ + auto &entry_point = get_entry_point(); + int index = -1; + + // Need to redirect specialization constants which are used as WorkGroupSize to the builtin, + // since the spec constant declarations are never explicitly declared. + if (entry_point.workgroup_size.constant == 0 && entry_point.flags.get(ExecutionModeLocalSizeId)) + { + if (c.self == entry_point.workgroup_size.id_x) + index = 0; + else if (c.self == entry_point.workgroup_size.id_y) + index = 1; + else if (c.self == entry_point.workgroup_size.id_z) + index = 2; + } + + return index; +} + void CompilerGLSL::emit_constant(const SPIRConstant &constant) { auto &type = get(constant.constant_type); - auto name = to_name(constant.self); + + // This will break. It is bogus and should not be legal. + if (type_is_top_level_block(type)) + return; SpecializationConstant wg_x, wg_y, wg_z; ID workgroup_size_id = get_work_group_size_specialization_constants(wg_x, wg_y, wg_z); @@ -2703,6 +2880,9 @@ void CompilerGLSL::emit_constant(const SPIRConstant &constant) return; } + add_resource_name(constant.self); + auto name = to_name(constant.self); + // Only scalars have constant IDs. if (has_decoration(constant.self, DecorationSpecId)) { @@ -2945,11 +3125,10 @@ void CompilerGLSL::fixup_image_load_store_access() // Solve this by making the image access as restricted as possible and loosen up if we need to. // If any no-read/no-write flags are actually set, assume that the compiler knows what it's doing. - auto &flags = ir.meta[var].decoration.decoration_flags; - if (!flags.get(DecorationNonWritable) && !flags.get(DecorationNonReadable)) + if (!has_decoration(var, DecorationNonWritable) && !has_decoration(var, DecorationNonReadable)) { - flags.set(DecorationNonWritable); - flags.set(DecorationNonReadable); + set_decoration(var, DecorationNonWritable); + set_decoration(var, DecorationNonReadable); } } }); @@ -2999,16 +3178,21 @@ bool CompilerGLSL::should_force_emit_builtin_block(StorageClass storage) }); // If we're declaring clip/cull planes with control points we need to force block declaration. - if (get_execution_model() == ExecutionModelTessellationControl && + if ((get_execution_model() == ExecutionModelTessellationControl || + get_execution_model() == ExecutionModelMeshEXT) && (clip_distance_count || cull_distance_count)) { should_force = true; } + // Either glslang bug or oversight, but global invariant position does not work in mesh shaders. + if (get_execution_model() == ExecutionModelMeshEXT && position_invariant) + should_force = true; + return should_force; } -void CompilerGLSL::fixup_implicit_builtin_block_names() +void CompilerGLSL::fixup_implicit_builtin_block_names(ExecutionModel model) { ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { auto &type = this->get(var.basetype); @@ -3016,11 +3200,43 @@ void CompilerGLSL::fixup_implicit_builtin_block_names() if ((var.storage == StorageClassOutput || var.storage == StorageClassInput) && block && is_builtin_variable(var)) { - // Make sure the array has a supported name in the code. - if (var.storage == StorageClassOutput) - set_name(var.self, "gl_out"); - else if (var.storage == StorageClassInput) - set_name(var.self, "gl_in"); + if (model != ExecutionModelMeshEXT) + { + // Make sure the array has a supported name in the code. + if (var.storage == StorageClassOutput) + set_name(var.self, "gl_out"); + else if (var.storage == StorageClassInput) + set_name(var.self, "gl_in"); + } + else + { + auto flags = get_buffer_block_flags(var.self); + if (flags.get(DecorationPerPrimitiveEXT)) + { + set_name(var.self, "gl_MeshPrimitivesEXT"); + set_name(type.self, "gl_MeshPerPrimitiveEXT"); + } + else + { + set_name(var.self, "gl_MeshVerticesEXT"); + set_name(type.self, "gl_MeshPerVertexEXT"); + } + } + } + + if (model == ExecutionModelMeshEXT && var.storage == StorageClassOutput && !block) + { + auto *m = ir.find_meta(var.self); + if (m && m->decoration.builtin) + { + auto builtin_type = m->decoration.builtin_type; + if (builtin_type == BuiltInPrimitivePointIndicesEXT) + set_name(var.self, "gl_PrimitivePointIndicesEXT"); + else if (builtin_type == BuiltInPrimitiveLineIndicesEXT) + set_name(var.self, "gl_PrimitiveLineIndicesEXT"); + else if (builtin_type == BuiltInPrimitiveTriangleIndicesEXT) + set_name(var.self, "gl_PrimitiveTriangleIndicesEXT"); + } } }); } @@ -3031,7 +3247,6 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo Bitset global_builtins; const SPIRVariable *block_var = nullptr; bool emitted_block = false; - bool builtin_array = false; // Need to use declared size in the type. // These variables might have been declared, but not statically used, so we haven't deduced their size yet. @@ -3044,6 +3259,11 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo uint32_t xfb_stride = 0, xfb_buffer = 0, geom_stream = 0; std::unordered_map builtin_xfb_offsets; + const auto builtin_is_per_vertex_set = [](BuiltIn builtin) -> bool { + return builtin == BuiltInPosition || builtin == BuiltInPointSize || + builtin == BuiltInClipDistance || builtin == BuiltInCullDistance; + }; + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { auto &type = this->get(var.basetype); bool block = has_decoration(type.self, DecorationBlock); @@ -3054,7 +3274,7 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo uint32_t index = 0; for (auto &m : ir.meta[type.self].members) { - if (m.builtin) + if (m.builtin && builtin_is_per_vertex_set(m.builtin_type)) { builtins.set(m.builtin_type); if (m.builtin_type == BuiltInCullDistance) @@ -3107,13 +3327,15 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo { // While we're at it, collect all declared global builtins (HLSL mostly ...). auto &m = ir.meta[var.self].decoration; - if (m.builtin) + if (m.builtin && builtin_is_per_vertex_set(m.builtin_type)) { + // For mesh/tesc output, Clip/Cull is an array-of-array. Look at innermost array type + // for correct result. global_builtins.set(m.builtin_type); if (m.builtin_type == BuiltInCullDistance) - cull_distance_size = to_array_size_literal(type); + cull_distance_size = to_array_size_literal(type, 0); else if (m.builtin_type == BuiltInClipDistance) - clip_distance_size = to_array_size_literal(type); + clip_distance_size = to_array_size_literal(type, 0); if (is_block_builtin(m.builtin_type) && m.decoration_flags.get(DecorationXfbStride) && m.decoration_flags.get(DecorationXfbBuffer) && m.decoration_flags.get(DecorationOffset)) @@ -3150,7 +3372,6 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo emitted_builtins = builtins; emitted_block = true; - builtin_array = !type.array.empty(); block_var = &var; }); @@ -3196,7 +3417,9 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo attr.push_back(join("stream = ", geom_stream)); } - if (!attr.empty()) + if (model == ExecutionModelMeshEXT) + statement("out gl_MeshPerVertexEXT"); + else if (!attr.empty()) statement("layout(", merge(attr), ") out gl_PerVertex"); else statement("out gl_PerVertex"); @@ -3216,6 +3439,8 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo auto itr = builtin_xfb_offsets.find(BuiltInPosition); if (itr != end(builtin_xfb_offsets)) statement("layout(xfb_offset = ", itr->second, ") vec4 gl_Position;"); + else if (position_invariant) + statement("invariant vec4 gl_Position;"); else statement("vec4 gl_Position;"); } @@ -3247,39 +3472,29 @@ void CompilerGLSL::emit_declared_builtin_block(StorageClass storage, ExecutionMo statement("float gl_CullDistance[", cull_distance_size, "];"); } + bool builtin_array = model == ExecutionModelTessellationControl || + (model == ExecutionModelMeshEXT && storage == StorageClassOutput) || + (model == ExecutionModelGeometry && storage == StorageClassInput) || + (model == ExecutionModelTessellationEvaluation && storage == StorageClassInput); + if (builtin_array) { + const char *instance_name; + if (model == ExecutionModelMeshEXT) + instance_name = "gl_MeshVerticesEXT"; // Per primitive is never synthesized. + else + instance_name = storage == StorageClassInput ? "gl_in" : "gl_out"; + if (model == ExecutionModelTessellationControl && storage == StorageClassOutput) - end_scope_decl(join(to_name(block_var->self), "[", get_entry_point().output_vertices, "]")); + end_scope_decl(join(instance_name, "[", get_entry_point().output_vertices, "]")); else - end_scope_decl(join(to_name(block_var->self), "[]")); + end_scope_decl(join(instance_name, "[]")); } else end_scope_decl(); statement(""); } -void CompilerGLSL::declare_undefined_values() -{ - bool emitted = false; - ir.for_each_typed_id([&](uint32_t, const SPIRUndef &undef) { - auto &type = this->get(undef.basetype); - // OpUndef can be void for some reason ... - if (type.basetype == SPIRType::Void) - return; - - string initializer; - if (options.force_zero_initialized_variables && type_can_zero_initialize(type)) - initializer = join(" = ", to_zero_initialized_expression(undef.basetype)); - - statement(variable_decl(type, to_name(undef.self), undef.self), initializer, ";"); - emitted = true; - }); - - if (emitted) - statement(""); -} - bool CompilerGLSL::variable_is_lut(const SPIRVariable &var) const { bool statically_assigned = var.statically_assigned && var.static_expression != ID(0) && var.remapped_variable; @@ -3314,13 +3529,16 @@ void CompilerGLSL::emit_resources() case ExecutionModelGeometry: case ExecutionModelTessellationControl: case ExecutionModelTessellationEvaluation: - fixup_implicit_builtin_block_names(); + case ExecutionModelMeshEXT: + fixup_implicit_builtin_block_names(execution.model); break; default: break; } + bool global_invariant_position = position_invariant && (options.es || options.version >= 120); + // Emit custom gl_PerVertex for SSO compatibility. if (options.separate_shader_objects && !options.es && execution.model != ExecutionModelFragment) { @@ -3331,10 +3549,13 @@ void CompilerGLSL::emit_resources() case ExecutionModelTessellationEvaluation: emit_declared_builtin_block(StorageClassInput, execution.model); emit_declared_builtin_block(StorageClassOutput, execution.model); + global_invariant_position = false; break; case ExecutionModelVertex: + case ExecutionModelMeshEXT: emit_declared_builtin_block(StorageClassOutput, execution.model); + global_invariant_position = false; break; default: @@ -3344,6 +3565,7 @@ void CompilerGLSL::emit_resources() else if (should_force_emit_builtin_block(StorageClassOutput)) { emit_declared_builtin_block(StorageClassOutput, execution.model); + global_invariant_position = false; } else if (execution.geometry_passthrough) { @@ -3364,7 +3586,7 @@ void CompilerGLSL::emit_resources() statement(""); } - if (position_invariant) + if (global_invariant_position) { statement("invariant gl_Position;"); statement(""); @@ -3378,10 +3600,14 @@ void CompilerGLSL::emit_resources() // { auto loop_lock = ir.create_loop_hard_lock(); - for (auto &id_ : ir.ids_for_constant_or_type) + for (auto &id_ : ir.ids_for_constant_undef_or_type) { auto &id = ir.ids[id_]; + // Skip declaring any bogus constants or undefs which use block types. + // We don't declare block types directly, so this will never work. + // Should not be legal SPIR-V, so this is considered a workaround. + if (id.get_type() == TypeConstant) { auto &c = id.get(); @@ -3431,6 +3657,26 @@ void CompilerGLSL::emit_resources() emit_struct(*type); } } + else if (id.get_type() == TypeUndef) + { + auto &undef = id.get(); + auto &type = this->get(undef.basetype); + // OpUndef can be void for some reason ... + if (type.basetype == SPIRType::Void) + return; + + // This will break. It is bogus and should not be legal. + if (type_is_top_level_block(type)) + return; + + string initializer; + if (options.force_zero_initialized_variables && type_can_zero_initialize(type)) + initializer = join(" = ", to_zero_initialized_expression(undef.basetype)); + + // FIXME: If used in a constant, we must declare it as one. + statement(variable_decl(type, to_name(undef.self), undef.self), initializer, ";"); + emitted = true; + } } } @@ -3441,7 +3687,7 @@ void CompilerGLSL::emit_resources() // If the work group size depends on a specialization constant, we need to declare the layout() block // after constants (and their macros) have been declared. if (execution.model == ExecutionModelGLCompute && !options.vulkan_semantics && - execution.workgroup_size.constant != 0) + (execution.workgroup_size.constant != 0 || execution.flags.get(ExecutionModeLocalSizeId))) { SpecializationConstant wg_x, wg_y, wg_z; get_work_group_size_specialization_constants(wg_x, wg_y, wg_z); @@ -3647,8 +3893,6 @@ void CompilerGLSL::emit_resources() if (emitted) statement(""); - - declare_undefined_values(); } void CompilerGLSL::emit_output_variable_initializer(const SPIRVariable &var) @@ -3694,6 +3938,7 @@ void CompilerGLSL::emit_output_variable_initializer(const SPIRVariable &var) auto &member_type = get(member_type_id); auto array_type = member_type; array_type.parent_type = member_type_id; + array_type.op = OpTypeArray; array_type.array.push_back(array_size); array_type.array_size_literal.push_back(true); @@ -3717,10 +3962,9 @@ void CompilerGLSL::emit_output_variable_initializer(const SPIRVariable &var) if (is_control_point) { uint32_t ids = ir.increase_bound_by(3); - SPIRType uint_type; + auto &uint_type = set(ids, OpTypeInt); uint_type.basetype = SPIRType::UInt; uint_type.width = 32; - set(ids, uint_type); set(ids + 1, builtin_to_glsl(BuiltInInvocationId, StorageClassInput), ids, true); set(ids + 2, ids, i, false); invocation_id = ids + 1; @@ -3800,6 +4044,169 @@ void CompilerGLSL::emit_output_variable_initializer(const SPIRVariable &var) } } +void CompilerGLSL::emit_subgroup_arithmetic_workaround(const std::string &func, Op op, GroupOperation group_op) +{ + std::string result; + switch (group_op) + { + case GroupOperationReduce: + result = "reduction"; + break; + + case GroupOperationExclusiveScan: + result = "excl_scan"; + break; + + case GroupOperationInclusiveScan: + result = "incl_scan"; + break; + + default: + SPIRV_CROSS_THROW("Unsupported workaround for arithmetic group operation"); + } + + struct TypeInfo + { + std::string type; + std::string identity; + }; + + std::vector type_infos; + switch (op) + { + case OpGroupNonUniformIAdd: + { + type_infos.emplace_back(TypeInfo{ "uint", "0u" }); + type_infos.emplace_back(TypeInfo{ "uvec2", "uvec2(0u)" }); + type_infos.emplace_back(TypeInfo{ "uvec3", "uvec3(0u)" }); + type_infos.emplace_back(TypeInfo{ "uvec4", "uvec4(0u)" }); + type_infos.emplace_back(TypeInfo{ "int", "0" }); + type_infos.emplace_back(TypeInfo{ "ivec2", "ivec2(0)" }); + type_infos.emplace_back(TypeInfo{ "ivec3", "ivec3(0)" }); + type_infos.emplace_back(TypeInfo{ "ivec4", "ivec4(0)" }); + break; + } + + case OpGroupNonUniformFAdd: + { + type_infos.emplace_back(TypeInfo{ "float", "0.0f" }); + type_infos.emplace_back(TypeInfo{ "vec2", "vec2(0.0f)" }); + type_infos.emplace_back(TypeInfo{ "vec3", "vec3(0.0f)" }); + type_infos.emplace_back(TypeInfo{ "vec4", "vec4(0.0f)" }); + // ARB_gpu_shader_fp64 is required in GL4.0 which in turn is required by NV_thread_shuffle + type_infos.emplace_back(TypeInfo{ "double", "0.0LF" }); + type_infos.emplace_back(TypeInfo{ "dvec2", "dvec2(0.0LF)" }); + type_infos.emplace_back(TypeInfo{ "dvec3", "dvec3(0.0LF)" }); + type_infos.emplace_back(TypeInfo{ "dvec4", "dvec4(0.0LF)" }); + break; + } + + case OpGroupNonUniformIMul: + { + type_infos.emplace_back(TypeInfo{ "uint", "1u" }); + type_infos.emplace_back(TypeInfo{ "uvec2", "uvec2(1u)" }); + type_infos.emplace_back(TypeInfo{ "uvec3", "uvec3(1u)" }); + type_infos.emplace_back(TypeInfo{ "uvec4", "uvec4(1u)" }); + type_infos.emplace_back(TypeInfo{ "int", "1" }); + type_infos.emplace_back(TypeInfo{ "ivec2", "ivec2(1)" }); + type_infos.emplace_back(TypeInfo{ "ivec3", "ivec3(1)" }); + type_infos.emplace_back(TypeInfo{ "ivec4", "ivec4(1)" }); + break; + } + + case OpGroupNonUniformFMul: + { + type_infos.emplace_back(TypeInfo{ "float", "1.0f" }); + type_infos.emplace_back(TypeInfo{ "vec2", "vec2(1.0f)" }); + type_infos.emplace_back(TypeInfo{ "vec3", "vec3(1.0f)" }); + type_infos.emplace_back(TypeInfo{ "vec4", "vec4(1.0f)" }); + type_infos.emplace_back(TypeInfo{ "double", "0.0LF" }); + type_infos.emplace_back(TypeInfo{ "dvec2", "dvec2(1.0LF)" }); + type_infos.emplace_back(TypeInfo{ "dvec3", "dvec3(1.0LF)" }); + type_infos.emplace_back(TypeInfo{ "dvec4", "dvec4(1.0LF)" }); + break; + } + + default: + SPIRV_CROSS_THROW("Unsupported workaround for arithmetic group operation"); + } + + const bool op_is_addition = op == OpGroupNonUniformIAdd || op == OpGroupNonUniformFAdd; + const bool op_is_multiplication = op == OpGroupNonUniformIMul || op == OpGroupNonUniformFMul; + std::string op_symbol; + if (op_is_addition) + { + op_symbol = "+="; + } + else if (op_is_multiplication) + { + op_symbol = "*="; + } + + for (const TypeInfo &t : type_infos) + { + statement(t.type, " ", func, "(", t.type, " v)"); + begin_scope(); + statement(t.type, " ", result, " = ", t.identity, ";"); + statement("uvec4 active_threads = subgroupBallot(true);"); + statement("if (subgroupBallotBitCount(active_threads) == gl_SubgroupSize)"); + begin_scope(); + statement("uint total = gl_SubgroupSize / 2u;"); + statement(result, " = v;"); + statement("for (uint i = 1u; i <= total; i <<= 1u)"); + begin_scope(); + statement("bool valid;"); + if (group_op == GroupOperationReduce) + { + statement(t.type, " s = shuffleXorNV(", result, ", i, gl_SubgroupSize, valid);"); + } + else if (group_op == GroupOperationExclusiveScan || group_op == GroupOperationInclusiveScan) + { + statement(t.type, " s = shuffleUpNV(", result, ", i, gl_SubgroupSize, valid);"); + } + if (op_is_addition || op_is_multiplication) + { + statement(result, " ", op_symbol, " valid ? s : ", t.identity, ";"); + } + end_scope(); + if (group_op == GroupOperationExclusiveScan) + { + statement(result, " = shuffleUpNV(", result, ", 1u, gl_SubgroupSize);"); + statement("if (subgroupElect())"); + begin_scope(); + statement(result, " = ", t.identity, ";"); + end_scope(); + } + end_scope(); + statement("else"); + begin_scope(); + if (group_op == GroupOperationExclusiveScan) + { + statement("uint total = subgroupBallotBitCount(gl_SubgroupLtMask);"); + } + else if (group_op == GroupOperationInclusiveScan) + { + statement("uint total = subgroupBallotBitCount(gl_SubgroupLeMask);"); + } + statement("for (uint i = 0u; i < gl_SubgroupSize; ++i)"); + begin_scope(); + statement("bool valid = subgroupBallotBitExtract(active_threads, i);"); + statement(t.type, " s = shuffleNV(v, i, gl_SubgroupSize);"); + if (group_op == GroupOperationExclusiveScan || group_op == GroupOperationInclusiveScan) + { + statement("valid = valid && (i < total);"); + } + if (op_is_addition || op_is_multiplication) + { + statement(result, " ", op_symbol, " valid ? s : ", t.identity, ";"); + } + end_scope(); + end_scope(); + statement("return ", result, ";"); + end_scope(); + } +} + void CompilerGLSL::emit_extension_workarounds(spv::ExecutionModel model) { static const char *workaround_types[] = { "int", "ivec2", "ivec3", "ivec4", "uint", "uvec2", "uvec3", "uvec4", @@ -4203,46 +4610,208 @@ void CompilerGLSL::emit_extension_workarounds(spv::ExecutionModel model) statement("#endif"); statement(""); } - } - if (!workaround_ubo_load_overload_types.empty()) - { - for (auto &type_id : workaround_ubo_load_overload_types) + auto arithmetic_feature_helper = + [&](Supp::Feature feat, std::string func_name, spv::Op op, spv::GroupOperation group_op) { - auto &type = get(type_id); - statement(type_to_glsl(type), " spvWorkaroundRowMajor(", type_to_glsl(type), - " wrap) { return wrap; }"); - } - statement(""); - } + if (shader_subgroup_supporter.is_feature_requested(feat)) + { + auto exts = Supp::get_candidates_for_feature(feat, result); + for (auto &e : exts) + { + const char *name = Supp::get_extension_name(e); + statement(&e == &exts.front() ? "#if" : "#elif", " defined(", name, ")"); - if (requires_transpose_2x2) + switch (e) + { + case Supp::NV_shader_thread_shuffle: + emit_subgroup_arithmetic_workaround(func_name, op, group_op); + break; + default: + break; + } + } + statement("#endif"); + statement(""); + } + }; + + arithmetic_feature_helper(Supp::SubgroupArithmeticIAddReduce, "subgroupAdd", OpGroupNonUniformIAdd, + GroupOperationReduce); + arithmetic_feature_helper(Supp::SubgroupArithmeticIAddExclusiveScan, "subgroupExclusiveAdd", + OpGroupNonUniformIAdd, GroupOperationExclusiveScan); + arithmetic_feature_helper(Supp::SubgroupArithmeticIAddInclusiveScan, "subgroupInclusiveAdd", + OpGroupNonUniformIAdd, GroupOperationInclusiveScan); + arithmetic_feature_helper(Supp::SubgroupArithmeticFAddReduce, "subgroupAdd", OpGroupNonUniformFAdd, + GroupOperationReduce); + arithmetic_feature_helper(Supp::SubgroupArithmeticFAddExclusiveScan, "subgroupExclusiveAdd", + OpGroupNonUniformFAdd, GroupOperationExclusiveScan); + arithmetic_feature_helper(Supp::SubgroupArithmeticFAddInclusiveScan, "subgroupInclusiveAdd", + OpGroupNonUniformFAdd, GroupOperationInclusiveScan); + + arithmetic_feature_helper(Supp::SubgroupArithmeticIMulReduce, "subgroupMul", OpGroupNonUniformIMul, + GroupOperationReduce); + arithmetic_feature_helper(Supp::SubgroupArithmeticIMulExclusiveScan, "subgroupExclusiveMul", + OpGroupNonUniformIMul, GroupOperationExclusiveScan); + arithmetic_feature_helper(Supp::SubgroupArithmeticIMulInclusiveScan, "subgroupInclusiveMul", + OpGroupNonUniformIMul, GroupOperationInclusiveScan); + arithmetic_feature_helper(Supp::SubgroupArithmeticFMulReduce, "subgroupMul", OpGroupNonUniformFMul, + GroupOperationReduce); + arithmetic_feature_helper(Supp::SubgroupArithmeticFMulExclusiveScan, "subgroupExclusiveMul", + OpGroupNonUniformFMul, GroupOperationExclusiveScan); + arithmetic_feature_helper(Supp::SubgroupArithmeticFMulInclusiveScan, "subgroupInclusiveMul", + OpGroupNonUniformFMul, GroupOperationInclusiveScan); + } + + if (!workaround_ubo_load_overload_types.empty()) + { + for (auto &type_id : workaround_ubo_load_overload_types) + { + auto &type = get(type_id); + + if (options.es && is_matrix(type)) + { + // Need both variants. + // GLSL cannot overload on precision, so need to dispatch appropriately. + statement("highp ", type_to_glsl(type), " spvWorkaroundRowMajor(highp ", type_to_glsl(type), " wrap) { return wrap; }"); + statement("mediump ", type_to_glsl(type), " spvWorkaroundRowMajorMP(mediump ", type_to_glsl(type), " wrap) { return wrap; }"); + } + else + { + statement(type_to_glsl(type), " spvWorkaroundRowMajor(", type_to_glsl(type), " wrap) { return wrap; }"); + } + } + statement(""); + } +} + +void CompilerGLSL::emit_polyfills(uint32_t polyfills, bool relaxed) +{ + const char *qual = ""; + const char *suffix = (options.es && relaxed) ? "MP" : ""; + if (options.es) + qual = relaxed ? "mediump " : "highp "; + + if (polyfills & PolyfillTranspose2x2) { - statement("mat2 spvTranspose(mat2 m)"); + statement(qual, "mat2 spvTranspose", suffix, "(", qual, "mat2 m)"); begin_scope(); statement("return mat2(m[0][0], m[1][0], m[0][1], m[1][1]);"); end_scope(); statement(""); } - if (requires_transpose_3x3) + if (polyfills & PolyfillTranspose3x3) { - statement("mat3 spvTranspose(mat3 m)"); + statement(qual, "mat3 spvTranspose", suffix, "(", qual, "mat3 m)"); begin_scope(); statement("return mat3(m[0][0], m[1][0], m[2][0], m[0][1], m[1][1], m[2][1], m[0][2], m[1][2], m[2][2]);"); end_scope(); statement(""); } - if (requires_transpose_4x4) + if (polyfills & PolyfillTranspose4x4) { - statement("mat4 spvTranspose(mat4 m)"); + statement(qual, "mat4 spvTranspose", suffix, "(", qual, "mat4 m)"); begin_scope(); statement("return mat4(m[0][0], m[1][0], m[2][0], m[3][0], m[0][1], m[1][1], m[2][1], m[3][1], m[0][2], " "m[1][2], m[2][2], m[3][2], m[0][3], m[1][3], m[2][3], m[3][3]);"); end_scope(); statement(""); } + + if (polyfills & PolyfillDeterminant2x2) + { + statement(qual, "float spvDeterminant", suffix, "(", qual, "mat2 m)"); + begin_scope(); + statement("return m[0][0] * m[1][1] - m[0][1] * m[1][0];"); + end_scope(); + statement(""); + } + + if (polyfills & PolyfillDeterminant3x3) + { + statement(qual, "float spvDeterminant", suffix, "(", qual, "mat3 m)"); + begin_scope(); + statement("return dot(m[0], vec3(m[1][1] * m[2][2] - m[1][2] * m[2][1], " + "m[1][2] * m[2][0] - m[1][0] * m[2][2], " + "m[1][0] * m[2][1] - m[1][1] * m[2][0]));"); + end_scope(); + statement(""); + } + + if (polyfills & PolyfillDeterminant4x4) + { + statement(qual, "float spvDeterminant", suffix, "(", qual, "mat4 m)"); + begin_scope(); + statement("return dot(m[0], vec4(" + "m[2][1] * m[3][2] * m[1][3] - m[3][1] * m[2][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3] - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] + m[1][1] * m[2][2] * m[3][3], " + "m[3][0] * m[2][2] * m[1][3] - m[2][0] * m[3][2] * m[1][3] - m[3][0] * m[1][2] * m[2][3] + m[1][0] * m[3][2] * m[2][3] + m[2][0] * m[1][2] * m[3][3] - m[1][0] * m[2][2] * m[3][3], " + "m[2][0] * m[3][1] * m[1][3] - m[3][0] * m[2][1] * m[1][3] + m[3][0] * m[1][1] * m[2][3] - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] + m[1][0] * m[2][1] * m[3][3], " + "m[3][0] * m[2][1] * m[1][2] - m[2][0] * m[3][1] * m[1][2] - m[3][0] * m[1][1] * m[2][2] + m[1][0] * m[3][1] * m[2][2] + m[2][0] * m[1][1] * m[3][2] - m[1][0] * m[2][1] * m[3][2]));"); + end_scope(); + statement(""); + } + + if (polyfills & PolyfillMatrixInverse2x2) + { + statement(qual, "mat2 spvInverse", suffix, "(", qual, "mat2 m)"); + begin_scope(); + statement("return mat2(m[1][1], -m[0][1], -m[1][0], m[0][0]) " + "* (1.0 / (m[0][0] * m[1][1] - m[1][0] * m[0][1]));"); + end_scope(); + statement(""); + } + + if (polyfills & PolyfillMatrixInverse3x3) + { + statement(qual, "mat3 spvInverse", suffix, "(", qual, "mat3 m)"); + begin_scope(); + statement(qual, "vec3 t = vec3(m[1][1] * m[2][2] - m[1][2] * m[2][1], m[1][2] * m[2][0] - m[1][0] * m[2][2], m[1][0] * m[2][1] - m[1][1] * m[2][0]);"); + statement("return mat3(t[0], " + "m[0][2] * m[2][1] - m[0][1] * m[2][2], " + "m[0][1] * m[1][2] - m[0][2] * m[1][1], " + "t[1], " + "m[0][0] * m[2][2] - m[0][2] * m[2][0], " + "m[0][2] * m[1][0] - m[0][0] * m[1][2], " + "t[2], " + "m[0][1] * m[2][0] - m[0][0] * m[2][1], " + "m[0][0] * m[1][1] - m[0][1] * m[1][0]) " + "* (1.0 / dot(m[0], t));"); + end_scope(); + statement(""); + } + + if (polyfills & PolyfillMatrixInverse4x4) + { + statement(qual, "mat4 spvInverse", suffix, "(", qual, "mat4 m)"); + begin_scope(); + statement(qual, "vec4 t = vec4(" + "m[2][1] * m[3][2] * m[1][3] - m[3][1] * m[2][2] * m[1][3] + m[3][1] * m[1][2] * m[2][3] - m[1][1] * m[3][2] * m[2][3] - m[2][1] * m[1][2] * m[3][3] + m[1][1] * m[2][2] * m[3][3], " + "m[3][0] * m[2][2] * m[1][3] - m[2][0] * m[3][2] * m[1][3] - m[3][0] * m[1][2] * m[2][3] + m[1][0] * m[3][2] * m[2][3] + m[2][0] * m[1][2] * m[3][3] - m[1][0] * m[2][2] * m[3][3], " + "m[2][0] * m[3][1] * m[1][3] - m[3][0] * m[2][1] * m[1][3] + m[3][0] * m[1][1] * m[2][3] - m[1][0] * m[3][1] * m[2][3] - m[2][0] * m[1][1] * m[3][3] + m[1][0] * m[2][1] * m[3][3], " + "m[3][0] * m[2][1] * m[1][2] - m[2][0] * m[3][1] * m[1][2] - m[3][0] * m[1][1] * m[2][2] + m[1][0] * m[3][1] * m[2][2] + m[2][0] * m[1][1] * m[3][2] - m[1][0] * m[2][1] * m[3][2]);"); + statement("return mat4(" + "t[0], " + "m[3][1] * m[2][2] * m[0][3] - m[2][1] * m[3][2] * m[0][3] - m[3][1] * m[0][2] * m[2][3] + m[0][1] * m[3][2] * m[2][3] + m[2][1] * m[0][2] * m[3][3] - m[0][1] * m[2][2] * m[3][3], " + "m[1][1] * m[3][2] * m[0][3] - m[3][1] * m[1][2] * m[0][3] + m[3][1] * m[0][2] * m[1][3] - m[0][1] * m[3][2] * m[1][3] - m[1][1] * m[0][2] * m[3][3] + m[0][1] * m[1][2] * m[3][3], " + "m[2][1] * m[1][2] * m[0][3] - m[1][1] * m[2][2] * m[0][3] - m[2][1] * m[0][2] * m[1][3] + m[0][1] * m[2][2] * m[1][3] + m[1][1] * m[0][2] * m[2][3] - m[0][1] * m[1][2] * m[2][3], " + "t[1], " + "m[2][0] * m[3][2] * m[0][3] - m[3][0] * m[2][2] * m[0][3] + m[3][0] * m[0][2] * m[2][3] - m[0][0] * m[3][2] * m[2][3] - m[2][0] * m[0][2] * m[3][3] + m[0][0] * m[2][2] * m[3][3], " + "m[3][0] * m[1][2] * m[0][3] - m[1][0] * m[3][2] * m[0][3] - m[3][0] * m[0][2] * m[1][3] + m[0][0] * m[3][2] * m[1][3] + m[1][0] * m[0][2] * m[3][3] - m[0][0] * m[1][2] * m[3][3], " + "m[1][0] * m[2][2] * m[0][3] - m[2][0] * m[1][2] * m[0][3] + m[2][0] * m[0][2] * m[1][3] - m[0][0] * m[2][2] * m[1][3] - m[1][0] * m[0][2] * m[2][3] + m[0][0] * m[1][2] * m[2][3], " + "t[2], " + "m[3][0] * m[2][1] * m[0][3] - m[2][0] * m[3][1] * m[0][3] - m[3][0] * m[0][1] * m[2][3] + m[0][0] * m[3][1] * m[2][3] + m[2][0] * m[0][1] * m[3][3] - m[0][0] * m[2][1] * m[3][3], " + "m[1][0] * m[3][1] * m[0][3] - m[3][0] * m[1][1] * m[0][3] + m[3][0] * m[0][1] * m[1][3] - m[0][0] * m[3][1] * m[1][3] - m[1][0] * m[0][1] * m[3][3] + m[0][0] * m[1][1] * m[3][3], " + "m[2][0] * m[1][1] * m[0][3] - m[1][0] * m[2][1] * m[0][3] - m[2][0] * m[0][1] * m[1][3] + m[0][0] * m[2][1] * m[1][3] + m[1][0] * m[0][1] * m[2][3] - m[0][0] * m[1][1] * m[2][3], " + "t[3], " + "m[2][0] * m[3][1] * m[0][2] - m[3][0] * m[2][1] * m[0][2] + m[3][0] * m[0][1] * m[2][2] - m[0][0] * m[3][1] * m[2][2] - m[2][0] * m[0][1] * m[3][2] + m[0][0] * m[2][1] * m[3][2], " + "m[3][0] * m[1][1] * m[0][2] - m[1][0] * m[3][1] * m[0][2] - m[3][0] * m[0][1] * m[1][2] + m[0][0] * m[3][1] * m[1][2] + m[1][0] * m[0][1] * m[3][2] - m[0][0] * m[1][1] * m[3][2], " + "m[1][0] * m[2][1] * m[0][2] - m[2][0] * m[1][1] * m[0][2] + m[2][0] * m[0][1] * m[1][2] - m[0][0] * m[2][1] * m[1][2] - m[1][0] * m[0][1] * m[2][2] + m[0][0] * m[1][1] * m[2][2]) " + "* (1.0 / dot(m[0], t));"); + end_scope(); + statement(""); + } } // Returns a string representation of the ID, usable as a function arg. @@ -4258,12 +4827,96 @@ string CompilerGLSL::to_func_call_arg(const SPIRFunction::Parameter &, uint32_t return to_expression(name_id); } +void CompilerGLSL::force_temporary_and_recompile(uint32_t id) +{ + auto res = forced_temporaries.insert(id); + + // Forcing new temporaries guarantees forward progress. + if (res.second) + force_recompile_guarantee_forward_progress(); + else + force_recompile(); +} + +uint32_t CompilerGLSL::consume_temporary_in_precision_context(uint32_t type_id, uint32_t id, Options::Precision precision) +{ + // Constants do not have innate precision. + auto handle_type = ir.ids[id].get_type(); + if (handle_type == TypeConstant || handle_type == TypeConstantOp || handle_type == TypeUndef) + return id; + + // Ignore anything that isn't 32-bit values. + auto &type = get(type_id); + if (type.pointer) + return id; + if (type.basetype != SPIRType::Float && type.basetype != SPIRType::UInt && type.basetype != SPIRType::Int) + return id; + + if (precision == Options::DontCare) + { + // If precision is consumed as don't care (operations only consisting of constants), + // we need to bind the expression to a temporary, + // otherwise we have no way of controlling the precision later. + auto itr = forced_temporaries.insert(id); + if (itr.second) + force_recompile_guarantee_forward_progress(); + return id; + } + + auto current_precision = has_decoration(id, DecorationRelaxedPrecision) ? Options::Mediump : Options::Highp; + if (current_precision == precision) + return id; + + auto itr = temporary_to_mirror_precision_alias.find(id); + if (itr == temporary_to_mirror_precision_alias.end()) + { + uint32_t alias_id = ir.increase_bound_by(1); + auto &m = ir.meta[alias_id]; + if (auto *input_m = ir.find_meta(id)) + m = *input_m; + + const char *prefix; + if (precision == Options::Mediump) + { + set_decoration(alias_id, DecorationRelaxedPrecision); + prefix = "mp_copy_"; + } + else + { + unset_decoration(alias_id, DecorationRelaxedPrecision); + prefix = "hp_copy_"; + } + + auto alias_name = join(prefix, to_name(id)); + ParsedIR::sanitize_underscores(alias_name); + set_name(alias_id, alias_name); + + emit_op(type_id, alias_id, to_expression(id), true); + temporary_to_mirror_precision_alias[id] = alias_id; + forced_temporaries.insert(id); + forced_temporaries.insert(alias_id); + force_recompile_guarantee_forward_progress(); + id = alias_id; + } + else + { + id = itr->second; + } + + return id; +} + void CompilerGLSL::handle_invalid_expression(uint32_t id) { // We tried to read an invalidated expression. - // This means we need another pass at compilation, but next time, force temporary variables so that they cannot be invalidated. - forced_temporaries.insert(id); - force_recompile(); + // This means we need another pass at compilation, but next time, + // force temporary variables so that they cannot be invalidated. + force_temporary_and_recompile(id); + + // If the invalid expression happened as a result of a CompositeInsert + // overwrite, we must block this from happening next iteration. + if (composite_insert_overwritten.count(id)) + block_composite_insert_overwrite.insert(id); } // Converts the format of the current expression from packed to unpacked, @@ -4301,7 +4954,7 @@ void CompilerGLSL::strip_enclosed_expression(string &expr) expr.erase(begin(expr)); } -string CompilerGLSL::enclose_expression(const string &expr) +bool CompilerGLSL::needs_enclose_expression(const std::string &expr) { bool need_parens = false; @@ -4335,10 +4988,15 @@ string CompilerGLSL::enclose_expression(const string &expr) assert(paren_count == 0); } + return need_parens; +} + +string CompilerGLSL::enclose_expression(const string &expr) +{ // If this expression contains any spaces which are not enclosed by parentheses, // we need to enclose it so we can treat the whole string as an expression. // This happens when two expressions have been part of a binary op earlier. - if (need_parens) + if (needs_enclose_expression(expr)) return join('(', expr, ')'); else return expr; @@ -4495,8 +5153,27 @@ string CompilerGLSL::to_extract_constant_composite_expression(uint32_t result_ty return constant_expression(tmp); } -string CompilerGLSL::to_rerolled_array_expression(const string &base_expr, const SPIRType &type) +string CompilerGLSL::to_rerolled_array_expression(const SPIRType &parent_type, + const string &base_expr, const SPIRType &type) { + bool remapped_boolean = parent_type.basetype == SPIRType::Struct && + type.basetype == SPIRType::Boolean && + backend.boolean_in_struct_remapped_type != SPIRType::Boolean; + + SPIRType tmp_type { OpNop }; + if (remapped_boolean) + { + tmp_type = get(type.parent_type); + tmp_type.basetype = backend.boolean_in_struct_remapped_type; + } + else if (type.basetype == SPIRType::Boolean && backend.boolean_in_struct_remapped_type != SPIRType::Boolean) + { + // It's possible that we have an r-value expression that was OpLoaded from a struct. + // We have to reroll this and explicitly cast the input to bool, because the r-value is short. + tmp_type = get(type.parent_type); + remapped_boolean = true; + } + uint32_t size = to_array_size_literal(type); auto &parent = get(type.parent_type); string expr = "{ "; @@ -4504,10 +5181,14 @@ string CompilerGLSL::to_rerolled_array_expression(const string &base_expr, const for (uint32_t i = 0; i < size; i++) { auto subexpr = join(base_expr, "[", convert_to_string(i), "]"); - if (parent.array.empty()) + if (!is_array(parent)) + { + if (remapped_boolean) + subexpr = join(type_to_glsl(tmp_type), "(", subexpr, ")"); expr += subexpr; + } else - expr += to_rerolled_array_expression(subexpr, parent); + expr += to_rerolled_array_expression(parent_type, subexpr, parent); if (i + 1 < size) expr += ", "; @@ -4517,12 +5198,26 @@ string CompilerGLSL::to_rerolled_array_expression(const string &base_expr, const return expr; } -string CompilerGLSL::to_composite_constructor_expression(uint32_t id, bool uses_buffer_offset) +string CompilerGLSL::to_composite_constructor_expression(const SPIRType &parent_type, uint32_t id, bool block_like_type) { auto &type = expression_type(id); - bool reroll_array = !type.array.empty() && (!backend.array_is_value_type || - (uses_buffer_offset && !backend.buffer_offset_array_is_value_type)); + bool reroll_array = false; + bool remapped_boolean = parent_type.basetype == SPIRType::Struct && + type.basetype == SPIRType::Boolean && + backend.boolean_in_struct_remapped_type != SPIRType::Boolean; + + if (is_array(type)) + { + reroll_array = !backend.array_is_value_type || + (block_like_type && !backend.array_is_value_type_in_buffer_blocks); + + if (remapped_boolean) + { + // Forced to reroll if we have to change bool[] to short[]. + reroll_array = true; + } + } if (reroll_array) { @@ -4536,10 +5231,20 @@ string CompilerGLSL::to_composite_constructor_expression(uint32_t id, bool uses_ // We're only triggering one read of the array expression, but this is fine since arrays have to be declared // as temporaries anyways. - return to_rerolled_array_expression(to_enclosed_expression(id), type); + return to_rerolled_array_expression(parent_type, to_enclosed_expression(id), type); } else - return to_unpacked_expression(id); + { + auto expr = to_unpacked_expression(id); + if (remapped_boolean) + { + auto tmp_type = type; + tmp_type.basetype = backend.boolean_in_struct_remapped_type; + expr = join(type_to_glsl(tmp_type), "(", expr, ")"); + } + + return expr; + } } string CompilerGLSL::to_non_uniform_aware_expression(uint32_t id) @@ -4593,8 +5298,9 @@ string CompilerGLSL::to_expression(uint32_t id, bool register_expression_read) // when consuming an access chain expression. uint32_t physical_type_id = get_extended_decoration(id, SPIRVCrossDecorationPhysicalTypeID); bool is_packed = has_extended_decoration(id, SPIRVCrossDecorationPhysicalTypePacked); + bool relaxed = has_decoration(id, DecorationRelaxedPrecision); return convert_row_major_matrix(e.expression, get(e.expression_type), physical_type_id, - is_packed); + is_packed, relaxed); } else if (flattened_structs.count(id)) { @@ -4620,11 +5326,27 @@ string CompilerGLSL::to_expression(uint32_t id, bool register_expression_read) auto &type = get(c.constant_type); // WorkGroupSize may be a constant. - auto &dec = ir.meta[c.self].decoration; - if (dec.builtin) - return builtin_to_glsl(dec.builtin_type, StorageClassGeneric); + if (has_decoration(c.self, DecorationBuiltIn)) + return builtin_to_glsl(BuiltIn(get_decoration(c.self, DecorationBuiltIn)), StorageClassGeneric); else if (c.specialization) + { + if (backend.workgroup_size_is_hidden) + { + int wg_index = get_constant_mapping_to_workgroup_component(c); + if (wg_index >= 0) + { + auto wg_size = join(builtin_to_glsl(BuiltInWorkgroupSize, StorageClassInput), vector_swizzle(1, wg_index)); + if (type.basetype != SPIRType::UInt) + wg_size = bitcast_expression(type, SPIRType::UInt, wg_size); + return wg_size; + } + } + + if (expression_is_forwarded(id)) + return constant_expression(c); + return to_name(id); + } else if (c.is_used_as_lut) return to_name(id); else if (type.basetype == SPIRType::Struct && !backend.can_declare_struct_inline) @@ -4644,7 +5366,20 @@ string CompilerGLSL::to_expression(uint32_t id, bool register_expression_read) // If we try to use a loop variable before the loop header, we have to redirect it to the static expression, // the variable has not been declared yet. if (var.statically_assigned || (var.loop_variable && !var.loop_variable_enable)) - return to_expression(var.static_expression); + { + // We might try to load from a loop variable before it has been initialized. + // Prefer static expression and fallback to initializer. + if (var.static_expression) + return to_expression(var.static_expression); + else if (var.initializer) + return to_expression(var.initializer); + else + { + // We cannot declare the variable yet, so have to fake it. + uint32_t undef_id = ir.increase_bound_by(1); + return emit_uninitialized_temporary_expression(get_variable_data_type_id(var), undef_id).expression; + } + } else if (var.deferred_declaration) { var.deferred_declaration = false; @@ -4681,6 +5416,80 @@ string CompilerGLSL::to_expression(uint32_t id, bool register_expression_read) } } +SmallVector CompilerGLSL::get_composite_constant_ids(ConstantID const_id) +{ + if (auto *constant = maybe_get(const_id)) + { + const auto &type = get(constant->constant_type); + if (is_array(type) || type.basetype == SPIRType::Struct) + return constant->subconstants; + if (is_matrix(type)) + return SmallVector(constant->m.id); + if (is_vector(type)) + return SmallVector(constant->m.c[0].id); + SPIRV_CROSS_THROW("Unexpected scalar constant!"); + } + if (!const_composite_insert_ids.count(const_id)) + SPIRV_CROSS_THROW("Unimplemented for this OpSpecConstantOp!"); + return const_composite_insert_ids[const_id]; +} + +void CompilerGLSL::fill_composite_constant(SPIRConstant &constant, TypeID type_id, + const SmallVector &initializers) +{ + auto &type = get(type_id); + constant.specialization = true; + if (is_array(type) || type.basetype == SPIRType::Struct) + { + constant.subconstants = initializers; + } + else if (is_matrix(type)) + { + constant.m.columns = type.columns; + for (uint32_t i = 0; i < type.columns; ++i) + { + constant.m.id[i] = initializers[i]; + constant.m.c[i].vecsize = type.vecsize; + } + } + else if (is_vector(type)) + { + constant.m.c[0].vecsize = type.vecsize; + for (uint32_t i = 0; i < type.vecsize; ++i) + constant.m.c[0].id[i] = initializers[i]; + } + else + SPIRV_CROSS_THROW("Unexpected scalar in SpecConstantOp CompositeInsert!"); +} + +void CompilerGLSL::set_composite_constant(ConstantID const_id, TypeID type_id, + const SmallVector &initializers) +{ + if (maybe_get(const_id)) + { + const_composite_insert_ids[const_id] = initializers; + return; + } + + auto &constant = set(const_id, type_id); + fill_composite_constant(constant, type_id, initializers); + forwarded_temporaries.insert(const_id); +} + +TypeID CompilerGLSL::get_composite_member_type(TypeID type_id, uint32_t member_idx) +{ + auto &type = get(type_id); + if (is_array(type)) + return type.parent_type; + if (type.basetype == SPIRType::Struct) + return type.member_types[member_idx]; + if (is_matrix(type)) + return type.parent_type; + if (is_vector(type)) + return type.parent_type; + SPIRV_CROSS_THROW("Shouldn't reach lower than vector handling OpSpecConstantOp CompositeInsert!"); +} + string CompilerGLSL::constant_op_expression(const SPIRConstantOp &cop) { auto &type = get(cop.basetype); @@ -4785,10 +5594,21 @@ string CompilerGLSL::constant_op_expression(const SPIRConstantOp &cop) for (uint32_t i = 2; i < uint32_t(cop.arguments.size()); i++) { uint32_t index = cop.arguments[i]; - if (index >= left_components) + if (index == 0xFFFFFFFF) + { + SPIRConstant c; + c.constant_type = type.parent_type; + assert(type.parent_type != ID(0)); + expr += constant_expression(c); + } + else if (index >= left_components) + { expr += right_arg + "." + "xyzw"[index - left_components]; + } else + { expr += left_arg + "." + "xyzw"[index]; + } if (i + 1 < uint32_t(cop.arguments.size())) expr += ", "; @@ -4806,7 +5626,30 @@ string CompilerGLSL::constant_op_expression(const SPIRConstantOp &cop) } case OpCompositeInsert: - SPIRV_CROSS_THROW("OpCompositeInsert spec constant op is not supported."); + { + SmallVector new_init = get_composite_constant_ids(cop.arguments[1]); + uint32_t idx; + uint32_t target_id = cop.self; + uint32_t target_type_id = cop.basetype; + // We have to drill down to the part we want to modify, and create new + // constants for each containing part. + for (idx = 2; idx < cop.arguments.size() - 1; ++idx) + { + uint32_t new_const = ir.increase_bound_by(1); + uint32_t old_const = new_init[cop.arguments[idx]]; + new_init[cop.arguments[idx]] = new_const; + set_composite_constant(target_id, target_type_id, new_init); + new_init = get_composite_constant_ids(old_const); + target_id = new_const; + target_type_id = get_composite_member_type(target_type_id, cop.arguments[idx]); + } + // Now replace the initializer with the one from this instruction. + new_init[cop.arguments[idx]] = cop.arguments[0]; + set_composite_constant(target_id, target_type_id, new_init); + SPIRConstant tmp_const(cop.basetype); + fill_composite_constant(tmp_const, cop.basetype, const_composite_insert_ids[cop.self]); + return constant_expression(tmp_const); + } default: // Some opcodes are unimplemented here, these are currently not possible to test from glslang. @@ -4911,11 +5754,13 @@ string CompilerGLSL::constant_op_expression(const SPIRConstantOp &cop) } } -string CompilerGLSL::constant_expression(const SPIRConstant &c) +string CompilerGLSL::constant_expression(const SPIRConstant &c, + bool inside_block_like_struct_scope, + bool inside_struct_scope) { auto &type = get(c.constant_type); - if (type.pointer) + if (is_pointer(type)) { return backend.null_pointer_literal; } @@ -4924,17 +5769,38 @@ string CompilerGLSL::constant_expression(const SPIRConstant &c) // Handles Arrays and structures. string res; + // Only consider the decay if we are inside a struct scope where we are emitting a member with Offset decoration. + // Outside a block-like struct declaration, we can always bind to a constant array with templated type. + // Should look at ArrayStride here as well, but it's possible to declare a constant struct + // with Offset = 0, using no ArrayStride on the enclosed array type. + // A particular CTS test hits this scenario. + bool array_type_decays = inside_block_like_struct_scope && + is_array(type) && + !backend.array_is_value_type_in_buffer_blocks; + // Allow Metal to use the array template to make arrays a value type bool needs_trailing_tracket = false; if (backend.use_initializer_list && backend.use_typed_initializer_list && type.basetype == SPIRType::Struct && - type.array.empty()) + !is_array(type)) { res = type_to_glsl_constructor(type) + "{ "; } else if (backend.use_initializer_list && backend.use_typed_initializer_list && backend.array_is_value_type && - !type.array.empty()) + is_array(type) && !array_type_decays) { - res = type_to_glsl_constructor(type) + "({ "; + const auto *p_type = &type; + SPIRType tmp_type { OpNop }; + + if (inside_struct_scope && + backend.boolean_in_struct_remapped_type != SPIRType::Boolean && + type.basetype == SPIRType::Boolean) + { + tmp_type = type; + tmp_type.basetype = backend.boolean_in_struct_remapped_type; + p_type = &tmp_type; + } + + res = type_to_glsl_constructor(*p_type) + "({ "; needs_trailing_tracket = true; } else if (backend.use_initializer_list) @@ -4946,16 +5812,43 @@ string CompilerGLSL::constant_expression(const SPIRConstant &c) res = type_to_glsl_constructor(type) + "("; } + uint32_t subconstant_index = 0; for (auto &elem : c.subconstants) { - auto &subc = get(elem); - if (subc.specialization) + if (auto *op = maybe_get(elem)) + { + res += constant_op_expression(*op); + } + else if (maybe_get(elem) != nullptr) + { res += to_name(elem); + } else - res += constant_expression(subc); + { + auto &subc = get(elem); + if (subc.specialization && !expression_is_forwarded(elem)) + res += to_name(elem); + else + { + if (!is_array(type) && type.basetype == SPIRType::Struct) + { + // When we get down to emitting struct members, override the block-like information. + // For constants, we can freely mix and match block-like state. + inside_block_like_struct_scope = + has_member_decoration(type.self, subconstant_index, DecorationOffset); + } + + if (type.basetype == SPIRType::Struct) + inside_struct_scope = true; + + res += constant_expression(subc, inside_block_like_struct_scope, inside_struct_scope); + } + } if (&elem != &c.subconstants.back()) res += ", "; + + subconstant_index++; } res += backend.use_initializer_list ? " }" : ")"; @@ -4970,19 +5863,30 @@ string CompilerGLSL::constant_expression(const SPIRConstant &c) if (backend.supports_empty_struct) return "{ }"; else if (backend.use_typed_initializer_list) - return join(type_to_glsl(get(c.constant_type)), "{ 0 }"); + return join(type_to_glsl(type), "{ 0 }"); else if (backend.use_initializer_list) return "{ 0 }"; else - return join(type_to_glsl(get(c.constant_type)), "(0)"); + return join(type_to_glsl(type), "(0)"); } else if (c.columns() == 1) { - return constant_expression_vector(c, 0); + auto res = constant_expression_vector(c, 0); + + if (inside_struct_scope && + backend.boolean_in_struct_remapped_type != SPIRType::Boolean && + type.basetype == SPIRType::Boolean) + { + SPIRType tmp_type = type; + tmp_type.basetype = backend.boolean_in_struct_remapped_type; + res = join(type_to_glsl(tmp_type), "(", res, ")"); + } + + return res; } else { - string res = type_to_glsl(get(c.constant_type)) + "("; + string res = type_to_glsl(type) + "("; for (uint32_t col = 0; col < c.columns(); col++) { if (c.specialization_constant_id(col) != 0) @@ -4994,13 +5898,23 @@ string CompilerGLSL::constant_expression(const SPIRConstant &c) res += ", "; } res += ")"; + + if (inside_struct_scope && + backend.boolean_in_struct_remapped_type != SPIRType::Boolean && + type.basetype == SPIRType::Boolean) + { + SPIRType tmp_type = type; + tmp_type.basetype = backend.boolean_in_struct_remapped_type; + res = join(type_to_glsl(tmp_type), "(", res, ")"); + } + return res; } } #ifdef _MSC_VER -// sprintf warning. -// We cannot rely on snprintf existing because, ..., MSVC. +// snprintf does not exist or is buggy on older MSVC versions, some of them +// being used by MinGW. Use sprintf instead and disable corresponding warning. #pragma warning(push) #pragma warning(disable : 4996) #endif @@ -5014,7 +5928,7 @@ string CompilerGLSL::convert_half_to_string(const SPIRConstant &c, uint32_t col, // of complicated workarounds, just value-cast to the half type always. if (std::isnan(float_value) || std::isinf(float_value)) { - SPIRType type; + SPIRType type { OpTypeFloat }; type.basetype = SPIRType::Half; type.vecsize = 1; type.columns = 1; @@ -5030,11 +5944,11 @@ string CompilerGLSL::convert_half_to_string(const SPIRConstant &c, uint32_t col, } else { - SPIRType type; + SPIRType type { OpTypeFloat }; type.basetype = SPIRType::Half; type.vecsize = 1; type.columns = 1; - res = join(type_to_glsl(type), "(", convert_to_string(float_value, current_locale_radix_character), ")"); + res = join(type_to_glsl(type), "(", format_float(float_value), ")"); } return res; @@ -5050,8 +5964,8 @@ string CompilerGLSL::convert_float_to_string(const SPIRConstant &c, uint32_t col // Use special representation. if (!is_legacy()) { - SPIRType out_type; - SPIRType in_type; + SPIRType out_type { OpTypeFloat }; + SPIRType in_type { OpTypeInt }; out_type.basetype = SPIRType::Float; in_type.basetype = SPIRType::UInt; out_type.vecsize = 1; @@ -5060,7 +5974,11 @@ string CompilerGLSL::convert_float_to_string(const SPIRConstant &c, uint32_t col in_type.width = 32; char print_buffer[32]; +#ifdef _WIN32 sprintf(print_buffer, "0x%xu", c.scalar(col, row)); +#else + snprintf(print_buffer, sizeof(print_buffer), "0x%xu", c.scalar(col, row)); +#endif const char *comment = "inf"; if (float_value == -numeric_limits::infinity()) @@ -5098,7 +6016,7 @@ string CompilerGLSL::convert_float_to_string(const SPIRConstant &c, uint32_t col } else { - res = convert_to_string(float_value, current_locale_radix_character); + res = format_float(float_value); if (backend.float_literal_suffix) res += "f"; } @@ -5116,8 +6034,8 @@ std::string CompilerGLSL::convert_double_to_string(const SPIRConstant &c, uint32 // Use special representation. if (!is_legacy()) { - SPIRType out_type; - SPIRType in_type; + SPIRType out_type { OpTypeFloat }; + SPIRType in_type { OpTypeInt }; out_type.basetype = SPIRType::Double; in_type.basetype = SPIRType::UInt64; out_type.vecsize = 1; @@ -5127,13 +6045,18 @@ std::string CompilerGLSL::convert_double_to_string(const SPIRConstant &c, uint32 uint64_t u64_value = c.scalar_u64(col, row); - if (options.es) - SPIRV_CROSS_THROW("64-bit integers/float not supported in ES profile."); + if (options.es && options.version < 310) // GL_NV_gpu_shader5 fallback requires 310. + SPIRV_CROSS_THROW("64-bit integers not supported in ES profile before version 310."); require_extension_internal("GL_ARB_gpu_shader_int64"); char print_buffer[64]; +#ifdef _WIN32 sprintf(print_buffer, "0x%llx%s", static_cast(u64_value), backend.long_long_literal_suffix ? "ull" : "ul"); +#else + snprintf(print_buffer, sizeof(print_buffer), "0x%llx%s", static_cast(u64_value), + backend.long_long_literal_suffix ? "ull" : "ul"); +#endif const char *comment = "inf"; if (double_value == -numeric_limits::infinity()) @@ -5176,7 +6099,7 @@ std::string CompilerGLSL::convert_double_to_string(const SPIRConstant &c, uint32 } else { - res = convert_to_string(double_value, current_locale_radix_character); + res = format_double(double_value); if (backend.double_literal_suffix) res += "lf"; } @@ -5266,7 +6189,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t for (uint32_t i = 0; i < c.vector_size(); i++) { if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0) - res += to_name(c.specialization_constant_id(vector, i)); + res += to_expression(c.specialization_constant_id(vector, i)); else res += convert_half_to_string(c, vector, i); @@ -5288,7 +6211,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t for (uint32_t i = 0; i < c.vector_size(); i++) { if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0) - res += to_name(c.specialization_constant_id(vector, i)); + res += to_expression(c.specialization_constant_id(vector, i)); else res += convert_float_to_string(c, vector, i); @@ -5310,7 +6233,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t for (uint32_t i = 0; i < c.vector_size(); i++) { if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0) - res += to_name(c.specialization_constant_id(vector, i)); + res += to_expression(c.specialization_constant_id(vector, i)); else res += convert_double_to_string(c, vector, i); @@ -5336,7 +6259,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t for (uint32_t i = 0; i < c.vector_size(); i++) { if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0) - res += to_name(c.specialization_constant_id(vector, i)); + res += to_expression(c.specialization_constant_id(vector, i)); else res += convert_to_string(c.scalar_i64(vector, i), int64_type, backend.long_long_literal_suffix); @@ -5361,7 +6284,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t for (uint32_t i = 0; i < c.vector_size(); i++) { if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0) - res += to_name(c.specialization_constant_id(vector, i)); + res += to_expression(c.specialization_constant_id(vector, i)); else { res += convert_to_string(c.scalar_u64(vector, i)); @@ -5396,7 +6319,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t for (uint32_t i = 0; i < c.vector_size(); i++) { if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0) - res += to_name(c.specialization_constant_id(vector, i)); + res += to_expression(c.specialization_constant_id(vector, i)); else { res += convert_to_string(c.scalar(vector, i)); @@ -5426,7 +6349,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t for (uint32_t i = 0; i < c.vector_size(); i++) { if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0) - res += to_name(c.specialization_constant_id(vector, i)); + res += to_expression(c.specialization_constant_id(vector, i)); else res += convert_to_string(c.scalar_i32(vector, i)); if (i + 1 < c.vector_size()) @@ -5445,7 +6368,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t for (uint32_t i = 0; i < c.vector_size(); i++) { if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0) - res += to_name(c.specialization_constant_id(vector, i)); + res += to_expression(c.specialization_constant_id(vector, i)); else { if (*backend.uint16_t_literal_suffix) @@ -5479,7 +6402,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t for (uint32_t i = 0; i < c.vector_size(); i++) { if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0) - res += to_name(c.specialization_constant_id(vector, i)); + res += to_expression(c.specialization_constant_id(vector, i)); else { if (*backend.int16_t_literal_suffix) @@ -5513,7 +6436,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t for (uint32_t i = 0; i < c.vector_size(); i++) { if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0) - res += to_name(c.specialization_constant_id(vector, i)); + res += to_expression(c.specialization_constant_id(vector, i)); else { res += type_to_glsl(scalar_type); @@ -5538,7 +6461,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t for (uint32_t i = 0; i < c.vector_size(); i++) { if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0) - res += to_name(c.specialization_constant_id(vector, i)); + res += to_expression(c.specialization_constant_id(vector, i)); else { res += type_to_glsl(scalar_type); @@ -5561,7 +6484,7 @@ string CompilerGLSL::constant_expression_vector(const SPIRConstant &c, uint32_t for (uint32_t i = 0; i < c.vector_size(); i++) { if (c.vector_size() > 1 && c.specialization_constant_id(vector, i) != 0) - res += to_name(c.specialization_constant_id(vector, i)); + res += to_expression(c.specialization_constant_id(vector, i)); else res += c.scalar(vector, i) ? "true" : "false"; @@ -5592,7 +6515,7 @@ void CompilerGLSL::emit_uninitialized_temporary(uint32_t result_type, uint32_t r { // If we're declaring temporaries inside continue blocks, // we must declare the temporary in the loop header so that the continue block can avoid declaring new variables. - if (current_continue_block && !hoisted_temporaries.count(result_id)) + if (!block_temporary_hoisting && current_continue_block && !hoisted_temporaries.count(result_id)) { auto &header = get(current_continue_block->loop_dominator); if (find_if(begin(header.declare_temporary), end(header.declare_temporary), @@ -5608,7 +6531,7 @@ void CompilerGLSL::emit_uninitialized_temporary(uint32_t result_type, uint32_t r else if (hoisted_temporaries.count(result_id) == 0) { auto &type = get(result_type); - auto &flags = ir.meta[result_id].decoration.decoration_flags; + auto &flags = get_decoration_bitset(result_id); // The result_id has not been made into an expression yet, so use flags interface. add_local_variable_name(result_id); @@ -5624,11 +6547,10 @@ void CompilerGLSL::emit_uninitialized_temporary(uint32_t result_type, uint32_t r string CompilerGLSL::declare_temporary(uint32_t result_type, uint32_t result_id) { auto &type = get(result_type); - auto &flags = ir.meta[result_id].decoration.decoration_flags; // If we're declaring temporaries inside continue blocks, // we must declare the temporary in the loop header so that the continue block can avoid declaring new variables. - if (current_continue_block && !hoisted_temporaries.count(result_id)) + if (!block_temporary_hoisting && current_continue_block && !hoisted_temporaries.count(result_id)) { auto &header = get(current_continue_block->loop_dominator); if (find_if(begin(header.declare_temporary), end(header.declare_temporary), @@ -5638,7 +6560,7 @@ string CompilerGLSL::declare_temporary(uint32_t result_type, uint32_t result_id) { header.declare_temporary.emplace_back(result_type, result_id); hoisted_temporaries.insert(result_id); - force_recompile(); + force_recompile_guarantee_forward_progress(); } return join(to_name(result_id), " = "); @@ -5652,6 +6574,7 @@ string CompilerGLSL::declare_temporary(uint32_t result_type, uint32_t result_id) { // The result_id has not been made into an expression yet, so use flags interface. add_local_variable_name(result_id); + auto &flags = get_decoration_bitset(result_id); return join(flags_to_qualifiers_glsl(type, flags), variable_decl(type, to_name(result_id)), " = "); } } @@ -5705,6 +6628,22 @@ void CompilerGLSL::emit_unary_op(uint32_t result_type, uint32_t result_id, uint3 inherit_expression_dependencies(result_id, op0); } +void CompilerGLSL::emit_unary_op_cast(uint32_t result_type, uint32_t result_id, uint32_t op0, const char *op) +{ + auto &type = get(result_type); + bool forward = should_forward(op0); + emit_op(result_type, result_id, join(type_to_glsl(type), "(", op, to_enclosed_unpacked_expression(op0), ")"), forward); + inherit_expression_dependencies(result_id, op0); +} + +void CompilerGLSL::emit_mesh_tasks(SPIRBlock &block) +{ + statement("EmitMeshTasksEXT(", + to_unpacked_expression(block.mesh.groups[0]), ", ", + to_unpacked_expression(block.mesh.groups[1]), ", ", + to_unpacked_expression(block.mesh.groups[2]), ");"); +} + void CompilerGLSL::emit_binary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op) { // Various FP arithmetic opcodes such as add, sub, mul will hit this. @@ -5804,7 +6743,7 @@ SPIRType CompilerGLSL::binary_op_bitcast_helper(string &cast_op0, string &cast_o // Create a fake type so we can bitcast to it. // We only deal with regular arithmetic types here like int, uints and so on. - SPIRType expected_type; + SPIRType expected_type{type0.op}; expected_type.basetype = input_type; expected_type.vecsize = type0.vecsize; expected_type.columns = type0.columns; @@ -5848,7 +6787,9 @@ bool CompilerGLSL::emit_complex_bitcast(uint32_t result_type, uint32_t id, uint3 } void CompilerGLSL::emit_binary_op_cast(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, - const char *op, SPIRType::BaseType input_type, bool skip_cast_if_equal_type) + const char *op, SPIRType::BaseType input_type, + bool skip_cast_if_equal_type, + bool implicit_integer_promotion) { string cast_op0, cast_op1; auto expected_type = binary_op_bitcast_helper(cast_op0, cast_op1, input_type, op0, op1, skip_cast_if_equal_type); @@ -5857,17 +6798,23 @@ void CompilerGLSL::emit_binary_op_cast(uint32_t result_type, uint32_t result_id, // We might have casted away from the result type, so bitcast again. // For example, arithmetic right shift with uint inputs. // Special case boolean outputs since relational opcodes output booleans instead of int/uint. + auto bitop = join(cast_op0, " ", op, " ", cast_op1); string expr; - if (out_type.basetype != input_type && out_type.basetype != SPIRType::Boolean) + + if (implicit_integer_promotion) + { + // Simple value cast. + expr = join(type_to_glsl(out_type), '(', bitop, ')'); + } + else if (out_type.basetype != input_type && out_type.basetype != SPIRType::Boolean) { expected_type.basetype = input_type; - expr = bitcast_glsl_op(out_type, expected_type); - expr += '('; - expr += join(cast_op0, " ", op, " ", cast_op1); - expr += ')'; + expr = join(bitcast_glsl_op(out_type, expected_type), '(', bitop, ')'); } else - expr += join(cast_op0, " ", op, " ", cast_op1); + { + expr = std::move(bitop); + } emit_op(result_type, result_id, expr, should_forward(op0) && should_forward(op1)); inherit_expression_dependencies(result_id, op0); @@ -5884,7 +6831,10 @@ void CompilerGLSL::emit_unary_func_op(uint32_t result_type, uint32_t result_id, void CompilerGLSL::emit_binary_func_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op) { - bool forward = should_forward(op0) && should_forward(op1); + // Opaque types (e.g. OpTypeSampledImage) must always be forwarded in GLSL + const auto &type = get_type(result_type); + bool must_forward = type_is_opaque_value(type); + bool forward = must_forward || (should_forward(op0) && should_forward(op1)); emit_op(result_type, result_id, join(op, "(", to_unpacked_expression(op0), ", ", to_unpacked_expression(op1), ")"), forward); inherit_expression_dependencies(result_id, op0); @@ -5894,6 +6844,16 @@ void CompilerGLSL::emit_binary_func_op(uint32_t result_type, uint32_t result_id, void CompilerGLSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op) { + auto &type = get(result_type); + if (type_is_floating_point(type)) + { + if (!options.vulkan_semantics) + SPIRV_CROSS_THROW("Floating point atomics requires Vulkan semantics."); + if (options.es) + SPIRV_CROSS_THROW("Floating point atomics requires desktop GLSL."); + require_extension_internal("GL_EXT_shader_atomic_float"); + } + forced_temporaries.insert(result_id); emit_op(result_type, result_id, join(op, "(", to_non_uniform_aware_expression(op0), ", ", @@ -6137,7 +7097,9 @@ void CompilerGLSL::emit_bitfield_insert_op(uint32_t result_type, uint32_t result auto op2_expr = to_unpacked_expression(op2); auto op3_expr = to_unpacked_expression(op3); - SPIRType target_type; + assert(offset_count_type == SPIRType::UInt || offset_count_type == SPIRType::Int); + SPIRType target_type { OpTypeInt }; + target_type.width = 32; target_type.vecsize = 1; target_type.basetype = offset_count_type; @@ -6168,7 +7130,11 @@ string CompilerGLSL::legacy_tex_op(const std::string &op, const SPIRType &imgtyp switch (imgtype.image.dim) { case spv::Dim1D: - type = (imgtype.image.arrayed && !options.es) ? "1DArray" : "1D"; + // Force 2D path for ES. + if (options.es) + type = (imgtype.image.arrayed && !options.es) ? "2DArray" : "2D"; + else + type = (imgtype.image.arrayed && !options.es) ? "1DArray" : "1D"; break; case spv::Dim2D: type = (imgtype.image.arrayed && !options.es) ? "2DArray" : "2D"; @@ -6227,6 +7193,9 @@ string CompilerGLSL::legacy_tex_op(const std::string &op, const SPIRType &imgtyp require_extension_internal("GL_EXT_shadow_samplers"); else SPIRV_CROSS_THROW(join(op, " not allowed on depth samplers in legacy ES")); + + if (imgtype.image.dim == spv::DimCube) + return "shadowCubeNV"; } if (op == "textureSize") @@ -6492,7 +7461,7 @@ string CompilerGLSL::to_combined_image_sampler(VariableID image_id, VariableID s } } -bool CompilerGLSL::is_supported_subgroup_op_in_opengl(spv::Op op) +bool CompilerGLSL::is_supported_subgroup_op_in_opengl(spv::Op op, const uint32_t *ops) { switch (op) { @@ -6511,6 +7480,22 @@ bool CompilerGLSL::is_supported_subgroup_op_in_opengl(spv::Op op) case OpGroupNonUniformBallotBitExtract: case OpGroupNonUniformInverseBallot: return true; + case OpGroupNonUniformIAdd: + case OpGroupNonUniformFAdd: + case OpGroupNonUniformIMul: + case OpGroupNonUniformFMul: + { + const GroupOperation operation = static_cast(ops[3]); + if (operation == GroupOperationReduce || operation == GroupOperationInclusiveScan || + operation == GroupOperationExclusiveScan) + { + return true; + } + else + { + return false; + } + } default: return false; } @@ -6835,8 +7820,14 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool sparse, bool args.grad_x = grad_x; args.grad_y = grad_y; args.lod = lod; - args.coffset = coffset; - args.offset = offset; + + if (coffsets) + args.offset = coffsets; + else if (coffset) + args.offset = coffset; + else + args.offset = offset; + args.bias = bias; args.component = comp; args.sample = sample; @@ -6846,8 +7837,8 @@ std::string CompilerGLSL::to_texture_op(const Instruction &i, bool sparse, bool expr += to_function_args(args, forward); expr += ")"; - // texture(samplerXShadow) returns float. shadowX() returns vec4. Swizzle here. - if (is_legacy() && is_depth_image(imgtype, img)) + // texture(samplerXShadow) returns float. shadowX() returns vec4, but only in desktop GLSL. Swizzle here. + if (is_legacy() && !options.es && is_depth_image(imgtype, img)) expr += ".r"; // Sampling from a texture which was deduced to be a depth image, might actually return 1 component here. @@ -6899,7 +7890,7 @@ bool CompilerGLSL::expression_is_constant_null(uint32_t id) const bool CompilerGLSL::expression_is_non_value_type_array(uint32_t ptr) { auto &type = expression_type(ptr); - if (type.array.empty()) + if (!is_array(get_pointee_type(type))) return false; if (!backend.array_is_value_type) @@ -6910,7 +7901,7 @@ bool CompilerGLSL::expression_is_non_value_type_array(uint32_t ptr) return false; auto &backed_type = get(var->basetype); - return !backend.buffer_offset_array_is_value_type && backed_type.basetype == SPIRType::Struct && + return !backend.array_is_value_type_in_buffer_blocks && backed_type.basetype == SPIRType::Struct && has_member_decoration(backed_type.self, 0, DecorationOffset); } @@ -6935,7 +7926,7 @@ string CompilerGLSL::to_function_name(const TextureFunctionNameArguments &args) // This happens for HLSL SampleCmpLevelZero on Texture2DArray and TextureCube. bool workaround_lod_array_shadow_as_grad = false; if (((imgtype.image.arrayed && imgtype.image.dim == Dim2D) || imgtype.image.dim == DimCube) && - is_depth_image(imgtype, tex) && args.lod) + is_depth_image(imgtype, tex) && args.lod && !args.base.is_fetch) { if (!expression_is_constant_null(args.lod)) { @@ -7079,7 +8070,7 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool // This happens for HLSL SampleCmpLevelZero on Texture2DArray and TextureCube. bool workaround_lod_array_shadow_as_grad = ((imgtype.image.arrayed && imgtype.image.dim == Dim2D) || imgtype.image.dim == DimCube) && - is_depth_image(imgtype, img) && args.lod != 0; + is_depth_image(imgtype, img) && args.lod != 0 && !args.base.is_fetch; if (args.dref) { @@ -7128,10 +8119,29 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool // Create a composite which merges coord/dref into a single vector. auto type = expression_type(args.coord); type.vecsize = args.coord_components + 1; + if (imgtype.image.dim == Dim1D && options.es) + type.vecsize++; farg_str += ", "; farg_str += type_to_glsl_constructor(type); farg_str += "("; - farg_str += coord_expr; + + if (imgtype.image.dim == Dim1D && options.es) + { + if (imgtype.image.arrayed) + { + farg_str += enclose_expression(coord_expr) + ".x"; + farg_str += ", 0.0, "; + farg_str += enclose_expression(coord_expr) + ".y"; + } + else + { + farg_str += coord_expr; + farg_str += ", 0.0"; + } + } + else + farg_str += coord_expr; + farg_str += ", "; farg_str += to_expression(args.dref); farg_str += ")"; @@ -7139,6 +8149,33 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool } else { + if (imgtype.image.dim == Dim1D && options.es) + { + // Have to fake a second coordinate. + if (type_is_floating_point(coord_type)) + { + // Cannot mix proj and array. + if (imgtype.image.arrayed || args.base.is_proj) + { + coord_expr = join("vec3(", enclose_expression(coord_expr), ".x, 0.0, ", + enclose_expression(coord_expr), ".y)"); + } + else + coord_expr = join("vec2(", coord_expr, ", 0.0)"); + } + else + { + if (imgtype.image.arrayed) + { + coord_expr = join("ivec3(", enclose_expression(coord_expr), + ".x, 0, ", + enclose_expression(coord_expr), ".y)"); + } + else + coord_expr = join("ivec2(", coord_expr, ", 0)"); + } + } + farg_str += ", "; farg_str += coord_expr; } @@ -7169,18 +8206,11 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool forward = forward && should_forward(args.lod); farg_str += ", "; - auto &lod_expr_type = expression_type(args.lod); - // Lod expression for TexelFetch in GLSL must be int, and only int. - if (args.base.is_fetch && imgtype.image.dim != DimBuffer && !imgtype.image.ms && - lod_expr_type.basetype != SPIRType::Int) - { - farg_str += join("int(", to_expression(args.lod), ")"); - } + if (args.base.is_fetch && imgtype.image.dim != DimBuffer && !imgtype.image.ms) + farg_str += bitcast_expression(SPIRType::Int, args.lod); else - { farg_str += to_expression(args.lod); - } } } else if (args.base.is_fetch && imgtype.image.dim != DimBuffer && !imgtype.image.ms) @@ -7189,23 +8219,17 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool farg_str += ", 0"; } - if (args.coffset) - { - forward = forward && should_forward(args.coffset); - farg_str += ", "; - farg_str += to_expression(args.coffset); - } - else if (args.offset) + if (args.offset) { forward = forward && should_forward(args.offset); farg_str += ", "; - farg_str += to_expression(args.offset); + farg_str += bitcast_expression(SPIRType::Int, args.offset); } if (args.sample) { farg_str += ", "; - farg_str += to_expression(args.sample); + farg_str += bitcast_expression(SPIRType::Int, args.sample); } if (args.min_lod) @@ -7232,11 +8256,7 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool { forward = forward && should_forward(args.component); farg_str += ", "; - auto &component_type = expression_type(args.component); - if (component_type.basetype == SPIRType::Int) - farg_str += to_expression(args.component); - else - farg_str += join("int(", to_expression(args.component), ")"); + farg_str += bitcast_expression(SPIRType::Int, args.component); } *p_forward = forward; @@ -7244,6 +8264,63 @@ string CompilerGLSL::to_function_args(const TextureFunctionArguments &args, bool return farg_str; } +Op CompilerGLSL::get_remapped_spirv_op(Op op) const +{ + if (options.relax_nan_checks) + { + switch (op) + { + case OpFUnordLessThan: + op = OpFOrdLessThan; + break; + case OpFUnordLessThanEqual: + op = OpFOrdLessThanEqual; + break; + case OpFUnordGreaterThan: + op = OpFOrdGreaterThan; + break; + case OpFUnordGreaterThanEqual: + op = OpFOrdGreaterThanEqual; + break; + case OpFUnordEqual: + op = OpFOrdEqual; + break; + case OpFOrdNotEqual: + op = OpFUnordNotEqual; + break; + + default: + break; + } + } + + return op; +} + +GLSLstd450 CompilerGLSL::get_remapped_glsl_op(GLSLstd450 std450_op) const +{ + // Relax to non-NaN aware opcodes. + if (options.relax_nan_checks) + { + switch (std450_op) + { + case GLSLstd450NClamp: + std450_op = GLSLstd450FClamp; + break; + case GLSLstd450NMin: + std450_op = GLSLstd450FMin; + break; + case GLSLstd450NMax: + std450_op = GLSLstd450FMax; + break; + default: + break; + } + } + + return std450_op; +} + void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, const uint32_t *args, uint32_t length) { auto op = static_cast(eop); @@ -7256,6 +8333,8 @@ void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, auto int_type = to_signed_basetype(integer_width); auto uint_type = to_unsigned_basetype(integer_width); + op = get_remapped_glsl_op(op); + switch (op) { // FP fiddling @@ -7287,8 +8366,22 @@ void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, break; case GLSLstd450Trunc: - emit_unary_func_op(result_type, id, args[0], "trunc"); + if (!is_legacy()) + emit_unary_func_op(result_type, id, args[0], "trunc"); + else + { + // Implement by value-casting to int and back. + bool forward = should_forward(args[0]); + auto op0 = to_unpacked_expression(args[0]); + auto &op0_type = expression_type(args[0]); + auto via_type = op0_type; + via_type.basetype = SPIRType::Int; + auto expr = join(type_to_glsl(op0_type), "(", type_to_glsl(via_type), "(", op0, "))"); + emit_op(result_type, id, expr, forward); + inherit_expression_dependencies(id, args[0]); + } break; + case GLSLstd450SAbs: emit_unary_func_op_cast(result_type, id, args[0], "abs", int_type, int_type); break; @@ -7330,18 +8423,47 @@ void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, else emit_trinary_func_op(result_type, id, args[0], args[1], args[2], "fma"); break; + case GLSLstd450Modf: register_call_out_argument(args[1]); - forced_temporaries.insert(id); - emit_binary_func_op(result_type, id, args[0], args[1], "modf"); + if (!is_legacy()) + { + forced_temporaries.insert(id); + emit_binary_func_op(result_type, id, args[0], args[1], "modf"); + } + else + { + //NB. legacy GLSL doesn't have trunc() either, so we do a value cast + auto &op1_type = expression_type(args[1]); + auto via_type = op1_type; + via_type.basetype = SPIRType::Int; + statement(to_expression(args[1]), " = ", + type_to_glsl(op1_type), "(", type_to_glsl(via_type), + "(", to_expression(args[0]), "));"); + emit_binary_op(result_type, id, args[0], args[1], "-"); + } break; case GLSLstd450ModfStruct: { auto &type = get(result_type); emit_uninitialized_temporary_expression(result_type, id); - statement(to_expression(id), ".", to_member_name(type, 0), " = ", "modf(", to_expression(args[0]), ", ", - to_expression(id), ".", to_member_name(type, 1), ");"); + if (!is_legacy()) + { + statement(to_expression(id), ".", to_member_name(type, 0), " = ", "modf(", to_expression(args[0]), ", ", + to_expression(id), ".", to_member_name(type, 1), ");"); + } + else + { + //NB. legacy GLSL doesn't have trunc() either, so we do a value cast + auto &op0_type = expression_type(args[0]); + auto via_type = op0_type; + via_type.basetype = SPIRType::Int; + statement(to_expression(id), ".", to_member_name(type, 1), " = ", type_to_glsl(op0_type), + "(", type_to_glsl(via_type), "(", to_expression(args[0]), "));"); + statement(to_expression(id), ".", to_member_name(type, 0), " = ", to_enclosed_expression(args[0]), " - ", + to_expression(id), ".", to_member_name(type, 1), ";"); + } break; } @@ -7402,22 +8524,77 @@ void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, emit_unary_func_op(result_type, id, args[0], "atan"); break; case GLSLstd450Sinh: - emit_unary_func_op(result_type, id, args[0], "sinh"); + if (!is_legacy()) + emit_unary_func_op(result_type, id, args[0], "sinh"); + else + { + bool forward = should_forward(args[0]); + auto expr = join("(exp(", to_expression(args[0]), ") - exp(-", to_enclosed_expression(args[0]), ")) * 0.5"); + emit_op(result_type, id, expr, forward); + inherit_expression_dependencies(id, args[0]); + } break; case GLSLstd450Cosh: - emit_unary_func_op(result_type, id, args[0], "cosh"); + if (!is_legacy()) + emit_unary_func_op(result_type, id, args[0], "cosh"); + else + { + bool forward = should_forward(args[0]); + auto expr = join("(exp(", to_expression(args[0]), ") + exp(-", to_enclosed_expression(args[0]), ")) * 0.5"); + emit_op(result_type, id, expr, forward); + inherit_expression_dependencies(id, args[0]); + } break; case GLSLstd450Tanh: - emit_unary_func_op(result_type, id, args[0], "tanh"); + if (!is_legacy()) + emit_unary_func_op(result_type, id, args[0], "tanh"); + else + { + // Create temporaries to store the result of exp(arg) and exp(-arg). + uint32_t &ids = extra_sub_expressions[id]; + if (!ids) + { + ids = ir.increase_bound_by(2); + + // Inherit precision qualifier (legacy has no NoContraction). + if (has_decoration(id, DecorationRelaxedPrecision)) + { + set_decoration(ids, DecorationRelaxedPrecision); + set_decoration(ids + 1, DecorationRelaxedPrecision); + } + } + uint32_t epos_id = ids; + uint32_t eneg_id = ids + 1; + + emit_op(result_type, epos_id, join("exp(", to_expression(args[0]), ")"), false); + emit_op(result_type, eneg_id, join("exp(-", to_enclosed_expression(args[0]), ")"), false); + inherit_expression_dependencies(epos_id, args[0]); + inherit_expression_dependencies(eneg_id, args[0]); + + auto expr = join("(", to_enclosed_expression(epos_id), " - ", to_enclosed_expression(eneg_id), ") / " + "(", to_enclosed_expression(epos_id), " + ", to_enclosed_expression(eneg_id), ")"); + emit_op(result_type, id, expr, true); + inherit_expression_dependencies(id, epos_id); + inherit_expression_dependencies(id, eneg_id); + } break; case GLSLstd450Asinh: - emit_unary_func_op(result_type, id, args[0], "asinh"); + if (!is_legacy()) + emit_unary_func_op(result_type, id, args[0], "asinh"); + else + emit_emulated_ahyper_op(result_type, id, args[0], GLSLstd450Asinh); break; case GLSLstd450Acosh: - emit_unary_func_op(result_type, id, args[0], "acosh"); + if (!is_legacy()) + emit_unary_func_op(result_type, id, args[0], "acosh"); + else + emit_emulated_ahyper_op(result_type, id, args[0], GLSLstd450Acosh); break; case GLSLstd450Atanh: - emit_unary_func_op(result_type, id, args[0], "atanh"); + if (!is_legacy()) + emit_unary_func_op(result_type, id, args[0], "atanh"); + else + emit_emulated_ahyper_op(result_type, id, args[0], GLSLstd450Atanh); break; case GLSLstd450Atan2: emit_binary_func_op(result_type, id, args[0], args[1], "atan"); @@ -7448,11 +8625,74 @@ void CompilerGLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, // Matrix math case GLSLstd450Determinant: - emit_unary_func_op(result_type, id, args[0], "determinant"); + { + // No need to transpose - it doesn't affect the determinant + auto *e = maybe_get(args[0]); + bool old_transpose = e && e->need_transpose; + if (old_transpose) + e->need_transpose = false; + + if (options.version < 150) // also matches ES 100 + { + auto &type = expression_type(args[0]); + assert(type.vecsize >= 2 && type.vecsize <= 4); + assert(type.vecsize == type.columns); + + // ARB_gpu_shader_fp64 needs GLSL 150, other types are not valid + if (type.basetype != SPIRType::Float) + SPIRV_CROSS_THROW("Unsupported type for matrix determinant"); + + bool relaxed = has_decoration(id, DecorationRelaxedPrecision); + require_polyfill(static_cast(PolyfillDeterminant2x2 << (type.vecsize - 2)), + relaxed); + emit_unary_func_op(result_type, id, args[0], + (options.es && relaxed) ? "spvDeterminantMP" : "spvDeterminant"); + } + else + emit_unary_func_op(result_type, id, args[0], "determinant"); + + if (old_transpose) + e->need_transpose = true; break; + } + case GLSLstd450MatrixInverse: - emit_unary_func_op(result_type, id, args[0], "inverse"); + { + // The inverse of the transpose is the same as the transpose of + // the inverse, so we can just flip need_transpose of the result. + auto *a = maybe_get(args[0]); + bool old_transpose = a && a->need_transpose; + if (old_transpose) + a->need_transpose = false; + + const char *func = "inverse"; + if (options.version < 140) // also matches ES 100 + { + auto &type = get(result_type); + assert(type.vecsize >= 2 && type.vecsize <= 4); + assert(type.vecsize == type.columns); + + // ARB_gpu_shader_fp64 needs GLSL 150, other types are invalid + if (type.basetype != SPIRType::Float) + SPIRV_CROSS_THROW("Unsupported type for matrix inverse"); + + bool relaxed = has_decoration(id, DecorationRelaxedPrecision); + require_polyfill(static_cast(PolyfillMatrixInverse2x2 << (type.vecsize - 2)), + relaxed); + func = (options.es && relaxed) ? "spvInverseMP" : "spvInverse"; + } + + bool forward = should_forward(args[0]); + auto &e = emit_op(result_type, id, join(func, "(", to_unpacked_expression(args[0]), ")"), forward); + inherit_expression_dependencies(id, args[0]); + + if (old_transpose) + { + e.need_transpose = true; + a->need_transpose = true; + } break; + } // Lerping case GLSLstd450FMix: @@ -7645,13 +8885,60 @@ void CompilerGLSL::emit_nminmax_op(uint32_t result_type, uint32_t id, uint32_t o ir.meta[tmp_id] = ir.meta[id]; ir.meta[mixed_first_id] = ir.meta[id]; - emit_unary_func_op(btype_id, left_nan_id, op0, "isnan"); - emit_unary_func_op(btype_id, right_nan_id, op1, "isnan"); + if (!is_legacy()) + { + emit_unary_func_op(btype_id, left_nan_id, op0, "isnan"); + emit_unary_func_op(btype_id, right_nan_id, op1, "isnan"); + } + else if (expression_type(op0).vecsize > 1) + { + // If the number doesn't equal itself, it must be NaN + emit_binary_func_op(btype_id, left_nan_id, op0, op0, "notEqual"); + emit_binary_func_op(btype_id, right_nan_id, op1, op1, "notEqual"); + } + else + { + emit_binary_op(btype_id, left_nan_id, op0, op0, "!="); + emit_binary_op(btype_id, right_nan_id, op1, op1, "!="); + } emit_binary_func_op(result_type, tmp_id, op0, op1, op == GLSLstd450NMin ? "min" : "max"); emit_mix_op(result_type, mixed_first_id, tmp_id, op1, left_nan_id); emit_mix_op(result_type, id, mixed_first_id, op0, right_nan_id); } +void CompilerGLSL::emit_emulated_ahyper_op(uint32_t result_type, uint32_t id, uint32_t op0, GLSLstd450 op) +{ + const char *one = backend.float_literal_suffix ? "1.0f" : "1.0"; + std::string expr; + bool forward = should_forward(op0); + + switch (op) + { + case GLSLstd450Asinh: + expr = join("log(", to_enclosed_expression(op0), " + sqrt(", + to_enclosed_expression(op0), " * ", to_enclosed_expression(op0), " + ", one, "))"); + emit_op(result_type, id, expr, forward); + break; + + case GLSLstd450Acosh: + expr = join("log(", to_enclosed_expression(op0), " + sqrt(", + to_enclosed_expression(op0), " * ", to_enclosed_expression(op0), " - ", one, "))"); + break; + + case GLSLstd450Atanh: + expr = join("log((", one, " + ", to_enclosed_expression(op0), ") / " + "(", one, " - ", to_enclosed_expression(op0), ")) * 0.5", + backend.float_literal_suffix ? "f" : ""); + break; + + default: + SPIRV_CROSS_THROW("Invalid op."); + } + + emit_op(result_type, id, expr, forward); + inherit_expression_dependencies(id, op0); +} + void CompilerGLSL::emit_spv_amd_shader_ballot_op(uint32_t result_type, uint32_t id, uint32_t eop, const uint32_t *args, uint32_t) { @@ -7806,7 +9093,7 @@ void CompilerGLSL::emit_subgroup_op(const Instruction &i) const uint32_t *ops = stream(i); auto op = static_cast(i.op); - if (!options.vulkan_semantics && !is_supported_subgroup_op_in_opengl(op)) + if (!options.vulkan_semantics && !is_supported_subgroup_op_in_opengl(op, ops)) SPIRV_CROSS_THROW("This subgroup operation is only supported in Vulkan semantics."); // If we need to do implicit bitcasts, make sure we do it with the correct type. @@ -7874,12 +9161,34 @@ void CompilerGLSL::emit_subgroup_op(const Instruction &i) } break; - case OpGroupNonUniformFAdd: - case OpGroupNonUniformFMul: + // clang-format off +#define GLSL_GROUP_OP(OP)\ + case OpGroupNonUniform##OP:\ + {\ + auto operation = static_cast(ops[3]);\ + if (operation == GroupOperationClusteredReduce)\ + require_extension_internal("GL_KHR_shader_subgroup_clustered");\ + else if (operation == GroupOperationReduce)\ + request_subgroup_feature(ShaderSubgroupSupportHelper::SubgroupArithmetic##OP##Reduce);\ + else if (operation == GroupOperationExclusiveScan)\ + request_subgroup_feature(ShaderSubgroupSupportHelper::SubgroupArithmetic##OP##ExclusiveScan);\ + else if (operation == GroupOperationInclusiveScan)\ + request_subgroup_feature(ShaderSubgroupSupportHelper::SubgroupArithmetic##OP##InclusiveScan);\ + else\ + SPIRV_CROSS_THROW("Invalid group operation.");\ + break;\ + } + + GLSL_GROUP_OP(IAdd) + GLSL_GROUP_OP(FAdd) + GLSL_GROUP_OP(IMul) + GLSL_GROUP_OP(FMul) + +#undef GLSL_GROUP_OP + // clang-format on + case OpGroupNonUniformFMin: case OpGroupNonUniformFMax: - case OpGroupNonUniformIAdd: - case OpGroupNonUniformIMul: case OpGroupNonUniformSMin: case OpGroupNonUniformSMax: case OpGroupNonUniformUMin: @@ -8235,9 +9544,17 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) case BuiltInPointSize: return "gl_PointSize"; case BuiltInClipDistance: + { + if (options.es) + require_extension_internal("GL_EXT_clip_cull_distance"); return "gl_ClipDistance"; + } case BuiltInCullDistance: + { + if (options.es) + require_extension_internal("GL_EXT_clip_cull_distance"); return "gl_CullDistance"; + } case BuiltInVertexId: if (options.vulkan_semantics) SPIRV_CROSS_THROW("Cannot implement gl_VertexID in Vulkan GLSL. This shader was created " @@ -8307,6 +9624,8 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) return "gl_TessLevelInner"; case BuiltInTessCoord: return "gl_TessCoord"; + case BuiltInPatchVertices: + return "gl_PatchVerticesIn"; case BuiltInFragCoord: return "gl_FragCoord"; case BuiltInPointCoord: @@ -8382,17 +9701,21 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) return "gl_DrawIDARB"; case BuiltInSampleId: - if (options.es && options.version < 320) + if (is_legacy()) + SPIRV_CROSS_THROW("Sample variables not supported in legacy GLSL."); + else if (options.es && options.version < 320) require_extension_internal("GL_OES_sample_variables"); - if (!options.es && options.version < 400) - SPIRV_CROSS_THROW("gl_SampleID not supported before GLSL 400."); + else if (!options.es && options.version < 400) + require_extension_internal("GL_ARB_sample_shading"); return "gl_SampleID"; case BuiltInSampleMask: - if (options.es && options.version < 320) + if (is_legacy()) + SPIRV_CROSS_THROW("Sample variables not supported in legacy GLSL."); + else if (options.es && options.version < 320) require_extension_internal("GL_OES_sample_variables"); - if (!options.es && options.version < 400) - SPIRV_CROSS_THROW("gl_SampleMask/gl_SampleMaskIn not supported before GLSL 400."); + else if (!options.es && options.version < 400) + require_extension_internal("GL_ARB_sample_shading"); if (storage == StorageClassInput) return "gl_SampleMaskIn"; @@ -8400,10 +9723,12 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) return "gl_SampleMask"; case BuiltInSamplePosition: - if (options.es && options.version < 320) + if (is_legacy()) + SPIRV_CROSS_THROW("Sample variables not supported in legacy GLSL."); + else if (options.es && options.version < 320) require_extension_internal("GL_OES_sample_variables"); - if (!options.es && options.version < 400) - SPIRV_CROSS_THROW("gl_SamplePosition not supported before GLSL 400."); + else if (!options.es && options.version < 400) + require_extension_internal("GL_ARB_sample_shading"); return "gl_SamplePosition"; case BuiltInViewIndex: @@ -8478,24 +9803,42 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) case BuiltInIncomingRayFlagsKHR: return ray_tracing_is_khr ? "gl_IncomingRayFlagsEXT" : "gl_IncomingRayFlagsNV"; - case BuiltInBaryCoordNV: + case BuiltInBaryCoordKHR: { if (options.es && options.version < 320) - SPIRV_CROSS_THROW("gl_BaryCoordNV requires ESSL 320."); + SPIRV_CROSS_THROW("gl_BaryCoordEXT requires ESSL 320."); else if (!options.es && options.version < 450) - SPIRV_CROSS_THROW("gl_BaryCoordNV requires GLSL 450."); - require_extension_internal("GL_NV_fragment_shader_barycentric"); - return "gl_BaryCoordNV"; + SPIRV_CROSS_THROW("gl_BaryCoordEXT requires GLSL 450."); + + if (barycentric_is_nv) + { + require_extension_internal("GL_NV_fragment_shader_barycentric"); + return "gl_BaryCoordNV"; + } + else + { + require_extension_internal("GL_EXT_fragment_shader_barycentric"); + return "gl_BaryCoordEXT"; + } } case BuiltInBaryCoordNoPerspNV: { if (options.es && options.version < 320) - SPIRV_CROSS_THROW("gl_BaryCoordNoPerspNV requires ESSL 320."); + SPIRV_CROSS_THROW("gl_BaryCoordNoPerspEXT requires ESSL 320."); else if (!options.es && options.version < 450) - SPIRV_CROSS_THROW("gl_BaryCoordNoPerspNV requires GLSL 450."); - require_extension_internal("GL_NV_fragment_shader_barycentric"); - return "gl_BaryCoordNoPerspNV"; + SPIRV_CROSS_THROW("gl_BaryCoordNoPerspEXT requires GLSL 450."); + + if (barycentric_is_nv) + { + require_extension_internal("GL_NV_fragment_shader_barycentric"); + return "gl_BaryCoordNoPerspNV"; + } + else + { + require_extension_internal("GL_EXT_fragment_shader_barycentric"); + return "gl_BaryCoordNoPerspEXT"; + } } case BuiltInFragStencilRefEXT: @@ -8538,6 +9881,15 @@ string CompilerGLSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) SPIRV_CROSS_THROW("Need desktop GL to use GL_NV_conservative_raster_underestimation."); return "gl_FragFullyCoveredNV"; + case BuiltInPrimitiveTriangleIndicesEXT: + return "gl_PrimitiveTriangleIndicesEXT"; + case BuiltInPrimitiveLineIndicesEXT: + return "gl_PrimitiveLineIndicesEXT"; + case BuiltInPrimitivePointIndicesEXT: + return "gl_PrimitivePointIndicesEXT"; + case BuiltInCullPrimitiveEXT: + return "gl_CullPrimitiveEXT"; + default: return join("gl_BuiltIn_", convert_to_string(builtin)); } @@ -8561,19 +9913,35 @@ const char *CompilerGLSL::index_to_swizzle(uint32_t index) } void CompilerGLSL::access_chain_internal_append_index(std::string &expr, uint32_t /*base*/, const SPIRType * /*type*/, - AccessChainFlags flags, bool & /*access_chain_is_arrayed*/, + AccessChainFlags flags, bool &access_chain_is_arrayed, uint32_t index) { bool index_is_literal = (flags & ACCESS_CHAIN_INDEX_IS_LITERAL_BIT) != 0; + bool ptr_chain = (flags & ACCESS_CHAIN_PTR_CHAIN_BIT) != 0; bool register_expression_read = (flags & ACCESS_CHAIN_SKIP_REGISTER_EXPRESSION_READ_BIT) == 0; - expr += "["; + string idx_expr = index_is_literal ? convert_to_string(index) : to_unpacked_expression(index, register_expression_read); - if (index_is_literal) - expr += convert_to_string(index); - else - expr += to_unpacked_expression(index, register_expression_read); + // For the case where the base of an OpPtrAccessChain already ends in [n], + // we need to use the index as an offset to the existing index, otherwise, + // we can just use the index directly. + if (ptr_chain && access_chain_is_arrayed) + { + size_t split_pos = expr.find_last_of(']'); + size_t enclose_split = expr.find_last_of(')'); + + // If we have already enclosed the expression, don't try to be clever, it will break. + if (split_pos > enclose_split || enclose_split == string::npos) + { + string expr_front = expr.substr(0, split_pos); + string expr_back = expr.substr(split_pos); + expr = expr_front + " + " + enclose_expression(idx_expr) + expr_back; + return; + } + } + expr += "["; + expr += idx_expr; expr += "]"; } @@ -8609,6 +9977,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice // Start traversing type hierarchy at the proper non-pointer types, // but keep type_id referencing the original pointer for use below. uint32_t type_id = expression_type_id(base); + const auto *type = &get_pointee_type(type_id); if (!backend.native_pointers) { @@ -8618,27 +9987,37 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice // Wrapped buffer reference pointer types will need to poke into the internal "value" member before // continuing the access chain. if (should_dereference(base)) - { - auto &type = get(type_id); - expr = dereference_expression(type, expr); - } + expr = dereference_expression(get(type_id), expr); } - - const auto *type = &get_pointee_type(type_id); + else if (should_dereference(base) && type->basetype != SPIRType::Struct && !ptr_chain) + expr = join("(", dereference_expression(*type, expr), ")"); bool access_chain_is_arrayed = expr.find_first_of('[') != string::npos; bool row_major_matrix_needs_conversion = is_non_native_row_major_matrix(base); bool is_packed = has_extended_decoration(base, SPIRVCrossDecorationPhysicalTypePacked); uint32_t physical_type = get_extended_decoration(base, SPIRVCrossDecorationPhysicalTypeID); bool is_invariant = has_decoration(base, DecorationInvariant); + bool relaxed_precision = has_decoration(base, DecorationRelaxedPrecision); bool pending_array_enclose = false; bool dimension_flatten = false; + bool access_meshlet_position_y = false; + + if (auto *base_expr = maybe_get(base)) + { + access_meshlet_position_y = base_expr->access_meshlet_position_y; + } + + // If we are translating access to a structured buffer, the first subscript '._m0' must be hidden + bool hide_first_subscript = count > 1 && is_user_type_structured(base); - const auto append_index = [&](uint32_t index, bool is_literal) { + const auto append_index = [&](uint32_t index, bool is_literal, bool is_ptr_chain = false) { AccessChainFlags mod_flags = flags; if (!is_literal) mod_flags &= ~ACCESS_CHAIN_INDEX_IS_LITERAL_BIT; + if (!is_ptr_chain) + mod_flags &= ~ACCESS_CHAIN_PTR_CHAIN_BIT; access_chain_internal_append_index(expr, base, type, mod_flags, access_chain_is_arrayed, index); + check_physical_type_cast(expr, type, physical_type); }; for (uint32_t i = 0; i < count; i++) @@ -8652,9 +10031,21 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice index &= 0x7fffffffu; } - // Pointer chains + bool ptr_chain_array_entry = ptr_chain && i == 0 && is_array(*type); + + if (ptr_chain_array_entry) + { + // This is highly unusual code, since normally we'd use plain AccessChain, but it's still allowed. + // We are considered to have a pointer to array and one element shifts by one array at a time. + // If we use normal array indexing, we'll first decay to pointer, and lose the array-ness, + // so we have to take pointer to array explicitly. + if (!should_dereference(base)) + expr = enclose_expression(address_of_expression(expr)); + } + if (ptr_chain && i == 0) { + // Pointer chains // If we are flattening multidimensional arrays, only create opening bracket on first // array index. if (options.flatten_multidimensional_arrays) @@ -8689,7 +10080,7 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice } else { - append_index(index, is_literal); + append_index(index, is_literal, true); } if (type->basetype == SPIRType::ControlPointArray) @@ -8699,6 +10090,12 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice } access_chain_is_arrayed = true; + + // Explicitly enclose the expression if this is one of the weird pointer-to-array cases. + // We don't want any future indexing to add to this array dereference. + // Enclosing the expression blocks that and avoids any shenanigans with operand priority. + if (ptr_chain_array_entry) + expr = join("(", expr, ")"); } // Arrays else if (!type->array.empty()) @@ -8724,14 +10121,25 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice // but HLSL seems to just emit straight arrays here. // We must pretend this access goes through gl_in/gl_out arrays // to be able to access certain builtins as arrays. + // Similar concerns apply for mesh shaders where we have to redirect to gl_MeshVerticesEXT or MeshPrimitivesEXT. auto builtin = ir.meta[base].decoration.builtin_type; + bool mesh_shader = get_execution_model() == ExecutionModelMeshEXT; + switch (builtin) { - // case BuiltInCullDistance: // These are already arrays, need to figure out rules for these in tess/geom. - // case BuiltInClipDistance: + case BuiltInCullDistance: + case BuiltInClipDistance: + if (type->array.size() == 1) // Red herring. Only consider block IO for two-dimensional arrays here. + { + append_index(index, is_literal); + break; + } + // fallthrough case BuiltInPosition: case BuiltInPointSize: - if (var->storage == StorageClassInput) + if (mesh_shader) + expr = join("gl_MeshVerticesEXT[", to_expression(index, register_expression_read), "].", expr); + else if (var->storage == StorageClassInput) expr = join("gl_in[", to_expression(index, register_expression_read), "].", expr); else if (var->storage == StorageClassOutput) expr = join("gl_out[", to_expression(index, register_expression_read), "].", expr); @@ -8739,11 +10147,30 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice append_index(index, is_literal); break; + case BuiltInPrimitiveId: + case BuiltInLayer: + case BuiltInViewportIndex: + case BuiltInCullPrimitiveEXT: + case BuiltInPrimitiveShadingRateKHR: + if (mesh_shader) + expr = join("gl_MeshPrimitivesEXT[", to_expression(index, register_expression_read), "].", expr); + else + append_index(index, is_literal); + break; + default: append_index(index, is_literal); break; } } + else if (backend.force_merged_mesh_block && i == 0 && var && + !is_builtin_variable(*var) && var->storage == StorageClassOutput) + { + if (is_per_primitive_variable(*var)) + expr = join("gl_MeshPrimitivesEXT[", to_expression(index, register_expression_read), "].", expr); + else + expr = join("gl_MeshVerticesEXT[", to_expression(index, register_expression_read), "].", expr); + } else if (options.flatten_multidimensional_arrays && dimension_flatten) { // If we are flattening multidimensional arrays, do manual stride computation. @@ -8768,16 +10195,34 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice if (!pending_array_enclose) expr += "]"; } - // Some builtins are arrays in SPIR-V but not in other languages, e.g. gl_SampleMask[] is an array in SPIR-V but not in Metal. - // By throwing away the index, we imply the index was 0, which it must be for gl_SampleMask. - else if (!builtin_translates_to_nonarray(BuiltIn(get_decoration(base, DecorationBuiltIn)))) + else if (index_is_literal || !builtin_translates_to_nonarray(BuiltIn(get_decoration(base, DecorationBuiltIn)))) { + // Some builtins are arrays in SPIR-V but not in other languages, e.g. gl_SampleMask[] is an array in SPIR-V but not in Metal. + // By throwing away the index, we imply the index was 0, which it must be for gl_SampleMask. + // For literal indices we are working on composites, so we ignore this since we have already converted to proper array. append_index(index, is_literal); } + if (var && has_decoration(var->self, DecorationBuiltIn) && + get_decoration(var->self, DecorationBuiltIn) == BuiltInPosition && + get_execution_model() == ExecutionModelMeshEXT) + { + access_meshlet_position_y = true; + } + type_id = type->parent_type; type = &get(type_id); + // If the physical type has an unnatural vecsize, + // we must assume it's a faked struct where the .data member + // is used for the real payload. + if (physical_type && (is_vector(*type) || is_scalar(*type))) + { + auto &phys = get(physical_type); + if (phys.vecsize > 4) + expr += ".data"; + } + access_chain_is_arrayed = true; } // For structs, the index refers to a constant, which indexes into the members, possibly through a redirection mapping. @@ -8793,31 +10238,52 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice if (index >= type->member_types.size()) SPIRV_CROSS_THROW("Member index is out of bounds!"); - BuiltIn builtin; - if (is_member_builtin(*type, index, &builtin) && access_chain_needs_stage_io_builtin_translation(base)) + if (hide_first_subscript) { - if (access_chain_is_arrayed) - { - expr += "."; - expr += builtin_to_glsl(builtin, type->storage); - } - else - expr = builtin_to_glsl(builtin, type->storage); + // First "._m0" subscript has been hidden, subsequent fields must be emitted even for structured buffers + hide_first_subscript = false; } else { - // If the member has a qualified name, use it as the entire chain - string qual_mbr_name = get_member_qualified_name(type_id, index); - if (!qual_mbr_name.empty()) - expr = qual_mbr_name; - else if (flatten_member_reference) - expr += join("_", to_member_name(*type, index)); + BuiltIn builtin = BuiltInMax; + if (is_member_builtin(*type, index, &builtin) && access_chain_needs_stage_io_builtin_translation(base)) + { + if (access_chain_is_arrayed) + { + expr += "."; + expr += builtin_to_glsl(builtin, type->storage); + } + else + expr = builtin_to_glsl(builtin, type->storage); + + if (builtin == BuiltInPosition && get_execution_model() == ExecutionModelMeshEXT) + { + access_meshlet_position_y = true; + } + } else - expr += to_member_reference(base, *type, index, ptr_chain); + { + // If the member has a qualified name, use it as the entire chain + string qual_mbr_name = get_member_qualified_name(type_id, index); + if (!qual_mbr_name.empty()) + expr = qual_mbr_name; + else if (flatten_member_reference) + expr += join("_", to_member_name(*type, index)); + else + { + // Any pointer de-refences for values are handled in the first access chain. + // For pointer chains, the pointer-ness is resolved through an array access. + // The only time this is not true is when accessing array of SSBO/UBO. + // This case is explicitly handled. + expr += to_member_reference(base, *type, index, ptr_chain || i != 0); + } + } } if (has_member_decoration(type->self, index, DecorationInvariant)) is_invariant = true; + if (has_member_decoration(type->self, index, DecorationRelaxedPrecision)) + relaxed_precision = true; is_packed = member_is_packed_physical_type(*type, index); if (member_is_remapped_physical_type(*type, index)) @@ -8842,6 +10308,16 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice expr += to_unpacked_expression(index, register_expression_read); expr += "]"; + // If the physical type has an unnatural vecsize, + // we must assume it's a faked struct where the .data member + // is used for the real payload. + if (physical_type) + { + auto &phys = get(physical_type); + if (phys.vecsize > 4 || phys.columns > 4) + expr += ".data"; + } + type_id = type->parent_type; type = &get(type_id); } @@ -8856,6 +10332,18 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice if (column_index != string::npos) { deferred_index = expr.substr(column_index); + + auto end_deferred_index = deferred_index.find_last_of(']'); + if (end_deferred_index != string::npos && end_deferred_index + 1 != deferred_index.size()) + { + // If we have any data member fixups, it must be transposed so that it refers to this index. + // E.g. [0].data followed by [1] would be shuffled to [1][0].data which is wrong, + // and needs to be [1].data[0] instead. + end_deferred_index++; + deferred_index = deferred_index.substr(end_deferred_index) + + deferred_index.substr(0, end_deferred_index); + } + expr.resize(column_index); } } @@ -8894,30 +10382,37 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice is_packed); } - if (is_literal && !is_packed && !row_major_matrix_needs_conversion) + if (is_literal) { - expr += "."; - expr += index_to_swizzle(index); + bool out_of_bounds = (index >= type->vecsize); + + if (!is_packed && !row_major_matrix_needs_conversion) + { + expr += "."; + expr += index_to_swizzle(out_of_bounds ? 0 : index); + } + else + { + // For packed vectors, we can only access them as an array, not by swizzle. + expr += join("[", out_of_bounds ? 0 : index, "]"); + } } else if (ir.ids[index].get_type() == TypeConstant && !is_packed && !row_major_matrix_needs_conversion) { auto &c = get(index); + bool out_of_bounds = (c.scalar() >= type->vecsize); + if (c.specialization) { // If the index is a spec constant, we cannot turn extract into a swizzle. - expr += join("[", to_expression(index), "]"); + expr += join("[", out_of_bounds ? "0" : to_expression(index), "]"); } else { expr += "."; - expr += index_to_swizzle(c.scalar()); + expr += index_to_swizzle(out_of_bounds ? 0 : c.scalar()); } } - else if (is_literal) - { - // For packed vectors, we can only access them as an array, not by swizzle. - expr += join("[", index, "]"); - } else { expr += "["; @@ -8927,8 +10422,34 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice if (row_major_matrix_needs_conversion && !ignore_potential_sliced_writes) { - prepare_access_chain_for_scalar_access(expr, get(type->parent_type), effective_storage, - is_packed); + if (prepare_access_chain_for_scalar_access(expr, get(type->parent_type), effective_storage, + is_packed)) + { + // We're in a pointer context now, so just remove any member dereference. + auto first_index = deferred_index.find_first_of('['); + if (first_index != string::npos && first_index != 0) + deferred_index = deferred_index.substr(first_index); + } + } + + if (access_meshlet_position_y) + { + if (is_literal) + { + access_meshlet_position_y = index == 1; + } + else + { + const auto *c = maybe_get(index); + if (c) + access_meshlet_position_y = c->scalar() == 1; + else + { + // We don't know, but we have to assume no. + // Flip Y in mesh shaders is an opt-in horrible hack, so we'll have to assume shaders try to behave. + access_meshlet_position_y = false; + } + } } expr += deferred_index; @@ -8956,15 +10477,22 @@ string CompilerGLSL::access_chain_internal(uint32_t base, const uint32_t *indice meta->storage_is_packed = is_packed; meta->storage_is_invariant = is_invariant; meta->storage_physical_type = physical_type; + meta->relaxed_precision = relaxed_precision; + meta->access_meshlet_position_y = access_meshlet_position_y; } return expr; } -void CompilerGLSL::prepare_access_chain_for_scalar_access(std::string &, const SPIRType &, spv::StorageClass, bool &) +void CompilerGLSL::check_physical_type_cast(std::string &, const SPIRType *, uint32_t) { } +bool CompilerGLSL::prepare_access_chain_for_scalar_access(std::string &, const SPIRType &, spv::StorageClass, bool &) +{ + return false; +} + string CompilerGLSL::to_flattened_struct_member(const string &basename, const SPIRType &type, uint32_t index) { auto ret = join(basename, "_", to_member_name(type, index)); @@ -9114,8 +10642,13 @@ std::string CompilerGLSL::flattened_access_chain_struct(uint32_t base, const uin { std::string expr; - expr += type_to_glsl_constructor(target_type); - expr += "("; + if (backend.can_declare_struct_inline) + { + expr += type_to_glsl_constructor(target_type); + expr += "("; + } + else + expr += "{"; for (uint32_t i = 0; i < uint32_t(target_type.member_types.size()); ++i) { @@ -9128,10 +10661,13 @@ std::string CompilerGLSL::flattened_access_chain_struct(uint32_t base, const uin // The access chain terminates at the struct, so we need to find matrix strides and row-major information // ahead of time. bool need_transpose = false; + bool relaxed = false; uint32_t matrix_stride = 0; if (member_type.columns > 1) { - need_transpose = combined_decoration_for_member(target_type, i).get(DecorationRowMajor); + auto decorations = combined_decoration_for_member(target_type, i); + need_transpose = decorations.get(DecorationRowMajor); + relaxed = decorations.get(DecorationRelaxedPrecision); matrix_stride = type_struct_member_matrix_stride(target_type, i); } @@ -9140,12 +10676,12 @@ std::string CompilerGLSL::flattened_access_chain_struct(uint32_t base, const uin // Cannot forward transpositions, so resolve them here. if (need_transpose) - expr += convert_row_major_matrix(tmp, member_type, 0, false); + expr += convert_row_major_matrix(tmp, member_type, 0, false, relaxed); else expr += tmp; } - expr += ")"; + expr += backend.can_declare_struct_inline ? ")" : "}"; return expr; } @@ -9437,9 +10973,32 @@ bool CompilerGLSL::should_dereference(uint32_t id) if (auto *var = maybe_get(id)) return var->phi_variable; - // If id is an access chain, we should not dereference it. if (auto *expr = maybe_get(id)) - return !expr->access_chain; + { + // If id is an access chain, we should not dereference it. + if (expr->access_chain) + return false; + + // If id is a forwarded copy of a variable pointer, we should not dereference it. + SPIRVariable *var = nullptr; + while (expr->loaded_from && expression_is_forwarded(expr->self)) + { + auto &src_type = expression_type(expr->loaded_from); + // To be a copy, the pointer and its source expression must be the + // same type. Can't check type.self, because for some reason that's + // usually the base type with pointers stripped off. This check is + // complex enough that I've hoisted it out of the while condition. + if (src_type.pointer != type.pointer || src_type.pointer_depth != type.pointer_depth || + src_type.parent_type != type.parent_type) + break; + if ((var = maybe_get(expr->loaded_from))) + break; + if (!(expr = maybe_get(expr->loaded_from))) + break; + } + + return !var || var->phi_variable; + } // Otherwise, we should dereference this pointer expression. return true; @@ -9449,14 +11008,33 @@ bool CompilerGLSL::should_forward(uint32_t id) const { // If id is a variable we will try to forward it regardless of force_temporary check below // This is important because otherwise we'll get local sampler copies (highp sampler2D foo = bar) that are invalid in OpenGL GLSL + auto *var = maybe_get(id); - if (var && var->forwardable) - return true; + if (var) + { + // Never forward volatile builtin variables, e.g. SPIR-V 1.6 HelperInvocation. + return !(has_decoration(id, DecorationBuiltIn) && has_decoration(id, DecorationVolatile)); + } // For debugging emit temporary variables for all expressions if (options.force_temporary) return false; + // If an expression carries enough dependencies we need to stop forwarding at some point, + // or we explode compilers. There are usually limits to how much we can nest expressions. + auto *expr = maybe_get(id); + const uint32_t max_expression_dependencies = 64; + if (expr && expr->expression_dependencies.size() >= max_expression_dependencies) + return false; + + if (expr && expr->loaded_from + && has_decoration(expr->loaded_from, DecorationBuiltIn) + && has_decoration(expr->loaded_from, DecorationVolatile)) + { + // Never forward volatile builtin variables, e.g. SPIR-V 1.6 HelperInvocation. + return false; + } + // Immutable expression can always be forwarded. if (is_immutable(id)) return true; @@ -9513,9 +11091,8 @@ void CompilerGLSL::track_expression_read(uint32_t id) //if (v == 2) // fprintf(stderr, "ID %u was forced to temporary due to more than 1 expression use!\n", id); - forced_temporaries.insert(id); // Force a recompile after this pass to avoid forwarding this variable. - force_recompile(); + force_temporary_and_recompile(id); } } } @@ -9776,7 +11353,7 @@ string CompilerGLSL::build_composite_combiner(uint32_t return_type, const uint32 bool uses_buffer_offset = type.basetype == SPIRType::Struct && has_member_decoration(type.self, i, DecorationOffset); - subop = to_composite_constructor_expression(elems[i], uses_buffer_offset); + subop = to_composite_constructor_expression(type, elems[i], uses_buffer_offset); } base = e ? e->base_expression : ID(0); @@ -9835,6 +11412,12 @@ bool CompilerGLSL::optimize_read_modify_write(const SPIRType &type, const string char bop = rhs[op]; auto expr = rhs.substr(lhs.size() + 3); + + // Avoids false positives where we get a = a * b + c. + // Normally, these expressions are always enclosed, but unexpected code paths may end up hitting this. + if (needs_enclose_expression(expr)) + return false; + // Try to find increments and decrements. Makes it look neater as += 1, -= 1 is fairly rare to see in real code. // Find some common patterns which are equivalent. if ((bop == '+' || bop == '-') && (expr == "1" || expr == "uint(1)" || expr == "1u" || expr == "int(1u)")) @@ -9856,8 +11439,58 @@ void CompilerGLSL::register_control_dependent_expression(uint32_t expr) void CompilerGLSL::emit_block_instructions(SPIRBlock &block) { current_emitting_block = █ + + if (backend.requires_relaxed_precision_analysis) + { + // If PHI variables are consumed in unexpected precision contexts, copy them here. + for (size_t i = 0, n = block.phi_variables.size(); i < n; i++) + { + auto &phi = block.phi_variables[i]; + + // Ensure we only copy once. We know a-priori that this array will lay out + // the same function variables together. + if (i && block.phi_variables[i - 1].function_variable == phi.function_variable) + continue; + + auto itr = temporary_to_mirror_precision_alias.find(phi.function_variable); + if (itr != temporary_to_mirror_precision_alias.end()) + { + // Explicitly, we don't want to inherit RelaxedPrecision state in this CopyObject, + // so it helps to have handle_instruction_precision() on the outside of emit_instruction(). + EmbeddedInstruction inst; + inst.op = OpCopyObject; + inst.length = 3; + inst.ops.push_back(expression_type_id(itr->first)); + inst.ops.push_back(itr->second); + inst.ops.push_back(itr->first); + emit_instruction(inst); + } + } + } + for (auto &op : block.ops) + { + auto temporary_copy = handle_instruction_precision(op); emit_instruction(op); + if (temporary_copy.dst_id) + { + // Explicitly, we don't want to inherit RelaxedPrecision state in this CopyObject, + // so it helps to have handle_instruction_precision() on the outside of emit_instruction(). + EmbeddedInstruction inst; + inst.op = OpCopyObject; + inst.length = 3; + inst.ops.push_back(expression_type_id(temporary_copy.src_id)); + inst.ops.push_back(temporary_copy.dst_id); + inst.ops.push_back(temporary_copy.src_id); + + // Never attempt to hoist mirrored temporaries. + // They are hoisted in lock-step with their parents. + block_temporary_hoisting = true; + emit_instruction(inst); + block_temporary_hoisting = false; + } + } + current_emitting_block = nullptr; } @@ -9869,9 +11502,8 @@ void CompilerGLSL::disallow_forwarding_in_expression_chain(const SPIRExpression if (expression_is_forwarded(expr.self) && !expression_suppresses_usage_tracking(expr.self) && forced_invariant_temporaries.count(expr.self) == 0) { - forced_temporaries.insert(expr.self); + force_temporary_and_recompile(expr.self); forced_invariant_temporaries.insert(expr.self); - force_recompile(); for (auto &dependent : expr.expression_dependencies) disallow_forwarding_in_expression_chain(get(dependent)); @@ -9922,72 +11554,301 @@ void CompilerGLSL::emit_store_statement(uint32_t lhs_expression, uint32_t rhs_ex if (!optimize_read_modify_write(expression_type(rhs_expression), lhs, rhs)) statement(lhs, " = ", rhs, ";"); } - register_write(lhs_expression); + register_write(lhs_expression); + } +} + +uint32_t CompilerGLSL::get_integer_width_for_instruction(const Instruction &instr) const +{ + if (instr.length < 3) + return 32; + + auto *ops = stream(instr); + + switch (instr.op) + { + case OpSConvert: + case OpConvertSToF: + case OpUConvert: + case OpConvertUToF: + case OpIEqual: + case OpINotEqual: + case OpSLessThan: + case OpSLessThanEqual: + case OpSGreaterThan: + case OpSGreaterThanEqual: + case OpULessThan: + case OpULessThanEqual: + case OpUGreaterThan: + case OpUGreaterThanEqual: + return expression_type(ops[2]).width; + + default: + { + // We can look at result type which is more robust. + auto *type = maybe_get(ops[0]); + if (type && type_is_integral(*type)) + return type->width; + else + return 32; + } + } +} + +uint32_t CompilerGLSL::get_integer_width_for_glsl_instruction(GLSLstd450 op, const uint32_t *ops, uint32_t length) const +{ + if (length < 1) + return 32; + + switch (op) + { + case GLSLstd450SAbs: + case GLSLstd450SSign: + case GLSLstd450UMin: + case GLSLstd450SMin: + case GLSLstd450UMax: + case GLSLstd450SMax: + case GLSLstd450UClamp: + case GLSLstd450SClamp: + case GLSLstd450FindSMsb: + case GLSLstd450FindUMsb: + return expression_type(ops[0]).width; + + default: + { + // We don't need to care about other opcodes, just return 32. + return 32; + } + } +} + +void CompilerGLSL::forward_relaxed_precision(uint32_t dst_id, const uint32_t *args, uint32_t length) +{ + // Only GLSL supports RelaxedPrecision directly. + // We cannot implement this in HLSL or MSL because it is tied to the type system. + // In SPIR-V, everything must masquerade as 32-bit. + if (!backend.requires_relaxed_precision_analysis) + return; + + auto input_precision = analyze_expression_precision(args, length); + + // For expressions which are loaded or directly forwarded, we inherit mediump implicitly. + // For dst_id to be analyzed properly, it must inherit any relaxed precision decoration from src_id. + if (input_precision == Options::Mediump) + set_decoration(dst_id, DecorationRelaxedPrecision); +} + +CompilerGLSL::Options::Precision CompilerGLSL::analyze_expression_precision(const uint32_t *args, uint32_t length) const +{ + // Now, analyze the precision at which the arguments would run. + // GLSL rules are such that the precision used to evaluate an expression is equal to the highest precision + // for the inputs. Constants do not have inherent precision and do not contribute to this decision. + // If all inputs are constants, they inherit precision from outer expressions, including an l-value. + // In this case, we'll have to force a temporary for dst_id so that we can bind the constant expression with + // correct precision. + bool expression_has_highp = false; + bool expression_has_mediump = false; + + for (uint32_t i = 0; i < length; i++) + { + uint32_t arg = args[i]; + + auto handle_type = ir.ids[arg].get_type(); + if (handle_type == TypeConstant || handle_type == TypeConstantOp || handle_type == TypeUndef) + continue; + + if (has_decoration(arg, DecorationRelaxedPrecision)) + expression_has_mediump = true; + else + expression_has_highp = true; + } + + if (expression_has_highp) + return Options::Highp; + else if (expression_has_mediump) + return Options::Mediump; + else + return Options::DontCare; +} + +void CompilerGLSL::analyze_precision_requirements(uint32_t type_id, uint32_t dst_id, uint32_t *args, uint32_t length) +{ + if (!backend.requires_relaxed_precision_analysis) + return; + + auto &type = get(type_id); + + // RelaxedPrecision only applies to 32-bit values. + if (type.basetype != SPIRType::Float && type.basetype != SPIRType::Int && type.basetype != SPIRType::UInt) + return; + + bool operation_is_highp = !has_decoration(dst_id, DecorationRelaxedPrecision); + + auto input_precision = analyze_expression_precision(args, length); + if (input_precision == Options::DontCare) + { + consume_temporary_in_precision_context(type_id, dst_id, input_precision); + return; + } + + // In SPIR-V and GLSL, the semantics are flipped for how relaxed precision is determined. + // In SPIR-V, the operation itself marks RelaxedPrecision, meaning that inputs can be truncated to 16-bit. + // However, if the expression is not, inputs must be expanded to 32-bit first, + // since the operation must run at high precision. + // This is the awkward part, because if we have mediump inputs, or expressions which derived from mediump, + // we might have to forcefully bind the source IDs to highp temporaries. This is done by clearing decorations + // and forcing temporaries. Similarly for mediump operations. We bind highp expressions to mediump variables. + if ((operation_is_highp && input_precision == Options::Mediump) || + (!operation_is_highp && input_precision == Options::Highp)) + { + auto precision = operation_is_highp ? Options::Highp : Options::Mediump; + for (uint32_t i = 0; i < length; i++) + { + // Rewrites the opcode so that we consume an ID in correct precision context. + // This is pretty hacky, but it's the most straight forward way of implementing this without adding + // lots of extra passes to rewrite all code blocks. + args[i] = consume_temporary_in_precision_context(expression_type_id(args[i]), args[i], precision); + } } } -uint32_t CompilerGLSL::get_integer_width_for_instruction(const Instruction &instr) const +// This is probably not exhaustive ... +static bool opcode_is_precision_sensitive_operation(Op op) { - if (instr.length < 3) - return 32; - - auto *ops = stream(instr); - - switch (instr.op) + switch (op) { + case OpFAdd: + case OpFSub: + case OpFMul: + case OpFNegate: + case OpIAdd: + case OpISub: + case OpIMul: + case OpSNegate: + case OpFMod: + case OpFDiv: + case OpFRem: + case OpSMod: + case OpSDiv: + case OpSRem: + case OpUMod: + case OpUDiv: + case OpVectorTimesMatrix: + case OpMatrixTimesVector: + case OpMatrixTimesMatrix: + case OpDPdx: + case OpDPdy: + case OpDPdxCoarse: + case OpDPdyCoarse: + case OpDPdxFine: + case OpDPdyFine: + case OpFwidth: + case OpFwidthCoarse: + case OpFwidthFine: + case OpVectorTimesScalar: + case OpMatrixTimesScalar: + case OpOuterProduct: + case OpFConvert: case OpSConvert: - case OpConvertSToF: case OpUConvert: + case OpConvertSToF: case OpConvertUToF: - case OpIEqual: - case OpINotEqual: - case OpSLessThan: - case OpSLessThanEqual: - case OpSGreaterThan: - case OpSGreaterThanEqual: - case OpULessThan: - case OpULessThanEqual: - case OpUGreaterThan: - case OpUGreaterThanEqual: - return expression_type(ops[2]).width; + case OpConvertFToU: + case OpConvertFToS: + return true; default: - { - // We can look at result type which is more robust. - auto *type = maybe_get(ops[0]); - if (type && type_is_integral(*type)) - return type->width; - else - return 32; - } + return false; } } -uint32_t CompilerGLSL::get_integer_width_for_glsl_instruction(GLSLstd450 op, const uint32_t *ops, uint32_t length) const +// Instructions which just load data but don't do any arithmetic operation should just inherit the decoration. +// SPIR-V doesn't require this, but it's somewhat implied it has to work this way, relaxed precision is only +// relevant when operating on the IDs, not when shuffling things around. +static bool opcode_is_precision_forwarding_instruction(Op op, uint32_t &arg_count) { - if (length < 1) - return 32; - switch (op) { - case GLSLstd450SAbs: - case GLSLstd450SSign: - case GLSLstd450UMin: - case GLSLstd450SMin: - case GLSLstd450UMax: - case GLSLstd450SMax: - case GLSLstd450UClamp: - case GLSLstd450SClamp: - case GLSLstd450FindSMsb: - case GLSLstd450FindUMsb: - return expression_type(ops[0]).width; + case OpLoad: + case OpAccessChain: + case OpInBoundsAccessChain: + case OpCompositeExtract: + case OpVectorExtractDynamic: + case OpSampledImage: + case OpImage: + case OpCopyObject: + + case OpImageRead: + case OpImageFetch: + case OpImageSampleImplicitLod: + case OpImageSampleProjImplicitLod: + case OpImageSampleDrefImplicitLod: + case OpImageSampleProjDrefImplicitLod: + case OpImageSampleExplicitLod: + case OpImageSampleProjExplicitLod: + case OpImageSampleDrefExplicitLod: + case OpImageSampleProjDrefExplicitLod: + case OpImageGather: + case OpImageDrefGather: + case OpImageSparseRead: + case OpImageSparseFetch: + case OpImageSparseSampleImplicitLod: + case OpImageSparseSampleProjImplicitLod: + case OpImageSparseSampleDrefImplicitLod: + case OpImageSparseSampleProjDrefImplicitLod: + case OpImageSparseSampleExplicitLod: + case OpImageSparseSampleProjExplicitLod: + case OpImageSparseSampleDrefExplicitLod: + case OpImageSparseSampleProjDrefExplicitLod: + case OpImageSparseGather: + case OpImageSparseDrefGather: + arg_count = 1; + return true; + + case OpVectorShuffle: + arg_count = 2; + return true; + + case OpCompositeConstruct: + return true; default: - { - // We don't need to care about other opcodes, just return 32. - return 32; + break; } + + return false; +} + +CompilerGLSL::TemporaryCopy CompilerGLSL::handle_instruction_precision(const Instruction &instruction) +{ + auto ops = stream_mutable(instruction); + auto opcode = static_cast(instruction.op); + uint32_t length = instruction.length; + + if (backend.requires_relaxed_precision_analysis) + { + if (length > 2) + { + uint32_t forwarding_length = length - 2; + + if (opcode_is_precision_sensitive_operation(opcode)) + analyze_precision_requirements(ops[0], ops[1], &ops[2], forwarding_length); + else if (opcode == OpExtInst && length >= 5 && get(ops[2]).ext == SPIRExtension::GLSL) + analyze_precision_requirements(ops[0], ops[1], &ops[4], forwarding_length - 2); + else if (opcode_is_precision_forwarding_instruction(opcode, forwarding_length)) + forward_relaxed_precision(ops[1], &ops[2], forwarding_length); + } + + uint32_t result_type = 0, result_id = 0; + if (instruction_to_result_type(result_type, result_id, opcode, ops, length)) + { + auto itr = temporary_to_mirror_precision_alias.find(ops[1]); + if (itr != temporary_to_mirror_precision_alias.end()) + return { itr->second, itr->first }; + } } + + return {}; } void CompilerGLSL::emit_instruction(const Instruction &instruction) @@ -9998,8 +11859,10 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) #define GLSL_BOP(op) emit_binary_op(ops[0], ops[1], ops[2], ops[3], #op) #define GLSL_BOP_CAST(op, type) \ - emit_binary_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, opcode_is_sign_invariant(opcode)) + emit_binary_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, \ + opcode_is_sign_invariant(opcode), implicit_integer_promotion) #define GLSL_UOP(op) emit_unary_op(ops[0], ops[1], ops[2], #op) +#define GLSL_UOP_CAST(op) emit_unary_op_cast(ops[0], ops[1], ops[2], #op) #define GLSL_QFOP(op) emit_quaternary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], ops[5], #op) #define GLSL_TFOP(op) emit_trinary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], #op) #define GLSL_BFOP(op) emit_binary_func_op(ops[0], ops[1], ops[2], ops[3], #op) @@ -10013,6 +11876,15 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) auto int_type = to_signed_basetype(integer_width); auto uint_type = to_unsigned_basetype(integer_width); + // Handle C implicit integer promotion rules. + // If we get implicit promotion to int, need to make sure we cast by value to intended return type, + // otherwise, future sign-dependent operations and bitcasts will break. + bool implicit_integer_promotion = integer_width < 32 && backend.implicit_c_integer_promotion_rules && + opcode_can_promote_integer_implicitly(opcode) && + get(ops[0]).vecsize == 1; + + opcode = get_remapped_spirv_op(opcode); + switch (opcode) { // Dealing with memory @@ -10077,9 +11949,15 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) if (expr_type.vecsize > type.vecsize) expr = enclose_expression(expr + vector_swizzle(type.vecsize, 0)); + if (forward && ptr_expression) + ptr_expression->need_transpose = old_need_transpose; + // We might need to cast in order to load from a builtin. cast_from_variable_load(ptr, expr, type); + if (forward && ptr_expression) + ptr_expression->need_transpose = false; + // We might be trying to load a gl_Position[N], where we should be // doing float4[](gl_in[i].gl_Position, ...) instead. // Similar workarounds are required for input arrays in tessellation. @@ -10112,7 +11990,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) // it is an array, and our backend does not support arrays as value types. // Emit the temporary, and copy it explicitly. e = &emit_uninitialized_temporary_expression(result_type, id); - emit_array_copy(to_expression(id), id, ptr, StorageClassFunction, get_expression_effective_storage_class(ptr)); + emit_array_copy(nullptr, id, ptr, StorageClassFunction, get_expression_effective_storage_class(ptr)); } else e = &emit_op(result_type, id, expr, forward, !usage_tracking); @@ -10156,14 +12034,25 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) // If an expression is mutable and forwardable, we speculate that it is immutable. AccessChainMeta meta; bool ptr_chain = opcode == OpPtrAccessChain; - auto e = access_chain(ops[2], &ops[3], length - 3, get(ops[0]), &meta, ptr_chain); + auto &target_type = get(ops[0]); + auto e = access_chain(ops[2], &ops[3], length - 3, target_type, &meta, ptr_chain); - auto &expr = set(ops[1], move(e), ops[0], should_forward(ops[2])); + // If the base is flattened UBO of struct type, the expression has to be a composite. + // In that case, backends which do not support inline syntax need it to be bound to a temporary. + // Otherwise, invalid expressions like ({UBO[0].xyz, UBO[0].w, UBO[1]}).member are emitted. + bool requires_temporary = false; + if (flattened_buffer_blocks.count(ops[2]) && target_type.basetype == SPIRType::Struct) + requires_temporary = !backend.can_declare_struct_inline; + + auto &expr = requires_temporary ? + emit_op(ops[0], ops[1], std::move(e), false) : + set(ops[1], std::move(e), ops[0], should_forward(ops[2])); auto *backing_variable = maybe_get_backing_variable(ops[2]); expr.loaded_from = backing_variable ? backing_variable->self : ID(ops[2]); expr.need_transpose = meta.need_transpose; expr.access_chain = true; + expr.access_meshlet_position_y = meta.access_meshlet_position_y; // Mark the result as being packed. Some platforms handled packed vectors differently than non-packed. if (meta.storage_is_packed) @@ -10174,6 +12063,8 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) set_decoration(ops[1], DecorationInvariant); if (meta.flattened_struct) flattened_structs[ops[1]] = true; + if (meta.relaxed_precision && backend.requires_relaxed_precision_analysis) + set_decoration(ops[1], DecorationRelaxedPrecision); // If we have some expression dependencies in our access chain, this access chain is technically a forwarded // temporary which could be subject to invalidation. @@ -10538,6 +12429,9 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) e = &emit_op(result_type, id, expr, true, should_suppress_usage_tracking(ops[2])); inherit_expression_dependencies(id, ops[2]); e->base_expression = ops[2]; + + if (meta.relaxed_precision && backend.requires_relaxed_precision_analysis) + set_decoration(ops[1], DecorationRelaxedPrecision); } else { @@ -10572,11 +12466,66 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) flush_variable_declaration(composite); - // Make a copy, then use access chain to store the variable. - statement(declare_temporary(result_type, id), to_expression(composite), ";"); - set(id, to_name(id), result_type, true); - auto chain = access_chain_internal(id, elems, length, ACCESS_CHAIN_INDEX_IS_LITERAL_BIT, nullptr); - statement(chain, " = ", to_unpacked_expression(obj), ";"); + // CompositeInsert requires a copy + modification, but this is very awkward code in HLL. + // Speculate that the input composite is no longer used, and we can modify it in-place. + // There are various scenarios where this is not possible to satisfy. + bool can_modify_in_place = true; + forced_temporaries.insert(id); + + // Cannot safely RMW PHI variables since they have no way to be invalidated, + // forcing temporaries is not going to help. + // This is similar for Constant and Undef inputs. + // The only safe thing to RMW is SPIRExpression. + // If the expression has already been used (i.e. used in a continue block), we have to keep using + // that loop variable, since we won't be able to override the expression after the fact. + // If the composite is hoisted, we might never be able to properly invalidate any usage + // of that composite in a subsequent loop iteration. + if (invalid_expressions.count(composite) || + block_composite_insert_overwrite.count(composite) || + hoisted_temporaries.count(id) || hoisted_temporaries.count(composite) || + maybe_get(composite) == nullptr) + { + can_modify_in_place = false; + } + else if (backend.requires_relaxed_precision_analysis && + has_decoration(composite, DecorationRelaxedPrecision) != + has_decoration(id, DecorationRelaxedPrecision) && + get(result_type).basetype != SPIRType::Struct) + { + // Similarly, if precision does not match for input and output, + // we cannot alias them. If we write a composite into a relaxed precision + // ID, we might get a false truncation. + can_modify_in_place = false; + } + + if (can_modify_in_place) + { + // Have to make sure the modified SSA value is bound to a temporary so we can modify it in-place. + if (!forced_temporaries.count(composite)) + force_temporary_and_recompile(composite); + + auto chain = access_chain_internal(composite, elems, length, ACCESS_CHAIN_INDEX_IS_LITERAL_BIT, nullptr); + statement(chain, " = ", to_unpacked_expression(obj), ";"); + set(id, to_expression(composite), result_type, true); + invalid_expressions.insert(composite); + composite_insert_overwritten.insert(composite); + } + else + { + if (maybe_get(composite) != nullptr) + { + emit_uninitialized_temporary_expression(result_type, id); + } + else + { + // Make a copy, then use access chain to store the variable. + statement(declare_temporary(result_type, id), to_expression(composite), ";"); + set(id, to_name(id), result_type, true); + } + + auto chain = access_chain_internal(id, elems, length, ACCESS_CHAIN_INDEX_IS_LITERAL_BIT, nullptr); + statement(chain, " = ", to_unpacked_expression(obj), ";"); + } break; } @@ -10653,15 +12602,14 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) { // Need a copy. // For pointer types, we copy the pointer itself. - statement(declare_temporary(result_type, id), to_unpacked_expression(rhs), ";"); - set(id, to_name(id), result_type, true); + emit_op(result_type, id, to_unpacked_expression(rhs), false); } else { // RHS expression is immutable, so just forward it. // Copying these things really make no sense, but // seems to be allowed anyways. - auto &e = set(id, to_expression(rhs), result_type, true); + auto &e = emit_op(result_type, id, to_expression(rhs), true, true); if (pointer) { auto *var = maybe_get_backing_variable(rhs); @@ -10762,14 +12710,66 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) // ALU case OpIsNan: - GLSL_UFOP(isnan); + if (!is_legacy()) + GLSL_UFOP(isnan); + else + { + // Check if the number doesn't equal itself + auto &type = get(ops[0]); + if (type.vecsize > 1) + emit_binary_func_op(ops[0], ops[1], ops[2], ops[2], "notEqual"); + else + emit_binary_op(ops[0], ops[1], ops[2], ops[2], "!="); + } break; case OpIsInf: - GLSL_UFOP(isinf); + if (!is_legacy()) + GLSL_UFOP(isinf); + else + { + // inf * 2 == inf by IEEE 754 rules, note this also applies to 0.0 + // This is more reliable than checking if product with zero is NaN + uint32_t result_type = ops[0]; + uint32_t result_id = ops[1]; + uint32_t operand = ops[2]; + + auto &type = get(result_type); + std::string expr; + if (type.vecsize > 1) + { + expr = type_to_glsl_constructor(type); + expr += '('; + for (uint32_t i = 0; i < type.vecsize; i++) + { + auto comp = to_extract_component_expression(operand, i); + expr += join(comp, " != 0.0 && 2.0 * ", comp, " == ", comp); + + if (i + 1 < type.vecsize) + expr += ", "; + } + expr += ')'; + } + else + { + // Register an extra read to force writing out a temporary + auto oper = to_enclosed_expression(operand); + track_expression_read(operand); + expr += join(oper, " != 0.0 && 2.0 * ", oper, " == ", oper); + } + emit_op(result_type, result_id, expr, should_forward(operand)); + + inherit_expression_dependencies(result_id, operand); + } break; case OpSNegate: + if (implicit_integer_promotion || expression_type_id(ops[2]) != ops[0]) + GLSL_UOP_CAST(-); + else + GLSL_UOP(-); + break; + case OpFNegate: GLSL_UOP(-); break; @@ -10859,14 +12859,59 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) break; } - case OpFMul: case OpMatrixTimesScalar: + { + auto *a = maybe_get(ops[2]); + + // If the matrix need transpose, just mark the result as needing so. + if (a && a->need_transpose) + { + a->need_transpose = false; + auto expr = join(enclose_expression(to_unpacked_row_major_matrix_expression(ops[2])), " * ", + to_enclosed_unpacked_expression(ops[3])); + bool forward = should_forward(ops[2]) && should_forward(ops[3]); + auto &e = emit_op(ops[0], ops[1], expr, forward); + e.need_transpose = true; + a->need_transpose = true; + inherit_expression_dependencies(ops[1], ops[2]); + inherit_expression_dependencies(ops[1], ops[3]); + } + else + GLSL_BOP(*); + break; + } + + case OpFMul: case OpVectorTimesScalar: GLSL_BOP(*); break; case OpOuterProduct: - GLSL_BFOP(outerProduct); + if (options.version < 120) // Matches GLSL 1.10 / ESSL 1.00 + { + uint32_t result_type = ops[0]; + uint32_t id = ops[1]; + uint32_t a = ops[2]; + uint32_t b = ops[3]; + + auto &type = get(result_type); + string expr = type_to_glsl_constructor(type); + expr += "("; + for (uint32_t col = 0; col < type.columns; col++) + { + expr += to_enclosed_expression(a); + expr += " * "; + expr += to_extract_component_expression(b, col); + if (col + 1 < type.columns) + expr += ", "; + } + expr += ")"; + emit_op(result_type, id, expr, should_forward(a) && should_forward(b)); + inherit_expression_dependencies(id, a); + inherit_expression_dependencies(id, b); + } + else + GLSL_BFOP(outerProduct); break; case OpDot: @@ -10914,6 +12959,9 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) auto expr = join(to_enclosed_expression(op0), " - ", to_enclosed_expression(op1), " * ", "(", to_enclosed_expression(op0), " / ", to_enclosed_expression(op1), ")"); + if (implicit_integer_promotion) + expr = join(type_to_glsl(get(result_type)), '(', expr, ')'); + emit_op(result_type, result_id, expr, forward); inherit_expression_dependencies(result_id, op0); inherit_expression_dependencies(result_id, op1); @@ -11011,7 +13059,10 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) } case OpNot: - GLSL_UOP(~); + if (implicit_integer_promotion || expression_type_id(ops[2]) != ops[0]) + GLSL_UOP_CAST(~); + else + GLSL_UOP(~); break; case OpUMod: @@ -11028,10 +13079,6 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) case OpFRem: { - if (is_legacy()) - SPIRV_CROSS_THROW("OpFRem requires trunc() and is only supported on non-legacy targets. A workaround is " - "needed for legacy."); - uint32_t result_type = ops[0]; uint32_t result_id = ops[1]; uint32_t op0 = ops[2]; @@ -11039,8 +13086,22 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) // Needs special handling. bool forward = should_forward(op0) && should_forward(op1); - auto expr = join(to_enclosed_expression(op0), " - ", to_enclosed_expression(op1), " * ", "trunc(", - to_enclosed_expression(op0), " / ", to_enclosed_expression(op1), ")"); + std::string expr; + if (!is_legacy()) + { + expr = join(to_enclosed_expression(op0), " - ", to_enclosed_expression(op1), " * ", "trunc(", + to_enclosed_expression(op0), " / ", to_enclosed_expression(op1), ")"); + } + else + { + // Legacy GLSL has no trunc, emulate by casting to int and back + auto &op0_type = expression_type(op0); + auto via_type = op0_type; + via_type.basetype = SPIRType::Int; + expr = join(to_enclosed_expression(op0), " - ", to_enclosed_expression(op1), " * ", + type_to_glsl(op0_type), "(", type_to_glsl(via_type), "(", + to_enclosed_expression(op0), " / ", to_enclosed_expression(op1), "))"); + } emit_op(result_type, result_id, expr, forward); inherit_expression_dependencies(result_id, op0); @@ -11129,7 +13190,11 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) case OpLogicalNotEqual: case OpFOrdNotEqual: + case OpFUnordNotEqual: { + // GLSL is fuzzy on what to do with ordered vs unordered not equal. + // glslang started emitting UnorderedNotEqual some time ago to harmonize with IEEE, + // but this means we have no easy way of implementing ordered not equal. if (expression_type(ops[2]).vecsize > 1) GLSL_BFOP(notEqual); else @@ -11537,6 +13602,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) } case OpAtomicIAdd: + case OpAtomicFAddEXT: { const char *op = check_atomic_image(ops[2]) ? "imageAtomicAdd" : "atomicAdd"; emit_atomic_func_op(ops[0], ops[1], ops[2], ops[5], op); @@ -11689,7 +13755,12 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) op = "textureQueryLOD"; } else if (options.es) - SPIRV_CROSS_THROW("textureQueryLod not supported in ES profile."); + { + if (options.version < 300) + SPIRV_CROSS_THROW("textureQueryLod not supported in legacy ES"); + require_extension_internal("GL_EXT_texture_query_lod"); + op = "textureQueryLOD"; + } else op = "textureQueryLod"; @@ -11735,6 +13806,11 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) uint32_t result_type = ops[0]; uint32_t id = ops[1]; + if (options.es) + SPIRV_CROSS_THROW("textureSamples and imageSamples not supported in ES profile."); + else if (options.version < 450) + require_extension_internal("GL_ARB_texture_query_samples"); + string expr; if (type.image.sampled == 2) expr = join("imageSamples(", to_non_uniform_aware_expression(ops[2]), ")"); @@ -11762,12 +13838,12 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) uint32_t result_type = ops[0]; uint32_t id = ops[1]; uint32_t img = ops[2]; + auto &type = expression_type(img); + auto &imgtype = get(type.self); std::string fname = "textureSize"; if (is_legacy_desktop()) { - auto &type = expression_type(img); - auto &imgtype = get(type.self); fname = legacy_tex_op(fname, imgtype, img); } else if (is_legacy_es()) @@ -11775,6 +13851,11 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) auto expr = join(fname, "(", convert_separate_image_to_expression(img), ", ", bitcast_expression(SPIRType::Int, ops[3]), ")"); + + // ES needs to emulate 1D images as 2D. + if (type.image.dim == Dim1D && options.es) + expr = join(expr, ".x"); + auto &restype = get(ops[0]); expr = bitcast_expression(restype, SPIRType::Int, expr); emit_op(result_type, id, expr, true); @@ -11791,10 +13872,10 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) auto *var = maybe_get_backing_variable(ops[2]); if (var) { - auto &flags = ir.meta[var->self].decoration.decoration_flags; + auto &flags = get_decoration_bitset(var->self); if (flags.get(DecorationNonReadable)) { - flags.clear(DecorationNonReadable); + unset_decoration(var->self, DecorationNonReadable); force_recompile(); } } @@ -11889,6 +13970,10 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) target_coord_type.basetype = SPIRType::Int; coord_expr = bitcast_expression(target_coord_type, expression_type(ops[3]).basetype, coord_expr); + // ES needs to emulate 1D images as 2D. + if (type.image.dim == Dim1D && options.es) + coord_expr = join("ivec2(", coord_expr, ", 0)"); + // Plain image load/store. if (sparse) { @@ -11933,7 +14018,7 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) pure = false; } - if (var && var->forwardable) + if (var) { bool forward = forced_temporaries.find(id) == end(forced_temporaries); auto &e = emit_op(result_type, id, imgexpr, forward); @@ -11983,10 +14068,9 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) auto *var = maybe_get_backing_variable(ops[0]); if (var) { - auto &flags = ir.meta[var->self].decoration.decoration_flags; - if (flags.get(DecorationNonWritable)) + if (has_decoration(var->self, DecorationNonWritable)) { - flags.clear(DecorationNonWritable); + unset_decoration(var->self, DecorationNonWritable); force_recompile(); } } @@ -12002,6 +14086,10 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) target_coord_type.basetype = SPIRType::Int; coord_expr = bitcast_expression(target_coord_type, expression_type(ops[1]).basetype, coord_expr); + // ES needs to emulate 1D images as 2D. + if (type.image.dim == Dim1D && options.es) + coord_expr = join("ivec2(", coord_expr, ", 0)"); + if (type.image.ms) { uint32_t operands = ops[3]; @@ -12230,31 +14318,52 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) case OpExtInst: { uint32_t extension_set = ops[2]; + auto ext = get(extension_set).ext; - if (get(extension_set).ext == SPIRExtension::GLSL) + if (ext == SPIRExtension::GLSL) { emit_glsl_op(ops[0], ops[1], ops[3], &ops[4], length - 4); } - else if (get(extension_set).ext == SPIRExtension::SPV_AMD_shader_ballot) + else if (ext == SPIRExtension::SPV_AMD_shader_ballot) { emit_spv_amd_shader_ballot_op(ops[0], ops[1], ops[3], &ops[4], length - 4); } - else if (get(extension_set).ext == SPIRExtension::SPV_AMD_shader_explicit_vertex_parameter) + else if (ext == SPIRExtension::SPV_AMD_shader_explicit_vertex_parameter) { emit_spv_amd_shader_explicit_vertex_parameter_op(ops[0], ops[1], ops[3], &ops[4], length - 4); } - else if (get(extension_set).ext == SPIRExtension::SPV_AMD_shader_trinary_minmax) + else if (ext == SPIRExtension::SPV_AMD_shader_trinary_minmax) { emit_spv_amd_shader_trinary_minmax_op(ops[0], ops[1], ops[3], &ops[4], length - 4); } - else if (get(extension_set).ext == SPIRExtension::SPV_AMD_gcn_shader) + else if (ext == SPIRExtension::SPV_AMD_gcn_shader) { emit_spv_amd_gcn_shader_op(ops[0], ops[1], ops[3], &ops[4], length - 4); } - else if (get(extension_set).ext == SPIRExtension::SPV_debug_info) + else if (ext == SPIRExtension::SPV_debug_info || + ext == SPIRExtension::NonSemanticShaderDebugInfo || + ext == SPIRExtension::NonSemanticGeneric) { break; // Ignore SPIR-V debug information extended instructions. } + else if (ext == SPIRExtension::NonSemanticDebugPrintf) + { + // Operation 1 is printf. + if (ops[3] == 1) + { + if (!options.vulkan_semantics) + SPIRV_CROSS_THROW("Debug printf is only supported in Vulkan GLSL.\n"); + require_extension_internal("GL_EXT_debug_printf"); + auto &format_string = get(ops[4]).str; + string expr = join("debugPrintfEXT(\"", format_string, "\""); + for (uint32_t i = 5; i < length; i++) + { + expr += ", "; + expr += to_expression(ops[i]); + } + statement(expr, ");"); + } + } else { statement("// unimplemented ext op ", instruction.op); @@ -12449,7 +14558,6 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) break; case OpFUnordEqual: - case OpFUnordNotEqual: case OpFUnordLessThan: case OpFUnordGreaterThan: case OpFUnordLessThanEqual: @@ -12472,10 +14580,6 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) comp_op = "notEqual"; break; - case OpFUnordNotEqual: - comp_op = "equal"; - break; - case OpFUnordLessThan: comp_op = "greaterThanEqual"; break; @@ -12508,10 +14612,6 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) comp_op = " != "; break; - case OpFUnordNotEqual: - comp_op = " == "; - break; - case OpFUnordLessThan: comp_op = " >= "; break; @@ -12645,9 +14745,30 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) #undef GLSL_RAY_QUERY_GET_OP2 case OpConvertUToAccelerationStructureKHR: + { require_extension_internal("GL_EXT_ray_tracing"); - GLSL_UFOP(accelerationStructureEXT); + + bool elide_temporary = should_forward(ops[2]) && forced_temporaries.count(ops[1]) == 0 && + !hoisted_temporaries.count(ops[1]); + + if (elide_temporary) + { + GLSL_UFOP(accelerationStructureEXT); + } + else + { + // Force this path in subsequent iterations. + forced_temporaries.insert(ops[1]); + + // We cannot declare a temporary acceleration structure in GLSL. + // If we get to this point, we'll have to emit a temporary uvec2, + // and cast to RTAS on demand. + statement(declare_temporary(expression_type_id(ops[2]), ops[1]), to_unpacked_expression(ops[2]), ";"); + // Use raw SPIRExpression interface to block all usage tracking. + set(ops[1], join("accelerationStructureEXT(", to_name(ops[1]), ")"), ops[0], true); + } break; + } case OpConvertUToPtr: { @@ -12703,6 +14824,8 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) if (!options.vulkan_semantics) SPIRV_CROSS_THROW("GL_EXT_demote_to_helper_invocation is only supported in Vulkan GLSL."); require_extension_internal("GL_EXT_demote_to_helper_invocation"); + // Helper lane state with demote is volatile by nature. + // Do not forward this. emit_op(ops[0], ops[1], "helperInvocationEXT()", false); break; @@ -12726,6 +14849,46 @@ void CompilerGLSL::emit_instruction(const Instruction &instruction) } break; + case OpSetMeshOutputsEXT: + statement("SetMeshOutputsEXT(", to_unpacked_expression(ops[0]), ", ", to_unpacked_expression(ops[1]), ");"); + break; + + case OpReadClockKHR: + { + auto &type = get(ops[0]); + auto scope = static_cast(evaluate_constant_u32(ops[2])); + const char *op = nullptr; + // Forwarding clock statements leads to a scenario where an SSA value can take on different + // values every time it's evaluated. Block any forwarding attempt. + // We also might want to invalidate all expressions to function as a sort of optimization + // barrier, but might be overkill for now. + if (scope == ScopeDevice) + { + require_extension_internal("GL_EXT_shader_realtime_clock"); + if (type.basetype == SPIRType::BaseType::UInt64) + op = "clockRealtimeEXT()"; + else if (type.basetype == SPIRType::BaseType::UInt && type.vecsize == 2) + op = "clockRealtime2x32EXT()"; + else + SPIRV_CROSS_THROW("Unsupported result type for OpReadClockKHR opcode."); + } + else if (scope == ScopeSubgroup) + { + require_extension_internal("GL_ARB_shader_clock"); + if (type.basetype == SPIRType::BaseType::UInt64) + op = "clockARB()"; + else if (type.basetype == SPIRType::BaseType::UInt && type.vecsize == 2) + op = "clock2x32ARB()"; + else + SPIRV_CROSS_THROW("Unsupported result type for OpReadClockKHR opcode."); + } + else + SPIRV_CROSS_THROW("Unsupported scope for OpReadClockKHR opcode."); + + emit_op(ops[0], ops[1], op, false); + break; + } + default: statement("// unimplemented op ", instruction.op); break; @@ -12858,7 +15021,7 @@ bool CompilerGLSL::member_is_packed_physical_type(const SPIRType &type, uint32_t // Base implementation uses the standard library transpose() function. // Subclasses may override to use a different function. string CompilerGLSL::convert_row_major_matrix(string exp_str, const SPIRType &exp_type, uint32_t /* physical_type_id */, - bool /*is_packed*/) + bool /*is_packed*/, bool relaxed) { strip_enclosed_expression(exp_str); if (!is_matrix(exp_type)) @@ -12870,6 +15033,17 @@ string CompilerGLSL::convert_row_major_matrix(string exp_str, const SPIRType &ex auto column_expr = exp_str.substr(column_index); exp_str.resize(column_index); + auto end_deferred_index = column_expr.find_last_of(']'); + if (end_deferred_index != string::npos && end_deferred_index + 1 != column_expr.size()) + { + // If we have any data member fixups, it must be transposed so that it refers to this index. + // E.g. [0].data followed by [1] would be shuffled to [1][0].data which is wrong, + // and needs to be [1].data[0] instead. + end_deferred_index++; + column_expr = column_expr.substr(end_deferred_index) + + column_expr.substr(0, end_deferred_index); + } + auto transposed_expr = type_to_glsl_constructor(exp_type) + "("; // Loading a column from a row-major matrix. Unroll the load. @@ -12888,32 +15062,14 @@ string CompilerGLSL::convert_row_major_matrix(string exp_str, const SPIRType &ex // GLSL 110, ES 100 do not have transpose(), so emulate it. Note that // these GLSL versions do not support non-square matrices. if (exp_type.vecsize == 2 && exp_type.columns == 2) - { - if (!requires_transpose_2x2) - { - requires_transpose_2x2 = true; - force_recompile(); - } - } + require_polyfill(PolyfillTranspose2x2, relaxed); else if (exp_type.vecsize == 3 && exp_type.columns == 3) - { - if (!requires_transpose_3x3) - { - requires_transpose_3x3 = true; - force_recompile(); - } - } + require_polyfill(PolyfillTranspose3x3, relaxed); else if (exp_type.vecsize == 4 && exp_type.columns == 4) - { - if (!requires_transpose_4x4) - { - requires_transpose_4x4 = true; - force_recompile(); - } - } + require_polyfill(PolyfillTranspose4x4, relaxed); else SPIRV_CROSS_THROW("Non-square matrices are not supported in legacy GLSL, cannot transpose."); - return join("spvTranspose(", exp_str, ")"); + return join("spvTranspose", (options.es && relaxed) ? "MP" : "", "(", exp_str, ")"); } else return join("transpose(", exp_str, ")"); @@ -12982,7 +15138,12 @@ string CompilerGLSL::flags_to_qualifiers_glsl(const SPIRType &type, const Bitset { auto &execution = get_entry_point(); - if (flags.get(DecorationRelaxedPrecision)) + if (type.basetype == SPIRType::UInt && is_legacy_es()) + { + // HACK: This is a bool. See comment in type_to_glsl(). + qual += "lowp "; + } + else if (flags.get(DecorationRelaxedPrecision)) { bool implied_fmediump = type.basetype == SPIRType::Float && options.fragment.default_float_precision == Options::Mediump && @@ -13034,40 +15195,55 @@ string CompilerGLSL::to_precision_qualifiers_glsl(uint32_t id) return flags_to_qualifiers_glsl(type, ir.meta[id].decoration.decoration_flags); } -void CompilerGLSL::fixup_io_block_patch_qualifiers(const SPIRVariable &var) +void CompilerGLSL::fixup_io_block_patch_primitive_qualifiers(const SPIRVariable &var) { // Works around weird behavior in glslangValidator where // a patch out block is translated to just block members getting the decoration. // To make glslang not complain when we compile again, we have to transform this back to a case where // the variable itself has Patch decoration, and not members. + // Same for perprimitiveEXT. auto &type = get(var.basetype); if (has_decoration(type.self, DecorationBlock)) { uint32_t member_count = uint32_t(type.member_types.size()); + Decoration promoted_decoration = {}; + bool do_promote_decoration = false; for (uint32_t i = 0; i < member_count; i++) { if (has_member_decoration(type.self, i, DecorationPatch)) { - set_decoration(var.self, DecorationPatch); + promoted_decoration = DecorationPatch; + do_promote_decoration = true; + break; + } + else if (has_member_decoration(type.self, i, DecorationPerPrimitiveEXT)) + { + promoted_decoration = DecorationPerPrimitiveEXT; + do_promote_decoration = true; break; } } - if (has_decoration(var.self, DecorationPatch)) + if (do_promote_decoration) + { + set_decoration(var.self, promoted_decoration); for (uint32_t i = 0; i < member_count; i++) - unset_member_decoration(type.self, i, DecorationPatch); + unset_member_decoration(type.self, i, promoted_decoration); + } } } string CompilerGLSL::to_qualifiers_glsl(uint32_t id) { - auto &flags = ir.meta[id].decoration.decoration_flags; + auto &flags = get_decoration_bitset(id); string res; auto *var = maybe_get(id); if (var && var->storage == StorageClassWorkgroup && !backend.shared_is_implied) res += "shared "; + else if (var && var->storage == StorageClassTaskPayloadWorkgroupEXT && !backend.shared_is_implied) + res += "taskPayloadSharedEXT "; res += to_interpolation_qualifiers(flags); if (var) @@ -13190,7 +15366,7 @@ string CompilerGLSL::variable_decl(const SPIRVariable &variable) const char *CompilerGLSL::to_pls_qualifiers_glsl(const SPIRVariable &variable) { - auto &flags = ir.meta[variable.self].decoration.decoration_flags; + auto &flags = get_decoration_bitset(variable.self); if (flags.get(DecorationRelaxedPrecision)) return "mediump "; else @@ -13201,9 +15377,16 @@ string CompilerGLSL::pls_decl(const PlsRemap &var) { auto &variable = get(var.id); - SPIRType type; - type.vecsize = pls_format_to_components(var.format); - type.basetype = pls_format_to_basetype(var.format); + auto op_and_basetype = pls_format_to_basetype(var.format); + + SPIRType type { op_and_basetype.first }; + type.basetype = op_and_basetype.second; + auto vecsize = pls_format_to_components(var.format); + if (vecsize > 1) + { + type.op = OpTypeVector; + type.vecsize = vecsize; + } return join(to_pls_layout(var.format), to_pls_qualifiers_glsl(variable), type_to_glsl(type), " ", to_name(variable.self)); @@ -13307,6 +15490,14 @@ string CompilerGLSL::image_type_glsl(const SPIRType &type, uint32_t id) switch (imagetype.basetype) { + case SPIRType::Int64: + res = "i64"; + require_extension_internal("GL_EXT_shader_image_int64"); + break; + case SPIRType::UInt64: + res = "u64"; + require_extension_internal("GL_EXT_shader_image_int64"); + break; case SPIRType::Int: case SPIRType::Short: case SPIRType::SByte: @@ -13350,7 +15541,8 @@ string CompilerGLSL::image_type_glsl(const SPIRType &type, uint32_t id) switch (type.image.dim) { case Dim1D: - res += "1D"; + // ES doesn't support 1D. Fake it with 2D. + res += options.es ? "2D" : "1D"; break; case Dim2D: res += "2D"; @@ -13373,7 +15565,7 @@ string CompilerGLSL::image_type_glsl(const SPIRType &type, uint32_t id) case DimBuffer: if (options.es && options.version < 320) - require_extension_internal("GL_OES_texture_buffer"); + require_extension_internal("GL_EXT_texture_buffer"); else if (!options.es && options.version < 300) require_extension_internal("GL_EXT_texture_buffer_object"); res += "Buffer"; @@ -13400,6 +15592,17 @@ string CompilerGLSL::image_type_glsl(const SPIRType &type, uint32_t id) is_depth_image(type, id)) { res += "Shadow"; + + if (type.image.dim == DimCube && is_legacy()) + { + if (!options.es) + require_extension_internal("GL_EXT_gpu_shader4"); + else + { + require_extension_internal("GL_NV_shadow_samplers_cube"); + res += "NV"; + } + } } return res; @@ -13479,7 +15682,24 @@ string CompilerGLSL::type_to_glsl(const SPIRType &type, uint32_t id) } if (type.basetype == SPIRType::UInt && is_legacy()) - SPIRV_CROSS_THROW("Unsigned integers are not supported on legacy targets."); + { + if (options.es) + // HACK: spirv-cross changes bools into uints and generates code which compares them to + // zero. Input code will have already been validated as not to have contained any uints, + // so any remaining uints must in fact be bools. However, simply returning "bool" here + // will result in invalid code. Instead, return an int. + return backend.basic_int_type; + else + require_extension_internal("GL_EXT_gpu_shader4"); + } + + if (type.basetype == SPIRType::AtomicCounter) + { + if (options.es && options.version < 310) + SPIRV_CROSS_THROW("At least ESSL 3.10 required for atomic counters."); + else if (!options.es && options.version < 420) + require_extension_internal("GL_ARB_shader_atomic_counters"); + } if (type.vecsize == 1 && type.columns == 1) // Scalar builtin { @@ -13634,6 +15854,11 @@ void CompilerGLSL::require_extension(const std::string &ext) forced_extensions.push_back(ext); } +const SmallVector &CompilerGLSL::get_required_extensions() const +{ + return forced_extensions; +} + void CompilerGLSL::require_extension_internal(const string &ext) { if (backend.supports_extensions && !has_extension(ext)) @@ -13648,7 +15873,7 @@ void CompilerGLSL::flatten_buffer_block(VariableID id) auto &var = get(id); auto &type = get(var.basetype); auto name = to_name(type.self, false); - auto &flags = ir.meta[type.self].decoration.decoration_flags; + auto &flags = get_decoration_bitset(type.self); if (!type.array.empty()) SPIRV_CROSS_THROW(name + " is an array of UBOs."); @@ -13667,6 +15892,11 @@ bool CompilerGLSL::builtin_translates_to_nonarray(spv::BuiltIn /*builtin*/) cons return false; // GLSL itself does not need to translate array builtin types to non-array builtin types } +bool CompilerGLSL::is_user_type_structured(uint32_t /*id*/) const +{ + return false; // GLSL itself does not have structured user type, but HLSL does with StructuredBuffer and RWStructuredBuffer resources. +} + bool CompilerGLSL::check_atomic_image(uint32_t id) { auto &type = expression_type(id); @@ -13678,11 +15908,10 @@ bool CompilerGLSL::check_atomic_image(uint32_t id) auto *var = maybe_get_backing_variable(id); if (var) { - auto &flags = ir.meta[var->self].decoration.decoration_flags; - if (flags.get(DecorationNonWritable) || flags.get(DecorationNonReadable)) + if (has_decoration(var->self, DecorationNonWritable) || has_decoration(var->self, DecorationNonReadable)) { - flags.clear(DecorationNonWritable); - flags.clear(DecorationNonReadable); + unset_decoration(var->self, DecorationNonWritable); + unset_decoration(var->self, DecorationNonReadable); force_recompile(); } } @@ -13935,7 +16164,11 @@ void CompilerGLSL::emit_function(SPIRFunction &func, const Bitset &return_flags) // Loop variables are never declared outside their for-loop, so block any implicit declaration. if (var.loop_variable) + { var.deferred_declaration = false; + // Need to reset the static expression so we can fallback to initializer if need be. + var.static_expression = 0; + } } // Enforce declaration order for regression testing purposes. @@ -14120,21 +16353,32 @@ void CompilerGLSL::branch(BlockID from, BlockID to) // - Break merge target all at once ... // Very dirty workaround. - // Switch constructs are able to break, but they cannot break out of a loop at the same time. + // Switch constructs are able to break, but they cannot break out of a loop at the same time, + // yet SPIR-V allows it. // Only sensible solution is to make a ladder variable, which we declare at the top of the switch block, // write to the ladder here, and defer the break. // The loop we're breaking out of must dominate the switch block, or there is no ladder breaking case. - if (current_emitting_switch && is_loop_break(to) && - current_emitting_switch->loop_dominator != BlockID(SPIRBlock::NoDominator) && - get(current_emitting_switch->loop_dominator).merge_block == to) + if (is_loop_break(to)) { - if (!current_emitting_switch->need_ladder_break) + for (size_t n = current_emitting_switch_stack.size(); n; n--) { - force_recompile(); - current_emitting_switch->need_ladder_break = true; - } + auto *current_emitting_switch = current_emitting_switch_stack[n - 1]; + + if (current_emitting_switch && + current_emitting_switch->loop_dominator != BlockID(SPIRBlock::NoDominator) && + get(current_emitting_switch->loop_dominator).merge_block == to) + { + if (!current_emitting_switch->need_ladder_break) + { + force_recompile(); + current_emitting_switch->need_ladder_break = true; + } - statement("_", current_emitting_switch->self, "_ladder_break = true;"); + statement("_", current_emitting_switch->self, "_ladder_break = true;"); + } + else + break; + } } statement("break;"); } @@ -14379,6 +16623,17 @@ bool CompilerGLSL::for_loop_initializers_are_same_type(const SPIRBlock &block) return true; } +void CompilerGLSL::emit_block_instructions_with_masked_debug(SPIRBlock &block) +{ + // Have to block debug instructions such as OpLine here, since it will be treated as a statement otherwise, + // which breaks loop optimizations. + // Any line directive would be declared outside the loop body, which would just be confusing either way. + bool old_block_debug_directives = block_debug_directives; + block_debug_directives = true; + emit_block_instructions(block); + block_debug_directives = old_block_debug_directives; +} + bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method method) { SPIRBlock::ContinueBlockType continue_type = continue_block_type(get(block.continue_block)); @@ -14389,7 +16644,7 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method // If we're trying to create a true for loop, // we need to make sure that all opcodes before branch statement do not actually emit any code. // We can then take the condition expression and create a for (; cond ; ) { body; } structure instead. - emit_block_instructions(block); + emit_block_instructions_with_masked_debug(block); bool condition_is_temporary = forced_temporaries.find(block.condition) == end(forced_temporaries); @@ -14469,7 +16724,7 @@ bool CompilerGLSL::attempt_emit_loop_header(SPIRBlock &block, SPIRBlock::Method // If we're trying to create a true for loop, // we need to make sure that all opcodes before branch statement do not actually emit any code. // We can then take the condition expression and create a for (; cond ; ) { body; } structure instead. - emit_block_instructions(child); + emit_block_instructions_with_masked_debug(child); bool condition_is_temporary = forced_temporaries.find(child.condition) == end(forced_temporaries); @@ -14554,10 +16809,17 @@ void CompilerGLSL::emit_hoisted_temporaries(SmallVector> &tempo for (auto &tmp : temporaries) { - add_local_variable_name(tmp.second); - auto &flags = ir.meta[tmp.second].decoration.decoration_flags; auto &type = get(tmp.first); + // There are some rare scenarios where we are asked to declare pointer types as hoisted temporaries. + // This should be ignored unless we're doing actual variable pointers and backend supports it. + // Access chains cannot normally be lowered to temporaries in GLSL and HLSL. + if (type.pointer && !backend.native_pointers) + continue; + + add_local_variable_name(tmp.second); + auto &flags = get_decoration_bitset(tmp.second); + // Not all targets support pointer literals, so don't bother with that case. string initializer; if (options.force_zero_initialized_variables && type_can_zero_initialize(type)) @@ -14570,6 +16832,21 @@ void CompilerGLSL::emit_hoisted_temporaries(SmallVector> &tempo // The temporary might be read from before it's assigned, set up the expression now. set(tmp.second, to_name(tmp.second), tmp.first, true); + + // If we have hoisted temporaries in multi-precision contexts, emit that here too ... + // We will not be able to analyze hoisted-ness for dependent temporaries that we hallucinate here. + auto mirrored_precision_itr = temporary_to_mirror_precision_alias.find(tmp.second); + if (mirrored_precision_itr != temporary_to_mirror_precision_alias.end()) + { + uint32_t mirror_id = mirrored_precision_itr->second; + auto &mirror_flags = get_decoration_bitset(mirror_id); + statement(flags_to_qualifiers_glsl(type, mirror_flags), + variable_decl(type, to_name(mirror_id)), + initializer, ";"); + // The temporary might be read from before it's assigned, set up the expression now. + set(mirror_id, to_name(mirror_id), tmp.first, true); + hoisted_temporaries.insert(mirror_id); + } } } @@ -14585,6 +16862,24 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) if (block.merge == SPIRBlock::MergeLoop) add_loop_level(); + // If we're emitting PHI variables with precision aliases, we have to emit them as hoisted temporaries. + for (auto var_id : block.dominated_variables) + { + auto &var = get(var_id); + if (var.phi_variable) + { + auto mirrored_precision_itr = temporary_to_mirror_precision_alias.find(var_id); + if (mirrored_precision_itr != temporary_to_mirror_precision_alias.end() && + find_if(block.declare_temporary.begin(), block.declare_temporary.end(), + [mirrored_precision_itr](const std::pair &p) { + return p.second == mirrored_precision_itr->second; + }) == block.declare_temporary.end()) + { + block.declare_temporary.push_back({ var.basetype, mirrored_precision_itr->second }); + } + } + } + emit_hoisted_temporaries(block.declare_temporary); SPIRBlock::ContinueBlockType continue_type = SPIRBlock::ContinueNone; @@ -14703,7 +16998,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) // as writes to said loop variables might have been masked out, we need a recompile. if (!emitted_loop_header_variables && !block.loop_variables.empty()) { - force_recompile(); + force_recompile_guarantee_forward_progress(); for (auto var : block.loop_variables) get(var).loop_variable = false; block.loop_variables.clear(); @@ -14797,8 +17092,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) else if (type.basetype == SPIRType::Short) label_suffix = backend.int16_t_literal_suffix; - SPIRBlock *old_emitting_switch = current_emitting_switch; - current_emitting_switch = █ + current_emitting_switch_stack.push_back(&block); if (block.need_ladder_break) statement("bool _", block.self, "_ladder_break = false;"); @@ -14956,26 +17250,32 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) // If there is only one default block, and no cases, this is a case where SPIRV-opt decided to emulate // non-structured exits with the help of a switch block. // This is buggy on FXC, so just emit the logical equivalent of a do { } while(false), which is more idiomatic. - bool degenerate_switch = block.default_block != block.merge_block && cases.empty(); + bool block_like_switch = cases.empty(); - if (degenerate_switch || is_legacy_es()) + // If this is true, the switch is completely meaningless, and we should just avoid it. + bool collapsed_switch = block_like_switch && block.default_block == block.next_block; + + if (!collapsed_switch) { - // ESSL 1.0 is not guaranteed to support do/while. - if (is_legacy_es()) + if (block_like_switch || is_legacy_es()) { - uint32_t counter = statement_count; - statement("for (int spvDummy", counter, " = 0; spvDummy", counter, - " < 1; spvDummy", counter, "++)"); + // ESSL 1.0 is not guaranteed to support do/while. + if (is_legacy_es()) + { + uint32_t counter = statement_count; + statement("for (int spvDummy", counter, " = 0; spvDummy", counter, " < 1; spvDummy", counter, + "++)"); + } + else + statement("do"); } else - statement("do"); - } - else - { - emit_block_hints(block); - statement("switch (", to_unpacked_expression(block.condition), ")"); + { + emit_block_hints(block); + statement("switch (", to_unpacked_expression(block.condition), ")"); + } + begin_scope(); } - begin_scope(); for (size_t i = 0; i < num_blocks; i++) { @@ -14985,7 +17285,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) if (literals.empty()) { // Default case. - if (!degenerate_switch) + if (!block_like_switch) { if (is_legacy_es()) statement("else"); @@ -15023,10 +17323,10 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) else current_emitting_switch_fallthrough = false; - if (!degenerate_switch) + if (!block_like_switch) begin_scope(); branch(block.self, target_block); - if (!degenerate_switch) + if (!block_like_switch) end_scope(); current_emitting_switch_fallthrough = false; @@ -15040,7 +17340,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) // - Header -> Merge requires flushing PHI. In this case, we need to collect all cases and flush PHI there. bool header_merge_requires_phi = flush_phi_required(block.self, block.next_block); bool need_fallthrough_block = block.default_block == block.next_block || !literals_to_merge.empty(); - if ((header_merge_requires_phi && need_fallthrough_block) || !literals_to_merge.empty()) + if (!collapsed_switch && ((header_merge_requires_phi && need_fallthrough_block) || !literals_to_merge.empty())) { for (auto &case_literal : literals_to_merge) statement("case ", to_case_label(case_literal, type.width, unsigned_case), label_suffix, ":"); @@ -15059,10 +17359,15 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) end_scope(); } - if (degenerate_switch && !is_legacy_es()) - end_scope_decl("while(false)"); + if (!collapsed_switch) + { + if (block_like_switch && !is_legacy_es()) + end_scope_decl("while(false)"); + else + end_scope(); + } else - end_scope(); + flush_phi(block.self, block.next_block); if (block.need_ladder_break) { @@ -15072,7 +17377,7 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) end_scope(); } - current_emitting_switch = old_emitting_switch; + current_emitting_switch_stack.pop_back(); break; } @@ -15132,8 +17437,43 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) break; case SPIRBlock::Unreachable: + { + // Avoid emitting false fallthrough, which can happen for + // if (cond) break; else discard; inside a case label. + // Discard is not always implementable as a terminator. + + auto &cfg = get_cfg_for_current_function(); + bool inner_dominator_is_switch = false; + ID id = block.self; + + while (id) + { + auto &iter_block = get(id); + if (iter_block.terminator == SPIRBlock::MultiSelect || + iter_block.merge == SPIRBlock::MergeLoop) + { + ID next_block = iter_block.merge == SPIRBlock::MergeLoop ? + iter_block.merge_block : iter_block.next_block; + bool outside_construct = next_block && cfg.find_common_dominator(next_block, block.self) == next_block; + if (!outside_construct) + { + inner_dominator_is_switch = iter_block.terminator == SPIRBlock::MultiSelect; + break; + } + } + + if (cfg.get_preceding_edges(id).empty()) + break; + + id = cfg.get_immediate_dominator(id); + } + + if (inner_dominator_is_switch) + statement("break; // unreachable workaround"); + emit_next_block = false; break; + } case SPIRBlock::IgnoreIntersection: statement("ignoreIntersectionEXT;"); @@ -15143,6 +17483,10 @@ void CompilerGLSL::emit_block_chain(SPIRBlock &block) statement("terminateRayEXT;"); break; + case SPIRBlock::EmitMeshTasks: + emit_mesh_tasks(block); + break; + default: SPIRV_CROSS_THROW("Unimplemented block terminator."); } @@ -15317,9 +17661,16 @@ uint32_t CompilerGLSL::mask_relevant_memory_semantics(uint32_t semantics) MemorySemanticsCrossWorkgroupMemoryMask | MemorySemanticsSubgroupMemoryMask); } -void CompilerGLSL::emit_array_copy(const string &lhs, uint32_t, uint32_t rhs_id, StorageClass, StorageClass) +bool CompilerGLSL::emit_array_copy(const char *expr, uint32_t lhs_id, uint32_t rhs_id, StorageClass, StorageClass) { + string lhs; + if (expr) + lhs = expr; + else + lhs = to_expression(lhs_id); + statement(lhs, " = ", to_expression(rhs_id), ";"); + return true; } bool CompilerGLSL::unroll_array_to_complex_store(uint32_t target_id, uint32_t source_id) @@ -15346,7 +17697,7 @@ bool CompilerGLSL::unroll_array_to_complex_store(uint32_t target_id, uint32_t so else array_expr = to_expression(type.array.back()); - SPIRType target_type; + SPIRType target_type { OpTypeInt }; target_type.basetype = SPIRType::Int; statement("for (int i = 0; i < int(", array_expr, "); i++)"); @@ -15411,7 +17762,7 @@ void CompilerGLSL::unroll_array_from_complex_load(uint32_t target_id, uint32_t s statement(new_expr, "[i] = gl_in[i].", expr, ";"); else if (is_sample_mask) { - SPIRType target_type; + SPIRType target_type { OpTypeInt }; target_type.basetype = SPIRType::Int; statement(new_expr, "[i] = ", bitcast_expression(target_type, type.basetype, join(expr, "[i]")), ";"); } @@ -15419,7 +17770,7 @@ void CompilerGLSL::unroll_array_from_complex_load(uint32_t target_id, uint32_t s statement(new_expr, "[i] = ", expr, "[i];"); end_scope(); - expr = move(new_expr); + expr = std::move(new_expr); } } @@ -15435,7 +17786,12 @@ void CompilerGLSL::cast_from_variable_load(uint32_t source_id, std::string &expr // Only interested in standalone builtin variables. if (!has_decoration(source_id, DecorationBuiltIn)) + { + // Except for int attributes in legacy GLSL, which are cast from float. + if (is_legacy() && expr_type.basetype == SPIRType::Int && var && var->storage == StorageClassInput) + expr = join(type_to_glsl(expr_type), "(", expr, ")"); return; + } auto builtin = static_cast(get_decoration(source_id, DecorationBuiltIn)); auto expected_type = expr_type.basetype; @@ -15471,6 +17827,9 @@ void CompilerGLSL::cast_from_variable_load(uint32_t source_id, std::string &expr case BuiltInIncomingRayFlagsNV: case BuiltInLaunchIdNV: case BuiltInLaunchSizeNV: + case BuiltInPrimitiveTriangleIndicesEXT: + case BuiltInPrimitiveLineIndicesEXT: + case BuiltInPrimitivePointIndicesEXT: expected_type = SPIRType::UInt; break; @@ -15482,19 +17841,8 @@ void CompilerGLSL::cast_from_variable_load(uint32_t source_id, std::string &expr expr = bitcast_expression(expr_type, expected_type, expr); } -void CompilerGLSL::cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) +SPIRType::BaseType CompilerGLSL::get_builtin_basetype(BuiltIn builtin, SPIRType::BaseType default_type) { - auto *var = maybe_get_backing_variable(target_id); - if (var) - target_id = var->self; - - // Only interested in standalone builtin variables. - if (!has_decoration(target_id, DecorationBuiltIn)) - return; - - auto builtin = static_cast(get_decoration(target_id, DecorationBuiltIn)); - auto expected_type = expr_type.basetype; - // TODO: Fill in for more builtins. switch (builtin) { @@ -15505,12 +17853,25 @@ void CompilerGLSL::cast_to_variable_store(uint32_t target_id, std::string &expr, case BuiltInSampleMask: case BuiltInPrimitiveShadingRateKHR: case BuiltInShadingRateKHR: - expected_type = SPIRType::Int; - break; + return SPIRType::Int; default: - break; + return default_type; } +} + +void CompilerGLSL::cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) +{ + auto *var = maybe_get_backing_variable(target_id); + if (var) + target_id = var->self; + + // Only interested in standalone builtin variables. + if (!has_decoration(target_id, DecorationBuiltIn)) + return; + + auto builtin = static_cast(get_decoration(target_id, DecorationBuiltIn)); + auto expected_type = get_builtin_basetype(builtin, expr_type.basetype); if (expected_type != expr_type.basetype) { @@ -15626,6 +17987,52 @@ void CompilerGLSL::reset_name_caches() function_overloads.clear(); } +void CompilerGLSL::fixup_anonymous_struct_names(std::unordered_set &visited, const SPIRType &type) +{ + if (visited.count(type.self)) + return; + visited.insert(type.self); + + for (uint32_t i = 0; i < uint32_t(type.member_types.size()); i++) + { + auto &mbr_type = get(type.member_types[i]); + + if (mbr_type.basetype == SPIRType::Struct) + { + // If there are multiple aliases, the output might be somewhat unpredictable, + // but the only real alternative in that case is to do nothing, which isn't any better. + // This check should be fine in practice. + if (get_name(mbr_type.self).empty() && !get_member_name(type.self, i).empty()) + { + auto anon_name = join("anon_", get_member_name(type.self, i)); + ParsedIR::sanitize_underscores(anon_name); + set_name(mbr_type.self, anon_name); + } + + fixup_anonymous_struct_names(visited, mbr_type); + } + } +} + +void CompilerGLSL::fixup_anonymous_struct_names() +{ + // HLSL codegen can often end up emitting anonymous structs inside blocks, which + // breaks GL linking since all names must match ... + // Try to emit sensible code, so attempt to find such structs and emit anon_$member. + + // Breaks exponential explosion with weird type trees. + std::unordered_set visited; + + ir.for_each_typed_id([&](uint32_t, SPIRType &type) { + if (type.basetype == SPIRType::Struct && + (has_decoration(type.self, DecorationBlock) || + has_decoration(type.self, DecorationBufferBlock))) + { + fixup_anonymous_struct_names(visited, type); + } + }); +} + void CompilerGLSL::fixup_type_alias() { // Due to how some backends work, the "master" type of type_alias must be a block-like type if it exists. @@ -15678,7 +18085,7 @@ void CompilerGLSL::reorder_type_alias() if (alias_itr < master_itr) { // Must also swap the type order for the constant-type joined array. - auto &joined_types = ir.ids_for_constant_or_type; + auto &joined_types = ir.ids_for_constant_undef_or_type; auto alt_alias_itr = find(begin(joined_types), end(joined_types), *alias_itr); auto alt_master_itr = find(begin(joined_types), end(joined_types), *master_itr); assert(alt_alias_itr != end(joined_types)); @@ -15698,6 +18105,11 @@ void CompilerGLSL::emit_line_directive(uint32_t file_id, uint32_t line_literal) if (redirect_statement) return; + // If we're emitting code in a sensitive context such as condition blocks in for loops, don't emit + // any line directives, because it's not possible. + if (block_debug_directives) + return; + if (options.emit_line_directives) { require_extension_internal("GL_GOOGLE_cpp_style_line_directive"); @@ -15754,7 +18166,7 @@ void CompilerGLSL::emit_copy_logical_type(uint32_t lhs_id, uint32_t lhs_type_id, rhs_id = id + 1; { - auto &lhs_expr = set(lhs_id, move(lhs), lhs_type_id, true); + auto &lhs_expr = set(lhs_id, std::move(lhs), lhs_type_id, true); lhs_expr.need_transpose = lhs_meta.need_transpose; if (lhs_meta.storage_is_packed) @@ -15767,7 +18179,7 @@ void CompilerGLSL::emit_copy_logical_type(uint32_t lhs_id, uint32_t lhs_type_id, } { - auto &rhs_expr = set(rhs_id, move(rhs), rhs_type_id, true); + auto &rhs_expr = set(rhs_id, std::move(rhs), rhs_type_id, true); rhs_expr.need_transpose = rhs_meta.need_transpose; if (rhs_meta.storage_is_packed) @@ -15860,6 +18272,7 @@ const char *CompilerGLSL::ShaderSubgroupSupportHelper::get_extension_name(Candid static const char *const retval[CandidateCount] = { "GL_KHR_shader_subgroup_ballot", "GL_KHR_shader_subgroup_basic", "GL_KHR_shader_subgroup_vote", + "GL_KHR_shader_subgroup_arithmetic", "GL_NV_gpu_shader_5", "GL_NV_shader_thread_group", "GL_NV_shader_thread_shuffle", @@ -15908,6 +18321,21 @@ CompilerGLSL::ShaderSubgroupSupportHelper::FeatureVector CompilerGLSL::ShaderSub return { SubgroupMask }; case SubgroupBallotBitCount: return { SubgroupBallot }; + case SubgroupArithmeticIAddReduce: + case SubgroupArithmeticIAddInclusiveScan: + case SubgroupArithmeticFAddReduce: + case SubgroupArithmeticFAddInclusiveScan: + case SubgroupArithmeticIMulReduce: + case SubgroupArithmeticIMulInclusiveScan: + case SubgroupArithmeticFMulReduce: + case SubgroupArithmeticFMulInclusiveScan: + return { SubgroupSize, SubgroupBallot, SubgroupBallotBitCount, SubgroupMask, SubgroupBallotBitExtract }; + case SubgroupArithmeticIAddExclusiveScan: + case SubgroupArithmeticFAddExclusiveScan: + case SubgroupArithmeticIMulExclusiveScan: + case SubgroupArithmeticFMulExclusiveScan: + return { SubgroupSize, SubgroupBallot, SubgroupBallotBitCount, + SubgroupMask, SubgroupElect, SubgroupBallotBitExtract }; default: return {}; } @@ -15921,11 +18349,15 @@ CompilerGLSL::ShaderSubgroupSupportHelper::FeatureMask CompilerGLSL::ShaderSubgr bool CompilerGLSL::ShaderSubgroupSupportHelper::can_feature_be_implemented_without_extensions(Feature feature) { - static const bool retval[FeatureCount] = { false, false, false, false, false, false, - true, // SubgroupBalloFindLSB_MSB - false, false, false, false, - true, // SubgroupMemBarrier - replaced with workgroup memory barriers - false, false, true, false }; + static const bool retval[FeatureCount] = { + false, false, false, false, false, false, + true, // SubgroupBalloFindLSB_MSB + false, false, false, false, + true, // SubgroupMemBarrier - replaced with workgroup memory barriers + false, false, true, false, + false, false, false, false, false, false, // iadd, fadd + false, false, false, false, false, false, // imul , fmul + }; return retval[feature]; } @@ -15937,7 +18369,11 @@ CompilerGLSL::ShaderSubgroupSupportHelper::Candidate CompilerGLSL::ShaderSubgrou KHR_shader_subgroup_ballot, KHR_shader_subgroup_basic, KHR_shader_subgroup_basic, KHR_shader_subgroup_basic, KHR_shader_subgroup_basic, KHR_shader_subgroup_ballot, KHR_shader_subgroup_ballot, KHR_shader_subgroup_vote, KHR_shader_subgroup_vote, KHR_shader_subgroup_basic, KHR_shader_subgroup_basic, KHR_shader_subgroup_basic, - KHR_shader_subgroup_ballot, KHR_shader_subgroup_ballot, KHR_shader_subgroup_ballot, KHR_shader_subgroup_ballot + KHR_shader_subgroup_ballot, KHR_shader_subgroup_ballot, KHR_shader_subgroup_ballot, KHR_shader_subgroup_ballot, + KHR_shader_subgroup_arithmetic, KHR_shader_subgroup_arithmetic, KHR_shader_subgroup_arithmetic, + KHR_shader_subgroup_arithmetic, KHR_shader_subgroup_arithmetic, KHR_shader_subgroup_arithmetic, + KHR_shader_subgroup_arithmetic, KHR_shader_subgroup_arithmetic, KHR_shader_subgroup_arithmetic, + KHR_shader_subgroup_arithmetic, KHR_shader_subgroup_arithmetic, KHR_shader_subgroup_arithmetic, }; return extensions[feature]; @@ -16033,6 +18469,19 @@ CompilerGLSL::ShaderSubgroupSupportHelper::CandidateVector CompilerGLSL::ShaderS return { NV_shader_thread_group }; case SubgroupBallotBitCount: return {}; + case SubgroupArithmeticIAddReduce: + case SubgroupArithmeticIAddExclusiveScan: + case SubgroupArithmeticIAddInclusiveScan: + case SubgroupArithmeticFAddReduce: + case SubgroupArithmeticFAddExclusiveScan: + case SubgroupArithmeticFAddInclusiveScan: + case SubgroupArithmeticIMulReduce: + case SubgroupArithmeticIMulExclusiveScan: + case SubgroupArithmeticIMulInclusiveScan: + case SubgroupArithmeticFMulReduce: + case SubgroupArithmeticFMulExclusiveScan: + case SubgroupArithmeticFMulInclusiveScan: + return { KHR_shader_subgroup_arithmetic, NV_shader_thread_shuffle }; default: return {}; } @@ -16057,6 +18506,7 @@ CompilerGLSL::ShaderSubgroupSupportHelper::Result::Result() weights[KHR_shader_subgroup_ballot] = big_num; weights[KHR_shader_subgroup_basic] = big_num; weights[KHR_shader_subgroup_vote] = big_num; + weights[KHR_shader_subgroup_arithmetic] = big_num; } void CompilerGLSL::request_workaround_wrapper_overload(TypeID id) @@ -16087,6 +18537,7 @@ void CompilerGLSL::rewrite_load_for_wrapped_row_major(std::string &expr, TypeID auto *type = &get(loaded_type); bool rewrite = false; + bool relaxed = options.es; if (is_matrix(*type)) { @@ -16097,24 +18548,31 @@ void CompilerGLSL::rewrite_load_for_wrapped_row_major(std::string &expr, TypeID // If an access chain occurred, the workaround is not required, so loading vectors or scalars don't need workaround. type = &backing_type; } + else + { + // If we're loading a composite, we don't have overloads like these. + relaxed = false; + } if (type->basetype == SPIRType::Struct) { // If we're loading a struct where any member is a row-major matrix, apply the workaround. for (uint32_t i = 0; i < uint32_t(type->member_types.size()); i++) { - if (combined_decoration_for_member(*type, i).get(DecorationRowMajor)) - { + auto decorations = combined_decoration_for_member(*type, i); + if (decorations.get(DecorationRowMajor)) rewrite = true; - break; - } + + // Since we decide on a per-struct basis, only use mediump wrapper if all candidates are mediump. + if (!decorations.get(DecorationRelaxedPrecision)) + relaxed = false; } } if (rewrite) { request_workaround_wrapper_overload(loaded_type); - expr = join("spvWorkaroundRowMajor(", expr, ")"); + expr = join("spvWorkaroundRowMajor", (relaxed ? "MP" : ""), "(", expr, ")"); } } @@ -16173,6 +18631,22 @@ bool CompilerGLSL::is_stage_output_block_member_masked(const SPIRVariable &var, } } +bool CompilerGLSL::is_per_primitive_variable(const SPIRVariable &var) const +{ + if (has_decoration(var.self, DecorationPerPrimitiveEXT)) + return true; + + auto &type = get(var.basetype); + if (!has_decoration(type.self, DecorationBlock)) + return false; + + for (uint32_t i = 0, n = uint32_t(type.member_types.size()); i < n; i++) + if (!has_member_decoration(type.self, i, DecorationPerPrimitiveEXT)) + return false; + + return true; +} + bool CompilerGLSL::is_stage_output_location_masked(uint32_t location, uint32_t component) const { return masked_output_locations.count({ location, component }) != 0; @@ -16263,3 +18737,22 @@ uint32_t CompilerGLSL::type_to_location_count(const SPIRType &type) const return count; } + +std::string CompilerGLSL::format_float(float value) const +{ + if (float_formatter) + return float_formatter->format_float(value); + + // default behavior + return convert_to_string(value, current_locale_radix_character); +} + +std::string CompilerGLSL::format_double(double value) const +{ + if (float_formatter) + return float_formatter->format_double(value); + + // default behavior + return convert_to_string(value, current_locale_radix_character); +} + diff --git a/src/libraries/spirv_cross/spirv_glsl.hpp b/src/libraries/spirv_cross/spirv_glsl.hpp index b34ed9930..c04ef88bf 100644 --- a/src/libraries/spirv_cross/spirv_glsl.hpp +++ b/src/libraries/spirv_cross/spirv_glsl.hpp @@ -83,6 +83,11 @@ class CompilerGLSL : public Compiler // Debug option to always emit temporary variables for all expressions. bool force_temporary = false; + // Debug option, can be increased in an attempt to workaround SPIRV-Cross bugs temporarily. + // If this limit has to be increased, it points to an implementation bug. + // In certain scenarios, the maximum number of debug iterations may increase beyond this limit + // as long as we can prove we're making certain kinds of forward progress. + uint32_t force_recompile_max_debug_iterations = 3; // If true, Vulkan GLSL features are used instead of GL-compatible features. // Mostly useful for debugging SPIR-V files. @@ -133,6 +138,19 @@ class CompilerGLSL : public Compiler // what happens on legacy GLSL targets for blocks and structs. bool force_flattened_io_blocks = false; + // For opcodes where we have to perform explicit additional nan checks, very ugly code is generated. + // If we opt-in, ignore these requirements. + // In opcodes like NClamp/NMin/NMax and FP compare, ignore NaN behavior. + // Use FClamp/FMin/FMax semantics for clamps and lets implementation choose ordered or unordered + // compares. + bool relax_nan_checks = false; + + // Loading row-major matrices from UBOs on older AMD Windows OpenGL drivers is problematic. + // To load these types correctly, we must generate a wrapper. them in a dummy function which only purpose is to + // ensure row_major decoration is actually respected. + // This workaround may cause significant performance degeneration on some Android devices. + bool enable_row_major_load_workaround = true; + // If non-zero, controls layout(num_views = N) in; in GL_OVR_multiview2. uint32_t ovr_multiview_view_count = 0; @@ -240,6 +258,10 @@ class CompilerGLSL : public Compiler // require_extension("GL_KHR_my_extension"); void require_extension(const std::string &ext); + // Returns the list of required extensions. After compilation this will contains any other + // extensions that the compiler used automatically, in addition to the user specified ones. + const SmallVector &get_required_extensions() const; + // Legacy GLSL compatibility method. // Takes a uniform or push constant variable and flattens it into a (i|u)vec4 array[N]; array instead. // For this to work, all types in the block must be the same basic type, e.g. mixing vec2 and vec4 is fine, but @@ -265,6 +287,14 @@ class CompilerGLSL : public Compiler void mask_stage_output_by_location(uint32_t location, uint32_t component); void mask_stage_output_by_builtin(spv::BuiltIn builtin); + // Allow to control how to format float literals in the output. + // Set to "nullptr" to use the default "convert_to_string" function. + // This handle is not owned by SPIRV-Cross and must remain valid until compile() has been called. + void set_float_formatter(FloatFormatter *formatter) + { + float_formatter = formatter; + } + protected: struct ShaderSubgroupSupportHelper { @@ -274,6 +304,7 @@ class CompilerGLSL : public Compiler KHR_shader_subgroup_ballot, KHR_shader_subgroup_basic, KHR_shader_subgroup_vote, + KHR_shader_subgroup_arithmetic, NV_gpu_shader_5, NV_shader_thread_group, NV_shader_thread_shuffle, @@ -306,7 +337,18 @@ class CompilerGLSL : public Compiler SubgroupInverseBallot_InclBitCount_ExclBitCout = 13, SubgroupBallotBitExtract = 14, SubgroupBallotBitCount = 15, - + SubgroupArithmeticIAddReduce = 16, + SubgroupArithmeticIAddExclusiveScan = 17, + SubgroupArithmeticIAddInclusiveScan = 18, + SubgroupArithmeticFAddReduce = 19, + SubgroupArithmeticFAddExclusiveScan = 20, + SubgroupArithmeticFAddInclusiveScan = 21, + SubgroupArithmeticIMulReduce = 22, + SubgroupArithmeticIMulExclusiveScan = 23, + SubgroupArithmeticIMulInclusiveScan = 24, + SubgroupArithmeticFMulReduce = 25, + SubgroupArithmeticFMulExclusiveScan = 26, + SubgroupArithmeticFMulInclusiveScan = 27, FeatureCount }; @@ -340,9 +382,9 @@ class CompilerGLSL : public Compiler }; // TODO remove this function when all subgroup ops are supported (or make it always return true) - static bool is_supported_subgroup_op_in_opengl(spv::Op op); + static bool is_supported_subgroup_op_in_opengl(spv::Op op, const uint32_t *ops); - void reset(); + void reset(uint32_t iteration_count); void emit_function(SPIRFunction &func, const Bitset &return_flags); bool has_extension(const std::string &ext) const; @@ -352,11 +394,23 @@ class CompilerGLSL : public Compiler virtual void emit_function_prototype(SPIRFunction &func, const Bitset &return_flags); SPIRBlock *current_emitting_block = nullptr; - SPIRBlock *current_emitting_switch = nullptr; + SmallVector current_emitting_switch_stack; bool current_emitting_switch_fallthrough = false; virtual void emit_instruction(const Instruction &instr); + struct TemporaryCopy + { + uint32_t dst_id; + uint32_t src_id; + }; + TemporaryCopy handle_instruction_precision(const Instruction &instr); void emit_block_instructions(SPIRBlock &block); + void emit_block_instructions_with_masked_debug(SPIRBlock &block); + + // For relax_nan_checks. + GLSLstd450 get_remapped_glsl_op(GLSLstd450 std450_op) const; + spv::Op get_remapped_spirv_op(spv::Op op) const; + virtual void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args, uint32_t count); virtual void emit_spv_amd_shader_ballot_op(uint32_t result_type, uint32_t result_id, uint32_t op, @@ -385,7 +439,9 @@ class CompilerGLSL : public Compiler const std::string &qualifier = "", uint32_t base_offset = 0); virtual void emit_struct_padding_target(const SPIRType &type); virtual std::string image_type_glsl(const SPIRType &type, uint32_t id = 0); - std::string constant_expression(const SPIRConstant &c); + std::string constant_expression(const SPIRConstant &c, + bool inside_block_like_struct_scope = false, + bool inside_struct_scope = false); virtual std::string constant_op_expression(const SPIRConstantOp &cop); virtual std::string constant_expression_vector(const SPIRConstant &c, uint32_t vector); virtual void emit_fixup(); @@ -419,7 +475,7 @@ class CompilerGLSL : public Compiler TextureFunctionArguments() = default; TextureFunctionBaseArguments base; uint32_t coord = 0, coord_components = 0, dref = 0; - uint32_t grad_x = 0, grad_y = 0, lod = 0, coffset = 0, offset = 0; + uint32_t grad_x = 0, grad_y = 0, lod = 0, offset = 0; uint32_t bias = 0, component = 0, sample = 0, sparse_texel = 0, min_lod = 0; bool nonuniform_expression = false; }; @@ -436,6 +492,8 @@ class CompilerGLSL : public Compiler virtual bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const; + virtual bool is_user_type_structured(uint32_t id) const; + void emit_copy_logical_type(uint32_t lhs_id, uint32_t lhs_type_id, uint32_t rhs_id, uint32_t rhs_type_id, SmallVector chain); @@ -495,6 +553,8 @@ class CompilerGLSL : public Compiler // on a single line separated by comma. SmallVector *redirect_statement = nullptr; const SPIRBlock *current_continue_block = nullptr; + bool block_temporary_hoisting = false; + bool block_debug_directives = false; void begin_scope(); void end_scope(); @@ -522,7 +582,8 @@ class CompilerGLSL : public Compiler bool member_is_remapped_physical_type(const SPIRType &type, uint32_t index) const; bool member_is_packed_physical_type(const SPIRType &type, uint32_t index) const; virtual std::string convert_row_major_matrix(std::string exp_str, const SPIRType &exp_type, - uint32_t physical_type_id, bool is_packed); + uint32_t physical_type_id, bool is_packed, + bool relaxed = false); std::unordered_set local_variable_names; std::unordered_set resource_names; @@ -559,6 +620,7 @@ class CompilerGLSL : public Compiler const char *uint16_t_literal_suffix = "us"; const char *nonuniform_qualifier = "nonuniformEXT"; const char *boolean_mix_function = "mix"; + SPIRType::BaseType boolean_in_struct_remapped_type = SPIRType::Boolean; bool swizzle_is_function = false; bool shared_is_implied = false; bool unsized_array_supported = true; @@ -572,12 +634,13 @@ class CompilerGLSL : public Compiler bool allow_precision_qualifiers = false; bool can_swizzle_scalar = false; bool force_gl_in_out_block = false; + bool force_merged_mesh_block = false; bool can_return_array = true; bool allow_truncated_access_chain = false; bool supports_extensions = false; bool supports_empty_struct = false; bool array_is_value_type = true; - bool buffer_offset_array_is_value_type = true; + bool array_is_value_type_in_buffer_blocks = true; bool comparison_image_samples_scalar = false; bool native_pointers = false; bool support_small_type_sampling_result = false; @@ -587,16 +650,21 @@ class CompilerGLSL : public Compiler bool support_pointer_to_pointer = false; bool support_precise_qualifier = false; bool support_64bit_switch = false; + bool workgroup_size_is_hidden = false; + bool requires_relaxed_precision_analysis = false; + bool implicit_c_integer_promotion_rules = false; } backend; void emit_struct(SPIRType &type); void emit_resources(); void emit_extension_workarounds(spv::ExecutionModel model); + void emit_subgroup_arithmetic_workaround(const std::string &func, spv::Op op, spv::GroupOperation group_op); + void emit_polyfills(uint32_t polyfills, bool relaxed); void emit_buffer_block_native(const SPIRVariable &var); void emit_buffer_reference_block(uint32_t type_id, bool forward_declaration); void emit_buffer_block_legacy(const SPIRVariable &var); void emit_buffer_block_flattened(const SPIRVariable &type); - void fixup_implicit_builtin_block_names(); + void fixup_implicit_builtin_block_names(spv::ExecutionModel model); void emit_declared_builtin_block(spv::StorageClass storage, spv::ExecutionModel model); bool should_force_emit_builtin_block(spv::StorageClass storage); void emit_push_constant_block_vulkan(const SPIRVariable &var); @@ -610,6 +678,7 @@ class CompilerGLSL : public Compiler void emit_block_chain(SPIRBlock &block); void emit_hoisted_temporaries(SmallVector> &temporaries); std::string constant_value_macro_name(uint32_t id); + int get_constant_mapping_to_workgroup_component(const SPIRConstant &constant) const; void emit_constant(const SPIRConstant &constant); void emit_specialization_constant_op(const SPIRConstantOp &constant); std::string emit_continue_block(uint32_t continue_block, bool follow_true_block, bool follow_false_block); @@ -628,6 +697,7 @@ class CompilerGLSL : public Compiler bool should_suppress_usage_tracking(uint32_t id) const; void emit_mix_op(uint32_t result_type, uint32_t id, uint32_t left, uint32_t right, uint32_t lerp); void emit_nminmax_op(uint32_t result_type, uint32_t id, uint32_t op0, uint32_t op1, GLSLstd450 op); + void emit_emulated_ahyper_op(uint32_t result_type, uint32_t result_id, uint32_t op0, GLSLstd450 op); bool to_trivial_mix_op(const SPIRType &type, std::string &op, uint32_t left, uint32_t right, uint32_t lerp); void emit_quaternary_func_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, uint32_t op2, uint32_t op3, const char *op); @@ -658,7 +728,7 @@ class CompilerGLSL : public Compiler void emit_unrolled_binary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op, bool negate, SPIRType::BaseType expected_type); void emit_binary_op_cast(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op, - SPIRType::BaseType input_type, bool skip_cast_if_equal_type); + SPIRType::BaseType input_type, bool skip_cast_if_equal_type, bool implicit_integer_promotion); SPIRType binary_op_bitcast_helper(std::string &cast_op0, std::string &cast_op1, SPIRType::BaseType &input_type, uint32_t op0, uint32_t op1, bool skip_cast_if_equal_type); @@ -669,6 +739,8 @@ class CompilerGLSL : public Compiler uint32_t false_value); void emit_unary_op(uint32_t result_type, uint32_t result_id, uint32_t op0, const char *op); + void emit_unary_op_cast(uint32_t result_type, uint32_t result_id, uint32_t op0, const char *op); + virtual void emit_mesh_tasks(SPIRBlock &block); bool expression_is_forwarded(uint32_t id) const; bool expression_suppresses_usage_tracking(uint32_t id) const; bool expression_read_implies_multiple_reads(uint32_t id) const; @@ -684,7 +756,8 @@ class CompilerGLSL : public Compiler spv::StorageClass get_expression_effective_storage_class(uint32_t ptr); virtual bool access_chain_needs_stage_io_builtin_translation(uint32_t base); - virtual void prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, + virtual void check_physical_type_cast(std::string &expr, const SPIRType *type, uint32_t physical_type); + virtual bool prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, spv::StorageClass storage, bool &is_packed); std::string access_chain(uint32_t base, const uint32_t *indices, uint32_t count, const SPIRType &target_type, @@ -716,8 +789,8 @@ class CompilerGLSL : public Compiler void append_global_func_args(const SPIRFunction &func, uint32_t index, SmallVector &arglist); std::string to_non_uniform_aware_expression(uint32_t id); std::string to_expression(uint32_t id, bool register_expression_read = true); - std::string to_composite_constructor_expression(uint32_t id, bool uses_buffer_offset); - std::string to_rerolled_array_expression(const std::string &expr, const SPIRType &type); + std::string to_composite_constructor_expression(const SPIRType &parent_type, uint32_t id, bool block_like_type); + std::string to_rerolled_array_expression(const SPIRType &parent_type, const std::string &expr, const SPIRType &type); std::string to_enclosed_expression(uint32_t id, bool register_expression_read = true); std::string to_unpacked_expression(uint32_t id, bool register_expression_read = true); std::string to_unpacked_row_major_matrix_expression(uint32_t id); @@ -728,17 +801,18 @@ class CompilerGLSL : public Compiler std::string to_extract_component_expression(uint32_t id, uint32_t index); std::string to_extract_constant_composite_expression(uint32_t result_type, const SPIRConstant &c, const uint32_t *chain, uint32_t length); + static bool needs_enclose_expression(const std::string &expr); std::string enclose_expression(const std::string &expr); std::string dereference_expression(const SPIRType &expression_type, const std::string &expr); std::string address_of_expression(const std::string &expr); void strip_enclosed_expression(std::string &expr); std::string to_member_name(const SPIRType &type, uint32_t index); - virtual std::string to_member_reference(uint32_t base, const SPIRType &type, uint32_t index, bool ptr_chain); + virtual std::string to_member_reference(uint32_t base, const SPIRType &type, uint32_t index, bool ptr_chain_is_resolved); std::string to_multi_member_reference(const SPIRType &type, const SmallVector &indices); std::string type_to_glsl_constructor(const SPIRType &type); std::string argument_decl(const SPIRFunction::Parameter &arg); virtual std::string to_qualifiers_glsl(uint32_t id); - void fixup_io_block_patch_qualifiers(const SPIRVariable &var); + void fixup_io_block_patch_primitive_qualifiers(const SPIRVariable &var); void emit_output_variable_initializer(const SPIRVariable &var); std::string to_precision_qualifiers_glsl(uint32_t id); virtual const char *to_storage_qualifiers_glsl(const SPIRVariable &var); @@ -749,7 +823,7 @@ class CompilerGLSL : public Compiler std::string layout_for_variable(const SPIRVariable &variable); std::string to_combined_image_sampler(VariableID image_id, VariableID samp_id); virtual bool skip_argument(uint32_t id) const; - virtual void emit_array_copy(const std::string &lhs, uint32_t lhs_id, uint32_t rhs_id, + virtual bool emit_array_copy(const char *expr, uint32_t lhs_id, uint32_t rhs_id, spv::StorageClass lhs_storage, spv::StorageClass rhs_storage); virtual void emit_block_hints(const SPIRBlock &block); virtual std::string to_initializer_expression(const SPIRVariable &var); @@ -789,6 +863,10 @@ class CompilerGLSL : public Compiler void replace_fragment_outputs(); std::string legacy_tex_op(const std::string &op, const SPIRType &imgtype, uint32_t id); + void forward_relaxed_precision(uint32_t dst_id, const uint32_t *args, uint32_t length); + void analyze_precision_requirements(uint32_t type_id, uint32_t dst_id, uint32_t *args, uint32_t length); + Options::Precision analyze_expression_precision(const uint32_t *args, uint32_t length) const; + uint32_t indent = 0; std::unordered_set emitted_functions; @@ -842,10 +920,25 @@ class CompilerGLSL : public Compiler return !options.es && options.version < 130; } - bool requires_transpose_2x2 = false; - bool requires_transpose_3x3 = false; - bool requires_transpose_4x4 = false; + enum Polyfill : uint32_t + { + PolyfillTranspose2x2 = 1 << 0, + PolyfillTranspose3x3 = 1 << 1, + PolyfillTranspose4x4 = 1 << 2, + PolyfillDeterminant2x2 = 1 << 3, + PolyfillDeterminant3x3 = 1 << 4, + PolyfillDeterminant4x4 = 1 << 5, + PolyfillMatrixInverse2x2 = 1 << 6, + PolyfillMatrixInverse3x3 = 1 << 7, + PolyfillMatrixInverse4x4 = 1 << 8, + }; + + uint32_t required_polyfills = 0; + uint32_t required_polyfills_relaxed = 0; + void require_polyfill(Polyfill polyfill, bool relaxed); + bool ray_tracing_is_khr = false; + bool barycentric_is_nv = false; void ray_tracing_khr_fixup_locations(); bool args_will_forward(uint32_t id, const uint32_t *args, uint32_t num_args, bool pure); @@ -879,8 +972,14 @@ class CompilerGLSL : public Compiler void check_function_call_constraints(const uint32_t *args, uint32_t length); void handle_invalid_expression(uint32_t id); + void force_temporary_and_recompile(uint32_t id); void find_static_extensions(); + uint32_t consume_temporary_in_precision_context(uint32_t type_id, uint32_t id, Options::Precision precision); + std::unordered_map temporary_to_mirror_precision_alias; + std::unordered_set composite_insert_overwritten; + std::unordered_set block_composite_insert_overwrite; + std::string emit_for_loop_initializers(const SPIRBlock &block); void emit_while_loop_initializers(const SPIRBlock &block); bool for_loop_initializers_are_same_type(const SPIRBlock &block); @@ -889,8 +988,6 @@ class CompilerGLSL : public Compiler bool type_is_empty(const SPIRType &type); - virtual void declare_undefined_values(); - bool can_use_io_location(spv::StorageClass storage, bool block); const Instruction *get_next_instruction_in_block(const Instruction &instr); static uint32_t mask_relevant_memory_semantics(uint32_t semantics); @@ -904,6 +1001,7 @@ class CompilerGLSL : public Compiler // Builtins in GLSL are always specific signedness, but the SPIR-V can declare them // as either unsigned or signed. // Sometimes we will need to automatically perform casts on load and store to make this work. + virtual SPIRType::BaseType get_builtin_basetype(spv::BuiltIn builtin, SPIRType::BaseType default_type); virtual void cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type); virtual void cast_from_variable_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type); void unroll_array_from_complex_load(uint32_t target_id, uint32_t source_id, std::string &expr); @@ -926,6 +1024,8 @@ class CompilerGLSL : public Compiler void fixup_type_alias(); void reorder_type_alias(); + void fixup_anonymous_struct_names(); + void fixup_anonymous_struct_names(std::unordered_set &visited, const SPIRType &type); static const char *vector_swizzle(int vecsize, int index); @@ -933,13 +1033,24 @@ class CompilerGLSL : public Compiler bool is_stage_output_builtin_masked(spv::BuiltIn builtin) const; bool is_stage_output_variable_masked(const SPIRVariable &var) const; bool is_stage_output_block_member_masked(const SPIRVariable &var, uint32_t index, bool strip_array) const; + bool is_per_primitive_variable(const SPIRVariable &var) const; uint32_t get_accumulated_member_location(const SPIRVariable &var, uint32_t mbr_idx, bool strip_array) const; uint32_t get_declared_member_location(const SPIRVariable &var, uint32_t mbr_idx, bool strip_array) const; std::unordered_set masked_output_locations; std::unordered_set masked_output_builtins; + FloatFormatter *float_formatter = nullptr; + std::string format_float(float value) const; + std::string format_double(double value) const; + private: void init(); + + SmallVector get_composite_constant_ids(ConstantID const_id); + void fill_composite_constant(SPIRConstant &constant, TypeID type_id, const SmallVector &initializers); + void set_composite_constant(ConstantID const_id, TypeID type_id, const SmallVector &initializers); + TypeID get_composite_member_type(TypeID type_id, uint32_t member_idx); + std::unordered_map> const_composite_insert_ids; }; } // namespace SPIRV_CROSS_NAMESPACE diff --git a/src/libraries/spirv_cross/spirv_hlsl.cpp b/src/libraries/spirv_cross/spirv_hlsl.cpp index bdcb6dd37..9b8349365 100644 --- a/src/libraries/spirv_cross/spirv_hlsl.cpp +++ b/src/libraries/spirv_cross/spirv_hlsl.cpp @@ -462,6 +462,10 @@ string CompilerHLSL::type_to_glsl(const SPIRType &type, uint32_t id) if (hlsl_options.shader_model < 60) SPIRV_CROSS_THROW("64-bit integers only supported in SM 6.0."); return "uint64_t"; + case SPIRType::AccelerationStructure: + return "RaytracingAccelerationStructure"; + case SPIRType::RayQuery: + return "RayQuery"; default: return "???"; } @@ -599,50 +603,158 @@ void CompilerHLSL::emit_builtin_outputs_in_struct() break; case BuiltInClipDistance: + { + static const char *types[] = { "float", "float2", "float3", "float4" }; + // HLSL is a bit weird here, use SV_ClipDistance0, SV_ClipDistance1 and so on with vectors. - for (uint32_t clip = 0; clip < clip_distance_count; clip += 4) + if (execution.model == ExecutionModelMeshEXT) { - uint32_t to_declare = clip_distance_count - clip; - if (to_declare > 4) - to_declare = 4; + if (clip_distance_count > 4) + SPIRV_CROSS_THROW("Clip distance count > 4 not supported for mesh shaders."); - uint32_t semantic_index = clip / 4; + if (clip_distance_count == 1) + { + // Avoids having to hack up access_chain code. Makes it trivially indexable. + statement("float gl_ClipDistance[1] : SV_ClipDistance;"); + } + else + { + // Replace array with vector directly, avoids any weird fixup path. + statement(types[clip_distance_count - 1], " gl_ClipDistance : SV_ClipDistance;"); + } + } + else + { + for (uint32_t clip = 0; clip < clip_distance_count; clip += 4) + { + uint32_t to_declare = clip_distance_count - clip; + if (to_declare > 4) + to_declare = 4; - static const char *types[] = { "float", "float2", "float3", "float4" }; - statement(types[to_declare - 1], " ", builtin_to_glsl(builtin, StorageClassOutput), semantic_index, - " : SV_ClipDistance", semantic_index, ";"); + uint32_t semantic_index = clip / 4; + + statement(types[to_declare - 1], " ", builtin_to_glsl(builtin, StorageClassOutput), semantic_index, + " : SV_ClipDistance", semantic_index, ";"); + } } break; + } case BuiltInCullDistance: + { + static const char *types[] = { "float", "float2", "float3", "float4" }; + // HLSL is a bit weird here, use SV_CullDistance0, SV_CullDistance1 and so on with vectors. - for (uint32_t cull = 0; cull < cull_distance_count; cull += 4) + if (execution.model == ExecutionModelMeshEXT) { - uint32_t to_declare = cull_distance_count - cull; - if (to_declare > 4) - to_declare = 4; + if (cull_distance_count > 4) + SPIRV_CROSS_THROW("Cull distance count > 4 not supported for mesh shaders."); - uint32_t semantic_index = cull / 4; + if (cull_distance_count == 1) + { + // Avoids having to hack up access_chain code. Makes it trivially indexable. + statement("float gl_CullDistance[1] : SV_CullDistance;"); + } + else + { + // Replace array with vector directly, avoids any weird fixup path. + statement(types[cull_distance_count - 1], " gl_CullDistance : SV_CullDistance;"); + } + } + else + { + for (uint32_t cull = 0; cull < cull_distance_count; cull += 4) + { + uint32_t to_declare = cull_distance_count - cull; + if (to_declare > 4) + to_declare = 4; - static const char *types[] = { "float", "float2", "float3", "float4" }; - statement(types[to_declare - 1], " ", builtin_to_glsl(builtin, StorageClassOutput), semantic_index, - " : SV_CullDistance", semantic_index, ";"); + uint32_t semantic_index = cull / 4; + + statement(types[to_declare - 1], " ", builtin_to_glsl(builtin, StorageClassOutput), semantic_index, + " : SV_CullDistance", semantic_index, ";"); + } } break; + } case BuiltInPointSize: // If point_size_compat is enabled, just ignore PointSize. // PointSize does not exist in HLSL, but some code bases might want to be able to use these shaders, // even if it means working around the missing feature. - if (hlsl_options.point_size_compat) - break; - else + if (legacy) + { + type = "float"; + semantic = "PSIZE"; + } + else if (!hlsl_options.point_size_compat) SPIRV_CROSS_THROW("Unsupported builtin in HLSL."); + break; + + case BuiltInLayer: + case BuiltInPrimitiveId: + case BuiltInViewportIndex: + case BuiltInPrimitiveShadingRateKHR: + case BuiltInCullPrimitiveEXT: + // per-primitive attributes handled separatly + break; + + case BuiltInPrimitivePointIndicesEXT: + case BuiltInPrimitiveLineIndicesEXT: + case BuiltInPrimitiveTriangleIndicesEXT: + // meshlet local-index buffer handled separatly + break; default: SPIRV_CROSS_THROW("Unsupported builtin in HLSL."); } + if (type && semantic) + statement(type, " ", builtin_to_glsl(builtin, StorageClassOutput), " : ", semantic, ";"); + }); +} + +void CompilerHLSL::emit_builtin_primitive_outputs_in_struct() +{ + active_output_builtins.for_each_bit([&](uint32_t i) { + const char *type = nullptr; + const char *semantic = nullptr; + auto builtin = static_cast(i); + switch (builtin) + { + case BuiltInLayer: + { + if (hlsl_options.shader_model < 50) + SPIRV_CROSS_THROW("Render target array index output is only supported in SM 5.0 or higher."); + type = "uint"; + semantic = "SV_RenderTargetArrayIndex"; + break; + } + + case BuiltInPrimitiveId: + type = "uint"; + semantic = "SV_PrimitiveID"; + break; + + case BuiltInViewportIndex: + type = "uint"; + semantic = "SV_ViewportArrayIndex"; + break; + + case BuiltInPrimitiveShadingRateKHR: + type = "uint"; + semantic = "SV_ShadingRate"; + break; + + case BuiltInCullPrimitiveEXT: + type = "bool"; + semantic = "SV_CullPrimitive"; + break; + + default: + break; + } + if (type && semantic) statement(type, " ", builtin_to_glsl(builtin, StorageClassOutput), " : ", semantic, ";"); }); @@ -670,6 +782,11 @@ void CompilerHLSL::emit_builtin_inputs_in_struct() semantic = "SV_VertexID"; break; + case BuiltInPrimitiveId: + type = "uint"; + semantic = "SV_PrimitiveID"; + break; + case BuiltInInstanceId: case BuiltInInstanceIndex: if (legacy) @@ -717,6 +834,13 @@ void CompilerHLSL::emit_builtin_inputs_in_struct() semantic = "SV_IsFrontFace"; break; + case BuiltInViewIndex: + if (hlsl_options.shader_model < 61 || (get_entry_point().model != ExecutionModelVertex && get_entry_point().model != ExecutionModelFragment)) + SPIRV_CROSS_THROW("View Index input is only supported in VS and PS 6.1 or higher."); + type = "uint"; + semantic = "SV_ViewID"; + break; + case BuiltInNumWorkgroups: case BuiltInSubgroupSize: case BuiltInSubgroupLocalInvocationId: @@ -725,9 +849,16 @@ void CompilerHLSL::emit_builtin_inputs_in_struct() case BuiltInSubgroupLeMask: case BuiltInSubgroupGtMask: case BuiltInSubgroupGeMask: + case BuiltInBaseVertex: + case BuiltInBaseInstance: // Handled specially. break; + case BuiltInHelperInvocation: + if (hlsl_options.shader_model < 50 || get_entry_point().model != ExecutionModelFragment) + SPIRV_CROSS_THROW("Helper Invocation input is only supported in PS 5.0 or higher."); + break; + case BuiltInClipDistance: // HLSL is a bit weird here, use SV_ClipDistance0, SV_ClipDistance1 and so on with vectors. for (uint32_t clip = 0; clip < clip_distance_count; clip += 4) @@ -767,6 +898,13 @@ void CompilerHLSL::emit_builtin_inputs_in_struct() else SPIRV_CROSS_THROW("Unsupported builtin in HLSL."); + case BuiltInLayer: + if (hlsl_options.shader_model < 50 || get_entry_point().model != ExecutionModelFragment) + SPIRV_CROSS_THROW("Render target array index input is only supported in PS 5.0 or higher."); + type = "uint"; + semantic = "SV_RenderTargetArrayIndex"; + break; + default: SPIRV_CROSS_THROW("Unsupported builtin in HLSL."); } @@ -880,6 +1018,7 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord string binding; bool use_location_number = true; + bool need_matrix_unroll = false; bool legacy = hlsl_options.shader_model <= 30; if (execution.model == ExecutionModelFragment && var.storage == StorageClassOutput) { @@ -895,6 +1034,12 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord if (legacy) // COLOR must be a four-component vector on legacy shader model targets (HLSL ERR_COLOR_4COMP) type.vecsize = 4; } + else if (var.storage == StorageClassInput && execution.model == ExecutionModelVertex) + { + need_matrix_unroll = true; + if (legacy) // Inputs must be floating-point in legacy targets. + type.basetype = SPIRType::Float; + } const auto get_vacant_location = [&]() -> uint32_t { for (uint32_t i = 0; i < 64; i++) @@ -903,8 +1048,6 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord SPIRV_CROSS_THROW("All locations from 0 to 63 are exhausted."); }; - bool need_matrix_unroll = var.storage == StorageClassInput && execution.model == ExecutionModelVertex; - auto name = to_name(var.self); if (use_location_number) { @@ -944,17 +1087,25 @@ void CompilerHLSL::emit_interface_block_in_struct(const SPIRVariable &var, unord } else { - statement(to_interpolation_qualifiers(get_decoration_bitset(var.self)), variable_decl(type, name), " : ", + auto decl_type = type; + if (execution.model == ExecutionModelMeshEXT) + { + decl_type.array.erase(decl_type.array.begin()); + decl_type.array_size_literal.erase(decl_type.array_size_literal.begin()); + } + statement(to_interpolation_qualifiers(get_decoration_bitset(var.self)), variable_decl(decl_type, name), " : ", semantic, ";"); // Structs and arrays should consume more locations. - uint32_t consumed_locations = type_to_consumed_locations(type); + uint32_t consumed_locations = type_to_consumed_locations(decl_type); for (uint32_t i = 0; i < consumed_locations; i++) active_locations.insert(location_number + i); } } else + { statement(variable_decl(type, name), " : ", binding, ";"); + } } std::string CompilerHLSL::builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClass storage) @@ -984,6 +1135,8 @@ std::string CompilerHLSL::builtin_to_glsl(spv::BuiltIn builtin, spv::StorageClas return "WaveGetLaneIndex()"; case BuiltInSubgroupSize: return "WaveGetLaneCount()"; + case BuiltInHelperInvocation: + return "IsHelperLane()"; default: return CompilerGLSL::builtin_to_glsl(builtin, storage); @@ -995,32 +1148,49 @@ void CompilerHLSL::emit_builtin_variables() Bitset builtins = active_input_builtins; builtins.merge_or(active_output_builtins); - bool need_base_vertex_info = false; - std::unordered_map builtin_to_initializer; - ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { - if (!is_builtin_variable(var) || var.storage != StorageClassOutput || !var.initializer) - return; - auto *c = this->maybe_get(var.initializer); - if (!c) + // We need to declare sample mask with the same type that module declares it. + // Sample mask is somewhat special in that SPIR-V has an array, and we can copy that array, so we need to + // match sign. + SPIRType::BaseType sample_mask_in_basetype = SPIRType::Void; + SPIRType::BaseType sample_mask_out_basetype = SPIRType::Void; + + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + if (!is_builtin_variable(var)) return; auto &type = this->get(var.basetype); - if (type.basetype == SPIRType::Struct) + auto builtin = BuiltIn(get_decoration(var.self, DecorationBuiltIn)); + + if (var.storage == StorageClassInput && builtin == BuiltInSampleMask) + sample_mask_in_basetype = type.basetype; + else if (var.storage == StorageClassOutput && builtin == BuiltInSampleMask) + sample_mask_out_basetype = type.basetype; + + if (var.initializer && var.storage == StorageClassOutput) { - uint32_t member_count = uint32_t(type.member_types.size()); - for (uint32_t i = 0; i < member_count; i++) + auto *c = this->maybe_get(var.initializer); + if (!c) + return; + + if (type.basetype == SPIRType::Struct) { - if (has_member_decoration(type.self, i, DecorationBuiltIn)) + uint32_t member_count = uint32_t(type.member_types.size()); + for (uint32_t i = 0; i < member_count; i++) { - builtin_to_initializer[get_member_decoration(type.self, i, DecorationBuiltIn)] = - c->subconstants[i]; + if (has_member_decoration(type.self, i, DecorationBuiltIn)) + { + builtin_to_initializer[get_member_decoration(type.self, i, DecorationBuiltIn)] = + c->subconstants[i]; + } } } + else if (has_decoration(var.self, DecorationBuiltIn)) + { + builtin_to_initializer[builtin] = var.initializer; + } } - else if (has_decoration(var.self, DecorationBuiltIn)) - builtin_to_initializer[get_decoration(var.self, DecorationBuiltIn)] = var.initializer; }); // Emit global variables for the interface variables which are statically used by the shader. @@ -1034,6 +1204,18 @@ void CompilerHLSL::emit_builtin_variables() if (init_itr != builtin_to_initializer.end()) init_expr = join(" = ", to_expression(init_itr->second)); + if (get_execution_model() == ExecutionModelMeshEXT) + { + if (builtin == BuiltInPosition || builtin == BuiltInPointSize || builtin == BuiltInClipDistance || + builtin == BuiltInCullDistance || builtin == BuiltInLayer || builtin == BuiltInPrimitiveId || + builtin == BuiltInViewportIndex || builtin == BuiltInCullPrimitiveEXT || + builtin == BuiltInPrimitiveShadingRateKHR || builtin == BuiltInPrimitivePointIndicesEXT || + builtin == BuiltInPrimitiveLineIndicesEXT || builtin == BuiltInPrimitiveTriangleIndicesEXT) + { + return; + } + } + switch (builtin) { case BuiltInFragCoord: @@ -1050,7 +1232,13 @@ void CompilerHLSL::emit_builtin_variables() case BuiltInInstanceIndex: type = "int"; if (hlsl_options.support_nonzero_base_vertex_base_instance) - need_base_vertex_info = true; + base_vertex_info.used = true; + break; + + case BuiltInBaseVertex: + case BuiltInBaseInstance: + type = "int"; + base_vertex_info.used = true; break; case BuiltInInstanceId: @@ -1059,7 +1247,7 @@ void CompilerHLSL::emit_builtin_variables() break; case BuiltInPointSize: - if (hlsl_options.point_size_compat) + if (hlsl_options.point_size_compat || hlsl_options.shader_model <= 30) { // Just emit the global variable, it will be ignored. type = "float"; @@ -1103,6 +1291,11 @@ void CompilerHLSL::emit_builtin_variables() type = "uint4"; break; + case BuiltInHelperInvocation: + if (hlsl_options.shader_model < 50) + SPIRV_CROSS_THROW("Need SM 5.0 for Helper Invocation."); + break; + case BuiltInClipDistance: array_size = clip_distance_count; type = "float"; @@ -1114,7 +1307,24 @@ void CompilerHLSL::emit_builtin_variables() break; case BuiltInSampleMask: - type = "int"; + if (active_input_builtins.get(BuiltInSampleMask)) + type = sample_mask_in_basetype == SPIRType::UInt ? "uint" : "int"; + else + type = sample_mask_out_basetype == SPIRType::UInt ? "uint" : "int"; + array_size = 1; + break; + + case BuiltInPrimitiveId: + case BuiltInViewIndex: + case BuiltInLayer: + type = "uint"; + break; + + case BuiltInViewportIndex: + case BuiltInPrimitiveShadingRateKHR: + case BuiltInPrimitiveLineIndicesEXT: + case BuiltInCullPrimitiveEXT: + type = "uint"; break; default: @@ -1135,13 +1345,25 @@ void CompilerHLSL::emit_builtin_variables() // declared the input variable and we need to add the output one now. if (builtin == BuiltInSampleMask && storage == StorageClassInput && this->active_output_builtins.get(i)) { - statement("static ", type, " ", this->builtin_to_glsl(builtin, StorageClassOutput), init_expr, ";"); + type = sample_mask_out_basetype == SPIRType::UInt ? "uint" : "int"; + if (array_size) + statement("static ", type, " ", this->builtin_to_glsl(builtin, StorageClassOutput), "[", array_size, "]", init_expr, ";"); + else + statement("static ", type, " ", this->builtin_to_glsl(builtin, StorageClassOutput), init_expr, ";"); } }); - if (need_base_vertex_info) + if (base_vertex_info.used) { - statement("cbuffer SPIRV_Cross_VertexInfo"); + string binding_info; + if (base_vertex_info.explicit_binding) + { + binding_info = join(" : register(b", base_vertex_info.register_index); + if (base_vertex_info.register_space) + binding_info += join(", space", base_vertex_info.register_space); + binding_info += ")"; + } + statement("cbuffer SPIRV_Cross_VertexInfo", binding_info); begin_scope(); statement("int SPIRV_Cross_BaseVertex;"); statement("int SPIRV_Cross_BaseInstance;"); @@ -1150,6 +1372,30 @@ void CompilerHLSL::emit_builtin_variables() } } +void CompilerHLSL::set_hlsl_aux_buffer_binding(HLSLAuxBinding binding, uint32_t register_index, uint32_t register_space) +{ + if (binding == HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE) + { + base_vertex_info.explicit_binding = true; + base_vertex_info.register_space = register_space; + base_vertex_info.register_index = register_index; + } +} + +void CompilerHLSL::unset_hlsl_aux_buffer_binding(HLSLAuxBinding binding) +{ + if (binding == HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE) + base_vertex_info.explicit_binding = false; +} + +bool CompilerHLSL::is_hlsl_aux_buffer_binding_used(HLSLAuxBinding binding) const +{ + if (binding == HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE) + return base_vertex_info.used; + else + return false; +} + void CompilerHLSL::emit_composite_constants() { // HLSL cannot declare structs or arrays inline, so we must move them out to @@ -1167,6 +1413,7 @@ void CompilerHLSL::emit_composite_constants() if (type.basetype == SPIRType::Struct || !type.array.empty()) { + add_resource_name(c.self); auto name = to_name(c.self); statement("static const ", variable_decl(type, name), " = ", constant_expression(c), ";"); emitted = true; @@ -1196,7 +1443,7 @@ void CompilerHLSL::emit_specialization_constants_and_structs() }); auto loop_lock = ir.create_loop_hard_lock(); - for (auto &id_ : ir.ids_for_constant_or_type) + for (auto &id_ : ir.ids_for_constant_undef_or_type) { auto &id = ir.ids[id_]; @@ -1213,16 +1460,23 @@ void CompilerHLSL::emit_specialization_constants_and_structs() else if (c.specialization) { auto &type = get(c.constant_type); + add_resource_name(c.self); auto name = to_name(c.self); - // HLSL does not support specialization constants, so fallback to macros. - c.specialization_constant_macro_name = - constant_value_macro_name(get_decoration(c.self, DecorationSpecId)); + if (has_decoration(c.self, DecorationSpecId)) + { + // HLSL does not support specialization constants, so fallback to macros. + c.specialization_constant_macro_name = + constant_value_macro_name(get_decoration(c.self, DecorationSpecId)); + + statement("#ifndef ", c.specialization_constant_macro_name); + statement("#define ", c.specialization_constant_macro_name, " ", constant_expression(c)); + statement("#endif"); + statement("static const ", variable_decl(type, name), " = ", c.specialization_constant_macro_name, ";"); + } + else + statement("static const ", variable_decl(type, name), " = ", constant_expression(c), ";"); - statement("#ifndef ", c.specialization_constant_macro_name); - statement("#define ", c.specialization_constant_macro_name, " ", constant_expression(c)); - statement("#endif"); - statement("static const ", variable_decl(type, name), " = ", c.specialization_constant_macro_name, ";"); emitted = true; } } @@ -1230,6 +1484,7 @@ void CompilerHLSL::emit_specialization_constants_and_structs() { auto &c = id.get(); auto &type = get(c.basetype); + add_resource_name(c.self); auto name = to_name(c.self); statement("static const ", variable_decl(type, name), " = ", constant_op_expression(c), ";"); emitted = true; @@ -1250,6 +1505,21 @@ void CompilerHLSL::emit_specialization_constants_and_structs() emit_struct(type); } } + else if (id.get_type() == TypeUndef) + { + auto &undef = id.get(); + auto &type = this->get(undef.basetype); + // OpUndef can be void for some reason ... + if (type.basetype == SPIRType::Void) + return; + + string initializer; + if (options.force_zero_initialized_variables && type_can_zero_initialize(type)) + initializer = join(" = ", to_zero_initialized_expression(undef.basetype)); + + statement("static ", variable_decl(type, to_name(undef.self), undef.self), initializer, ";"); + emitted = true; + } } if (emitted) @@ -1260,32 +1530,49 @@ void CompilerHLSL::replace_illegal_names() { static const unordered_set keywords = { // Additional HLSL specific keywords. - "line", "linear", "matrix", "point", "row_major", "sampler", "vector" + // From https://docs.microsoft.com/en-US/windows/win32/direct3dhlsl/dx-graphics-hlsl-appendix-keywords + "AppendStructuredBuffer", "asm", "asm_fragment", + "BlendState", "bool", "break", "Buffer", "ByteAddressBuffer", + "case", "cbuffer", "centroid", "class", "column_major", "compile", + "compile_fragment", "CompileShader", "const", "continue", "ComputeShader", + "ConsumeStructuredBuffer", + "default", "DepthStencilState", "DepthStencilView", "discard", "do", + "double", "DomainShader", "dword", + "else", "export", "false", "float", "for", "fxgroup", + "GeometryShader", "groupshared", "half", "HullShader", + "indices", "if", "in", "inline", "inout", "InputPatch", "int", "interface", + "line", "lineadj", "linear", "LineStream", + "matrix", "min16float", "min10float", "min16int", "min16uint", + "namespace", "nointerpolation", "noperspective", "NULL", + "out", "OutputPatch", + "payload", "packoffset", "pass", "pixelfragment", "PixelShader", "point", + "PointStream", "precise", "RasterizerState", "RenderTargetView", + "return", "register", "row_major", "RWBuffer", "RWByteAddressBuffer", + "RWStructuredBuffer", "RWTexture1D", "RWTexture1DArray", "RWTexture2D", + "RWTexture2DArray", "RWTexture3D", "sample", "sampler", "SamplerState", + "SamplerComparisonState", "shared", "snorm", "stateblock", "stateblock_state", + "static", "string", "struct", "switch", "StructuredBuffer", "tbuffer", + "technique", "technique10", "technique11", "texture", "Texture1D", + "Texture1DArray", "Texture2D", "Texture2DArray", "Texture2DMS", "Texture2DMSArray", + "Texture3D", "TextureCube", "TextureCubeArray", "true", "typedef", "triangle", + "triangleadj", "TriangleStream", "uint", "uniform", "unorm", "unsigned", + "vector", "vertexfragment", "VertexShader", "vertices", "void", "volatile", "while", }; CompilerGLSL::replace_illegal_names(keywords); CompilerGLSL::replace_illegal_names(); } -void CompilerHLSL::declare_undefined_values() +SPIRType::BaseType CompilerHLSL::get_builtin_basetype(BuiltIn builtin, SPIRType::BaseType default_type) { - bool emitted = false; - ir.for_each_typed_id([&](uint32_t, const SPIRUndef &undef) { - auto &type = this->get(undef.basetype); - // OpUndef can be void for some reason ... - if (type.basetype == SPIRType::Void) - return; - - string initializer; - if (options.force_zero_initialized_variables && type_can_zero_initialize(type)) - initializer = join(" = ", to_zero_initialized_expression(undef.basetype)); - - statement("static ", variable_decl(type, to_name(undef.self), undef.self), initializer, ";"); - emitted = true; - }); - - if (emitted) - statement(""); + switch (builtin) + { + case BuiltInSampleMask: + // We declare sample mask array with module type, so always use default_type here. + return default_type; + default: + return CompilerGLSL::get_builtin_basetype(builtin, default_type); + } } void CompilerHLSL::emit_resources() @@ -1294,6 +1581,19 @@ void CompilerHLSL::emit_resources() replace_illegal_names(); + switch (execution.model) + { + case ExecutionModelGeometry: + case ExecutionModelTessellationControl: + case ExecutionModelTessellationEvaluation: + case ExecutionModelMeshEXT: + fixup_implicit_builtin_block_names(execution.model); + break; + + default: + break; + } + emit_specialization_constants_and_structs(); emit_composite_constants(); @@ -1326,7 +1626,8 @@ void CompilerHLSL::emit_resources() } }); - if (execution.model == ExecutionModelVertex && hlsl_options.shader_model <= 30) + if (execution.model == ExecutionModelVertex && hlsl_options.shader_model <= 30 && + active_output_builtins.get(BuiltInPosition)) { statement("uniform float4 gl_HalfPixel;"); emitted = true; @@ -1365,18 +1666,21 @@ void CompilerHLSL::emit_resources() // Emit builtin input and output variables here. emit_builtin_variables(); - ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { - auto &type = this->get(var.basetype); + if (execution.model != ExecutionModelMeshEXT) + { + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); - if (var.storage != StorageClassFunction && !var.remapped_variable && type.pointer && - (var.storage == StorageClassInput || var.storage == StorageClassOutput) && !is_builtin_variable(var) && - interface_variable_exists_in_entry_point(var.self)) - { - // Builtin variables are handled separately. - emit_interface_block_globally(var); - emitted = true; - } - }); + if (var.storage != StorageClassFunction && !var.remapped_variable && type.pointer && + (var.storage == StorageClassInput || var.storage == StorageClassOutput) && !is_builtin_variable(var) && + interface_variable_exists_in_entry_point(var.self)) + { + // Builtin variables are handled separately. + emit_interface_block_globally(var); + emitted = true; + } + }); + } if (emitted) statement(""); @@ -1490,23 +1794,48 @@ void CompilerHLSL::emit_resources() statement(""); } + const bool is_mesh_shader = execution.model == ExecutionModelMeshEXT; if (!output_variables.empty() || !active_output_builtins.empty()) { - require_output = true; - statement("struct SPIRV_Cross_Output"); + sort(output_variables.begin(), output_variables.end(), variable_compare); + require_output = !is_mesh_shader; + statement(is_mesh_shader ? "struct gl_MeshPerVertexEXT" : "struct SPIRV_Cross_Output"); begin_scope(); - sort(output_variables.begin(), output_variables.end(), variable_compare); for (auto &var : output_variables) { - if (var.block) + if (is_per_primitive_variable(*var.var)) + continue; + if (var.block && is_mesh_shader && var.block_member_index != 0) + continue; + if (var.block && !is_mesh_shader) emit_interface_block_member_in_struct(*var.var, var.block_member_index, var.location, active_outputs); else emit_interface_block_in_struct(*var.var, active_outputs); } emit_builtin_outputs_in_struct(); + if (!is_mesh_shader) + emit_builtin_primitive_outputs_in_struct(); end_scope_decl(); statement(""); + + if (is_mesh_shader) + { + statement("struct gl_MeshPerPrimitiveEXT"); + begin_scope(); + for (auto &var : output_variables) + { + if (!is_per_primitive_variable(*var.var)) + continue; + if (var.block && var.block_member_index != 0) + continue; + + emit_interface_block_in_struct(*var.var, active_outputs); + } + emit_builtin_primitive_outputs_in_struct(); + end_scope_decl(); + statement(""); + } } // Global variables. @@ -1516,6 +1845,9 @@ void CompilerHLSL::emit_resources() if (is_hidden_variable(var, true)) continue; + if (var.storage == StorageClassTaskPayloadWorkgroupEXT && is_mesh_shader) + continue; + if (var.storage != StorageClassOutput) { if (!variable_is_lut(var)) @@ -1526,6 +1858,7 @@ void CompilerHLSL::emit_resources() switch (var.storage) { case StorageClassWorkgroup: + case StorageClassTaskPayloadWorkgroupEXT: storage = "groupshared"; break; @@ -1550,8 +1883,6 @@ void CompilerHLSL::emit_resources() if (emitted) statement(""); - declare_undefined_values(); - if (requires_op_fmod) { static const char *types[] = { @@ -1962,6 +2293,20 @@ void CompilerHLSL::emit_resources() end_scope(); statement(""); } + + if (is_mesh_shader && options.vertex.flip_vert_y) + { + statement("float4 spvFlipVertY(float4 v)"); + begin_scope(); + statement("return float4(v.x, -v.y, v.z, v.w);"); + end_scope(); + statement(""); + statement("float spvFlipVertY(float v)"); + begin_scope(); + statement("return -v;"); + end_scope(); + statement(""); + } } void CompilerHLSL::emit_texture_size_variants(uint64_t variant_mask, const char *vecsize_qualifier, bool uav, @@ -2042,6 +2387,194 @@ void CompilerHLSL::emit_texture_size_variants(uint64_t variant_mask, const char } } +void CompilerHLSL::analyze_meshlet_writes() +{ + uint32_t id_per_vertex = 0; + uint32_t id_per_primitive = 0; + bool need_per_primitive = false; + bool need_per_vertex = false; + + ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + auto &type = this->get(var.basetype); + bool block = has_decoration(type.self, DecorationBlock); + if (var.storage == StorageClassOutput && block && is_builtin_variable(var)) + { + auto flags = get_buffer_block_flags(var.self); + if (flags.get(DecorationPerPrimitiveEXT)) + id_per_primitive = var.self; + else + id_per_vertex = var.self; + } + else if (var.storage == StorageClassOutput) + { + Bitset flags; + if (block) + flags = get_buffer_block_flags(var.self); + else + flags = get_decoration_bitset(var.self); + + if (flags.get(DecorationPerPrimitiveEXT)) + need_per_primitive = true; + else + need_per_vertex = true; + } + }); + + // If we have per-primitive outputs, and no per-primitive builtins, + // empty version of gl_MeshPerPrimitiveEXT will be emitted. + // If we don't use block IO for vertex output, we'll also need to synthesize the PerVertex block. + + const auto generate_block = [&](const char *block_name, const char *instance_name, bool per_primitive) -> uint32_t { + auto &execution = get_entry_point(); + + uint32_t op_type = ir.increase_bound_by(4); + uint32_t op_arr = op_type + 1; + uint32_t op_ptr = op_type + 2; + uint32_t op_var = op_type + 3; + + auto &type = set(op_type, OpTypeStruct); + type.basetype = SPIRType::Struct; + set_name(op_type, block_name); + set_decoration(op_type, DecorationBlock); + if (per_primitive) + set_decoration(op_type, DecorationPerPrimitiveEXT); + + auto &arr = set(op_arr, type); + arr.parent_type = type.self; + arr.array.push_back(per_primitive ? execution.output_primitives : execution.output_vertices); + arr.array_size_literal.push_back(true); + + auto &ptr = set(op_ptr, arr); + ptr.parent_type = arr.self; + ptr.pointer = true; + ptr.pointer_depth++; + ptr.storage = StorageClassOutput; + set_decoration(op_ptr, DecorationBlock); + set_name(op_ptr, block_name); + + auto &var = set(op_var, op_ptr, StorageClassOutput); + if (per_primitive) + set_decoration(op_var, DecorationPerPrimitiveEXT); + set_name(op_var, instance_name); + execution.interface_variables.push_back(var.self); + + return op_var; + }; + + if (id_per_vertex == 0 && need_per_vertex) + id_per_vertex = generate_block("gl_MeshPerVertexEXT", "gl_MeshVerticesEXT", false); + if (id_per_primitive == 0 && need_per_primitive) + id_per_primitive = generate_block("gl_MeshPerPrimitiveEXT", "gl_MeshPrimitivesEXT", true); + + unordered_set processed_func_ids; + analyze_meshlet_writes(ir.default_entry_point, id_per_vertex, id_per_primitive, processed_func_ids); +} + +void CompilerHLSL::analyze_meshlet_writes(uint32_t func_id, uint32_t id_per_vertex, uint32_t id_per_primitive, + std::unordered_set &processed_func_ids) +{ + // Avoid processing a function more than once + if (processed_func_ids.find(func_id) != processed_func_ids.end()) + return; + processed_func_ids.insert(func_id); + + auto &func = get(func_id); + // Recursively establish global args added to functions on which we depend. + for (auto& block : func.blocks) + { + auto &b = get(block); + for (auto &i : b.ops) + { + auto ops = stream(i); + auto op = static_cast(i.op); + + switch (op) + { + case OpFunctionCall: + { + // Then recurse into the function itself to extract globals used internally in the function + uint32_t inner_func_id = ops[2]; + analyze_meshlet_writes(inner_func_id, id_per_vertex, id_per_primitive, processed_func_ids); + auto &inner_func = get(inner_func_id); + for (auto &iarg : inner_func.arguments) + { + if (!iarg.alias_global_variable) + continue; + + bool already_declared = false; + for (auto &arg : func.arguments) + { + if (arg.id == iarg.id) + { + already_declared = true; + break; + } + } + + if (!already_declared) + { + // basetype is effectively ignored here since we declare the argument + // with explicit types. Just pass down a valid type. + func.arguments.push_back({ expression_type_id(iarg.id), iarg.id, + iarg.read_count, iarg.write_count, true }); + } + } + break; + } + + case OpStore: + case OpLoad: + case OpInBoundsAccessChain: + case OpAccessChain: + case OpPtrAccessChain: + case OpInBoundsPtrAccessChain: + case OpArrayLength: + { + auto *var = maybe_get(ops[op == OpStore ? 0 : 2]); + if (var && (var->storage == StorageClassOutput || var->storage == StorageClassTaskPayloadWorkgroupEXT)) + { + bool already_declared = false; + auto builtin_type = BuiltIn(get_decoration(var->self, DecorationBuiltIn)); + + uint32_t var_id = var->self; + if (var->storage != StorageClassTaskPayloadWorkgroupEXT && + builtin_type != BuiltInPrimitivePointIndicesEXT && + builtin_type != BuiltInPrimitiveLineIndicesEXT && + builtin_type != BuiltInPrimitiveTriangleIndicesEXT) + { + var_id = is_per_primitive_variable(*var) ? id_per_primitive : id_per_vertex; + } + + for (auto &arg : func.arguments) + { + if (arg.id == var_id) + { + already_declared = true; + break; + } + } + + if (!already_declared) + { + // basetype is effectively ignored here since we declare the argument + // with explicit types. Just pass down a valid type. + uint32_t type_id = expression_type_id(var_id); + if (var->storage == StorageClassTaskPayloadWorkgroupEXT) + func.arguments.push_back({ type_id, var_id, 1u, 0u, true }); + else + func.arguments.push_back({ type_id, var_id, 1u, 1u, true }); + } + } + break; + } + + default: + break; + } + } + } +} + string CompilerHLSL::layout_for_member(const SPIRType &type, uint32_t index) { auto &flags = get_member_decoration_bitset(type.self, index); @@ -2087,23 +2620,66 @@ void CompilerHLSL::emit_struct_member(const SPIRType &type, uint32_t member_type variable_decl(membertype, to_member_name(type, index)), packing_offset, ";"); } +void CompilerHLSL::emit_rayquery_function(const char *commited, const char *candidate, const uint32_t *ops) +{ + flush_variable_declaration(ops[0]); + uint32_t is_commited = evaluate_constant_u32(ops[3]); + emit_op(ops[0], ops[1], join(to_expression(ops[2]), is_commited ? commited : candidate), false); +} + +void CompilerHLSL::emit_mesh_tasks(SPIRBlock &block) +{ + if (block.mesh.payload != 0) + { + statement("DispatchMesh(", to_unpacked_expression(block.mesh.groups[0]), ", ", to_unpacked_expression(block.mesh.groups[1]), ", ", + to_unpacked_expression(block.mesh.groups[2]), ", ", to_unpacked_expression(block.mesh.payload), ");"); + } + else + { + SPIRV_CROSS_THROW("Amplification shader in HLSL must have payload"); + } +} + void CompilerHLSL::emit_buffer_block(const SPIRVariable &var) { auto &type = get(var.basetype); bool is_uav = var.storage == StorageClassStorageBuffer || has_decoration(type.self, DecorationBufferBlock); - if (is_uav) + if (flattened_buffer_blocks.count(var.self)) + { + emit_buffer_block_flattened(var); + } + else if (is_uav) { Bitset flags = ir.get_buffer_block_flags(var); bool is_readonly = flags.get(DecorationNonWritable) && !is_hlsl_force_storage_buffer_as_uav(var.self); bool is_coherent = flags.get(DecorationCoherent) && !is_readonly; bool is_interlocked = interlocked_resources.count(var.self) > 0; - const char *type_name = "ByteAddressBuffer "; - if (!is_readonly) - type_name = is_interlocked ? "RasterizerOrderedByteAddressBuffer " : "RWByteAddressBuffer "; + + auto to_structuredbuffer_subtype_name = [this](const SPIRType &parent_type) -> std::string + { + if (parent_type.basetype == SPIRType::Struct && parent_type.member_types.size() == 1) + { + // Use type of first struct member as a StructuredBuffer will have only one '._m0' field in SPIR-V + const auto &member0_type = this->get(parent_type.member_types.front()); + return this->type_to_glsl(member0_type); + } + else + { + // Otherwise, this StructuredBuffer only has a basic subtype, e.g. StructuredBuffer + return this->type_to_glsl(parent_type); + } + }; + + std::string type_name; + if (is_user_type_structured(var.self)) + type_name = join(is_readonly ? "" : is_interlocked ? "RasterizerOrdered" : "RW", "StructuredBuffer<", to_structuredbuffer_subtype_name(type), ">"); + else + type_name = is_readonly ? "ByteAddressBuffer" : is_interlocked ? "RasterizerOrderedByteAddressBuffer" : "RWByteAddressBuffer"; + add_resource_name(var.self); - statement(is_coherent ? "globallycoherent " : "", type_name, to_name(var.self), type_to_array_glsl(type), + statement(is_coherent ? "globallycoherent " : "", type_name, " ", to_name(var.self), type_to_array_glsl(type), to_resource_binding(var), ";"); } else @@ -2198,7 +2774,11 @@ void CompilerHLSL::emit_buffer_block(const SPIRVariable &var) void CompilerHLSL::emit_push_constant_block(const SPIRVariable &var) { - if (root_constants_layout.empty()) + if (flattened_buffer_blocks.count(var.self)) + { + emit_buffer_block_flattened(var); + } + else if (root_constants_layout.empty()) { emit_buffer_block(var); } @@ -2305,12 +2885,36 @@ string CompilerHLSL::to_func_call_arg(const SPIRFunction::Parameter &arg, uint32 return arg_str; } +string CompilerHLSL::get_inner_entry_point_name() const +{ + auto &execution = get_entry_point(); + + if (hlsl_options.use_entry_point_name) + { + auto name = join(execution.name, "_inner"); + ParsedIR::sanitize_underscores(name); + return name; + } + + if (execution.model == ExecutionModelVertex) + return "vert_main"; + else if (execution.model == ExecutionModelFragment) + return "frag_main"; + else if (execution.model == ExecutionModelGLCompute) + return "comp_main"; + else if (execution.model == ExecutionModelMeshEXT) + return "mesh_main"; + else if (execution.model == ExecutionModelTaskEXT) + return "task_main"; + else + SPIRV_CROSS_THROW("Unsupported execution model."); +} + void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &return_flags) { if (func.self != ir.default_entry_point) add_function_overload(func); - auto &execution = get_entry_point(); // Avoid shadow declarations. local_variable_names = resource_names; @@ -2331,14 +2935,7 @@ void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret if (func.self == ir.default_entry_point) { - if (execution.model == ExecutionModelVertex) - decl += "vert_main"; - else if (execution.model == ExecutionModelFragment) - decl += "frag_main"; - else if (execution.model == ExecutionModelGLCompute) - decl += "comp_main"; - else - SPIRV_CROSS_THROW("Unsupported execution model."); + decl += get_inner_entry_point_name(); processing_entry_point = true; } else @@ -2356,7 +2953,7 @@ void CompilerHLSL::emit_function_prototype(SPIRFunction &func, const Bitset &ret out_argument += " "; out_argument += "spvReturnValue"; out_argument += type_to_array_glsl(type); - arglist.push_back(move(out_argument)); + arglist.push_back(std::move(out_argument)); } for (auto &arg : func.arguments) @@ -2422,8 +3019,58 @@ void CompilerHLSL::emit_hlsl_entry_point() switch (execution.model) { + case ExecutionModelTaskEXT: + case ExecutionModelMeshEXT: case ExecutionModelGLCompute: { + if (execution.model == ExecutionModelMeshEXT) + { + if (execution.flags.get(ExecutionModeOutputTrianglesEXT)) + statement("[outputtopology(\"triangle\")]"); + else if (execution.flags.get(ExecutionModeOutputLinesEXT)) + statement("[outputtopology(\"line\")]"); + else if (execution.flags.get(ExecutionModeOutputPoints)) + SPIRV_CROSS_THROW("Topology mode \"points\" is not supported in DirectX"); + + auto &func = get(ir.default_entry_point); + for (auto &arg : func.arguments) + { + auto &var = get(arg.id); + auto &base_type = get(var.basetype); + bool block = has_decoration(base_type.self, DecorationBlock); + if (var.storage == StorageClassTaskPayloadWorkgroupEXT) + { + arguments.push_back("in payload " + variable_decl(var)); + } + else if (block) + { + auto flags = get_buffer_block_flags(var.self); + if (flags.get(DecorationPerPrimitiveEXT) || has_decoration(arg.id, DecorationPerPrimitiveEXT)) + { + arguments.push_back("out primitives gl_MeshPerPrimitiveEXT gl_MeshPrimitivesEXT[" + + std::to_string(execution.output_primitives) + "]"); + } + else + { + arguments.push_back("out vertices gl_MeshPerVertexEXT gl_MeshVerticesEXT[" + + std::to_string(execution.output_vertices) + "]"); + } + } + else + { + if (execution.flags.get(ExecutionModeOutputTrianglesEXT)) + { + arguments.push_back("out indices uint3 gl_PrimitiveTriangleIndicesEXT[" + + std::to_string(execution.output_primitives) + "]"); + } + else + { + arguments.push_back("out indices uint2 gl_PrimitiveLineIndicesEXT[" + + std::to_string(execution.output_primitives) + "]"); + } + } + } + } SpecializationConstant wg_x, wg_y, wg_z; get_work_group_size_specialization_constants(wg_x, wg_y, wg_z); @@ -2431,6 +3078,16 @@ void CompilerHLSL::emit_hlsl_entry_point() uint32_t y = execution.workgroup_size.y; uint32_t z = execution.workgroup_size.z; + if (!execution.workgroup_size.constant && execution.flags.get(ExecutionModeLocalSizeId)) + { + if (execution.workgroup_size.id_x) + x = get(execution.workgroup_size.id_x).scalar(); + if (execution.workgroup_size.id_y) + y = get(execution.workgroup_size.id_y).scalar(); + if (execution.workgroup_size.id_z) + z = get(execution.workgroup_size.id_z).scalar(); + } + auto x_expr = wg_x.id ? get(wg_x.id).specialization_constant_macro_name : to_string(x); auto y_expr = wg_y.id ? get(wg_y.id).specialization_constant_macro_name : to_string(y); auto z_expr = wg_z.id ? get(wg_z.id).specialization_constant_macro_name : to_string(z); @@ -2446,7 +3103,13 @@ void CompilerHLSL::emit_hlsl_entry_point() break; } - statement(require_output ? "SPIRV_Cross_Output " : "void ", "main(", merge(arguments), ")"); + const char *entry_point_name; + if (hlsl_options.use_entry_point_name) + entry_point_name = get_entry_point().name.c_str(); + else + entry_point_name = "main"; + + statement(require_output ? "SPIRV_Cross_Output " : "void ", entry_point_name, "(", merge(arguments), ")"); begin_scope(); bool legacy = hlsl_options.shader_model <= 30; @@ -2484,15 +3147,28 @@ void CompilerHLSL::emit_hlsl_entry_point() statement(builtin, " = int(stage_input.", builtin, ");"); break; + case BuiltInBaseVertex: + statement(builtin, " = SPIRV_Cross_BaseVertex;"); + break; + + case BuiltInBaseInstance: + statement(builtin, " = SPIRV_Cross_BaseInstance;"); + break; + case BuiltInInstanceId: // D3D semantics are uint, but shader wants int. statement(builtin, " = int(stage_input.", builtin, ");"); break; + case BuiltInSampleMask: + statement(builtin, "[0] = stage_input.", builtin, ";"); + break; + case BuiltInNumWorkgroups: case BuiltInPointCoord: case BuiltInSubgroupSize: case BuiltInSubgroupLocalInvocationId: + case BuiltInHelperInvocation: break; case BuiltInSubgroupEqMask: @@ -2618,12 +3294,22 @@ void CompilerHLSL::emit_hlsl_entry_point() }); // Run the shader. - if (execution.model == ExecutionModelVertex) - statement("vert_main();"); - else if (execution.model == ExecutionModelFragment) - statement("frag_main();"); - else if (execution.model == ExecutionModelGLCompute) - statement("comp_main();"); + if (execution.model == ExecutionModelVertex || + execution.model == ExecutionModelFragment || + execution.model == ExecutionModelGLCompute || + execution.model == ExecutionModelMeshEXT || + execution.model == ExecutionModelTaskEXT) + { + // For mesh shaders, we receive special arguments that we must pass down as function arguments. + // HLSL does not support proper reference types for passing these IO blocks, + // but DXC post-inlining seems to magically fix it up anyways *shrug*. + SmallVector arglist; + auto &func = get(ir.default_entry_point); + // The arguments are marked out, avoid detecting reads and emitting inout. + for (auto &arg : func.arguments) + arglist.push_back(to_expression(arg.id, false)); + statement(get_inner_entry_point_name(), "(", merge(arglist), ");"); + } else SPIRV_CROSS_THROW("Unsupported shader stage."); @@ -2634,8 +3320,8 @@ void CompilerHLSL::emit_hlsl_entry_point() // Copy builtins from globals to return struct. active_output_builtins.for_each_bit([&](uint32_t i) { - // PointSize doesn't exist in HLSL. - if (i == BuiltInPointSize) + // PointSize doesn't exist in HLSL SM 4+. + if (i == BuiltInPointSize && !legacy) return; switch (static_cast(i)) @@ -2652,6 +3338,10 @@ void CompilerHLSL::emit_hlsl_entry_point() cull, "];"); break; + case BuiltInSampleMask: + statement("stage_output.gl_SampleMask = gl_SampleMask[0];"); + break; + default: { auto builtin_expr = builtin_to_glsl(static_cast(i), StorageClassOutput); @@ -2712,7 +3402,7 @@ void CompilerHLSL::emit_hlsl_entry_point() void CompilerHLSL::emit_fixup() { - if (is_vertex_like_shader()) + if (is_vertex_like_shader() && active_output_builtins.get(BuiltInPosition)) { // Do various mangling on the gl_Position. if (hlsl_options.shader_model <= 30) @@ -2901,9 +3591,9 @@ void CompilerHLSL::emit_texture_op(const Instruction &i, bool sparse) else { auto &imgformat = get(imgtype.image.type); - if (imgformat.basetype != SPIRType::Float) + if (hlsl_options.shader_model < 67 && imgformat.basetype != SPIRType::Float) { - SPIRV_CROSS_THROW("Sampling non-float textures is not supported in HLSL."); + SPIRV_CROSS_THROW("Sampling non-float textures is not supported in HLSL SM < 6.7."); } if (hlsl_options.shader_model >= 40) @@ -2914,7 +3604,7 @@ void CompilerHLSL::emit_texture_op(const Instruction &i, bool sparse) { if (gather) { - SPIRV_CROSS_THROW("GatherCmp does not exist in HLSL."); + texop += ".GatherCmp"; } else if (lod || grad_x || grad_y) { @@ -3248,6 +3938,11 @@ string CompilerHLSL::to_resource_binding(const SPIRVariable &var) resource_flags = HLSL_BINDING_AUTO_SAMPLER_BIT; break; + case SPIRType::AccelerationStructure: + space = 't'; // SRV + resource_flags = HLSL_BINDING_AUTO_SRV_BIT; + break; + case SPIRType::Struct: { auto storage = type.storage; @@ -3483,6 +4178,18 @@ string CompilerHLSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &i } return "spvPackFloat2x16"; } + else if (out_type.basetype == SPIRType::UShort && in_type.basetype == SPIRType::Half) + { + if (hlsl_options.shader_model < 40) + SPIRV_CROSS_THROW("Half to UShort requires Shader Model 4."); + return "(" + type_to_glsl(out_type) + ")f32tof16"; + } + else if (out_type.basetype == SPIRType::Half && in_type.basetype == SPIRType::UShort) + { + if (hlsl_options.shader_model < 40) + SPIRV_CROSS_THROW("UShort to Half requires Shader Model 4."); + return "(" + type_to_glsl(out_type) + ")f16tof32"; + } else return ""; } @@ -3496,6 +4203,8 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, auto int_type = to_signed_basetype(integer_width); auto uint_type = to_unsigned_basetype(integer_width); + op = get_remapped_glsl_op(op); + switch (op) { case GLSLstd450InverseSqrt: @@ -3512,10 +4221,16 @@ void CompilerHLSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, emit_unary_func_op(result_type, id, args[0], "round"); break; + case GLSLstd450Trunc: + emit_unary_func_op(result_type, id, args[0], "trunc"); + break; + case GLSLstd450Acosh: case GLSLstd450Asinh: case GLSLstd450Atanh: - SPIRV_CROSS_THROW("Inverse hyperbolics are not supported on HLSL."); + // These are not supported in HLSL, always emulate them. + emit_emulated_ahyper_op(result_type, id, args[0], op); + break; case GLSLstd450FMix: case GLSLstd450IMix: @@ -3793,7 +4508,7 @@ void CompilerHLSL::read_access_chain(string *expr, const string &lhs, const SPIR { auto &type = get(chain.basetype); - SPIRType target_type; + SPIRType target_type { is_scalar(type) ? OpTypeInt : type.op }; target_type.basetype = SPIRType::UInt; target_type.vecsize = type.vecsize; target_type.columns = type.columns; @@ -3968,7 +4683,7 @@ void CompilerHLSL::read_access_chain(string *expr, const string &lhs, const SPIR if (lhs.empty()) { assert(expr); - *expr = move(load_expr); + *expr = std::move(load_expr); } else statement(lhs, " = ", load_expr, ";"); @@ -4028,14 +4743,19 @@ void CompilerHLSL::emit_load(const Instruction &instruction) void CompilerHLSL::write_access_chain_array(const SPIRAccessChain &chain, uint32_t value, const SmallVector &composite_chain) { - auto &type = get(chain.basetype); + auto *ptype = &get(chain.basetype); + while (ptype->pointer) + { + ptype = &get(ptype->basetype); + } + auto &type = *ptype; // Need to use a reserved identifier here since it might shadow an identifier in the access chain input or other loops. auto ident = get_unique_identifier(); uint32_t id = ir.increase_bound_by(2); uint32_t int_type_id = id + 1; - SPIRType int_type; + SPIRType int_type { OpTypeInt }; int_type.basetype = SPIRType::Int; int_type.width = 32; set(int_type_id, int_type); @@ -4123,7 +4843,7 @@ void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t val // Make sure we trigger a read of the constituents in the access chain. track_expression_read(chain.self); - SPIRType target_type; + SPIRType target_type { is_scalar(type) ? OpTypeInt : type.op }; target_type.basetype = SPIRType::UInt; target_type.vecsize = type.vecsize; target_type.columns = type.columns; @@ -4296,6 +5016,19 @@ void CompilerHLSL::write_access_chain(const SPIRAccessChain &chain, uint32_t val void CompilerHLSL::emit_store(const Instruction &instruction) { auto ops = stream(instruction); + if (options.vertex.flip_vert_y) + { + auto *expr = maybe_get(ops[0]); + if (expr != nullptr && expr->access_meshlet_position_y) + { + auto lhs = to_dereferenced_expression(ops[0]); + auto rhs = to_unpacked_expression(ops[1]); + statement(lhs, " = spvFlipVertY(", rhs, ");"); + register_write(ops[0]); + return; + } + } + auto *chain = maybe_get(ops[0]); if (chain) write_access_chain(*chain, ops[1], {}); @@ -4334,6 +5067,12 @@ void CompilerHLSL::emit_access_chain(const Instruction &instruction) auto *backing_variable = maybe_get_backing_variable(ops[2]); + if (backing_variable != nullptr && is_user_type_structured(backing_variable->self)) + { + CompilerGLSL::emit_instruction(instruction); + return; + } + string base; if (to_plain_buffer_length != 0) base = access_chain(ops[2], &ops[3], to_plain_buffer_length, get(ops[0])); @@ -4599,9 +5338,9 @@ void CompilerHLSL::emit_subgroup_op(const Instruction &i) case OpGroupNonUniformBallotBitCount: { auto operation = static_cast(ops[3]); + bool forward = should_forward(ops[4]); if (operation == GroupOperationReduce) { - bool forward = should_forward(ops[4]); auto left = join("countbits(", to_enclosed_expression(ops[4]), ".x) + countbits(", to_enclosed_expression(ops[4]), ".y)"); auto right = join("countbits(", to_enclosed_expression(ops[4]), ".z) + countbits(", @@ -4610,9 +5349,31 @@ void CompilerHLSL::emit_subgroup_op(const Instruction &i) inherit_expression_dependencies(id, ops[4]); } else if (operation == GroupOperationInclusiveScan) - SPIRV_CROSS_THROW("Cannot trivially implement BallotBitCount Inclusive Scan in HLSL."); + { + auto left = join("countbits(", to_enclosed_expression(ops[4]), ".x & gl_SubgroupLeMask.x) + countbits(", + to_enclosed_expression(ops[4]), ".y & gl_SubgroupLeMask.y)"); + auto right = join("countbits(", to_enclosed_expression(ops[4]), ".z & gl_SubgroupLeMask.z) + countbits(", + to_enclosed_expression(ops[4]), ".w & gl_SubgroupLeMask.w)"); + emit_op(result_type, id, join(left, " + ", right), forward); + if (!active_input_builtins.get(BuiltInSubgroupLeMask)) + { + active_input_builtins.set(BuiltInSubgroupLeMask); + force_recompile_guarantee_forward_progress(); + } + } else if (operation == GroupOperationExclusiveScan) - SPIRV_CROSS_THROW("Cannot trivially implement BallotBitCount Exclusive Scan in HLSL."); + { + auto left = join("countbits(", to_enclosed_expression(ops[4]), ".x & gl_SubgroupLtMask.x) + countbits(", + to_enclosed_expression(ops[4]), ".y & gl_SubgroupLtMask.y)"); + auto right = join("countbits(", to_enclosed_expression(ops[4]), ".z & gl_SubgroupLtMask.z) + countbits(", + to_enclosed_expression(ops[4]), ".w & gl_SubgroupLtMask.w)"); + emit_op(result_type, id, join(left, " + ", right), forward); + if (!active_input_builtins.get(BuiltInSubgroupLtMask)) + { + active_input_builtins.set(BuiltInSubgroupLtMask); + force_recompile_guarantee_forward_progress(); + } + } else SPIRV_CROSS_THROW("Invalid BitCount operation."); break; @@ -4749,7 +5510,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) #define HLSL_BOP(op) emit_binary_op(ops[0], ops[1], ops[2], ops[3], #op) #define HLSL_BOP_CAST(op, type) \ - emit_binary_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, opcode_is_sign_invariant(opcode)) + emit_binary_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, opcode_is_sign_invariant(opcode), false) #define HLSL_UOP(op) emit_unary_op(ops[0], ops[1], ops[2], #op) #define HLSL_QFOP(op) emit_quaternary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], ops[5], #op) #define HLSL_TFOP(op) emit_trinary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], #op) @@ -4764,6 +5525,8 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) auto int_type = to_signed_basetype(integer_width); auto uint_type = to_unsigned_basetype(integer_width); + opcode = get_remapped_spirv_op(opcode); + switch (opcode) { case OpAccessChain: @@ -5314,7 +6077,7 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) image_format_to_components(get(var->basetype).image.format), imgexpr); } - if (var && var->forwardable) + if (var) { bool forward = forced_temporaries.find(id) == end(forced_temporaries); auto &e = emit_op(result_type, id, imgexpr, forward); @@ -5372,6 +6135,11 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) break; } + case OpAtomicFAddEXT: + case OpAtomicFMinEXT: + case OpAtomicFMaxEXT: + SPIRV_CROSS_THROW("Floating-point atomics are not supported in HLSL."); + case OpAtomicCompareExchange: case OpAtomicExchange: case OpAtomicISub: @@ -5558,7 +6326,12 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) } case OpIsHelperInvocationEXT: - SPIRV_CROSS_THROW("helperInvocationEXT() is not supported in HLSL."); + if (hlsl_options.shader_model < 50 || get_entry_point().model != ExecutionModelFragment) + SPIRV_CROSS_THROW("Helper Invocation input is only supported in PS 5.0 or higher."); + // Helper lane state with demote is volatile by nature. + // Do not forward this. + emit_op(ops[0], ops[1], "IsHelperLane()", false); + break; case OpBeginInvocationInterlockEXT: case OpEndInvocationInterlockEXT: @@ -5566,6 +6339,148 @@ void CompilerHLSL::emit_instruction(const Instruction &instruction) SPIRV_CROSS_THROW("Rasterizer order views require Shader Model 5.1."); break; // Nothing to do in the body + case OpRayQueryInitializeKHR: + { + flush_variable_declaration(ops[0]); + + std::string ray_desc_name = get_unique_identifier(); + statement("RayDesc ", ray_desc_name, " = {", to_expression(ops[4]), ", ", to_expression(ops[5]), ", ", + to_expression(ops[6]), ", ", to_expression(ops[7]), "};"); + + statement(to_expression(ops[0]), ".TraceRayInline(", + to_expression(ops[1]), ", ", // acc structure + to_expression(ops[2]), ", ", // ray flags + to_expression(ops[3]), ", ", // mask + ray_desc_name, ");"); // ray + break; + } + case OpRayQueryProceedKHR: + { + flush_variable_declaration(ops[0]); + emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".Proceed()"), false); + break; + } + case OpRayQueryTerminateKHR: + { + flush_variable_declaration(ops[0]); + statement(to_expression(ops[0]), ".Abort();"); + break; + } + case OpRayQueryGenerateIntersectionKHR: + { + flush_variable_declaration(ops[0]); + statement(to_expression(ops[0]), ".CommitProceduralPrimitiveHit(", to_expression(ops[1]), ");"); + break; + } + case OpRayQueryConfirmIntersectionKHR: + { + flush_variable_declaration(ops[0]); + statement(to_expression(ops[0]), ".CommitNonOpaqueTriangleHit();"); + break; + } + case OpRayQueryGetIntersectionTypeKHR: + { + emit_rayquery_function(".CommittedStatus()", ".CandidateType()", ops); + break; + } + case OpRayQueryGetIntersectionTKHR: + { + emit_rayquery_function(".CommittedRayT()", ".CandidateTriangleRayT()", ops); + break; + } + case OpRayQueryGetIntersectionInstanceCustomIndexKHR: + { + emit_rayquery_function(".CommittedInstanceID()", ".CandidateInstanceID()", ops); + break; + } + case OpRayQueryGetIntersectionInstanceIdKHR: + { + emit_rayquery_function(".CommittedInstanceIndex()", ".CandidateInstanceIndex()", ops); + break; + } + case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: + { + emit_rayquery_function(".CommittedInstanceContributionToHitGroupIndex()", + ".CandidateInstanceContributionToHitGroupIndex()", ops); + break; + } + case OpRayQueryGetIntersectionGeometryIndexKHR: + { + emit_rayquery_function(".CommittedGeometryIndex()", + ".CandidateGeometryIndex()", ops); + break; + } + case OpRayQueryGetIntersectionPrimitiveIndexKHR: + { + emit_rayquery_function(".CommittedPrimitiveIndex()", ".CandidatePrimitiveIndex()", ops); + break; + } + case OpRayQueryGetIntersectionBarycentricsKHR: + { + emit_rayquery_function(".CommittedTriangleBarycentrics()", ".CandidateTriangleBarycentrics()", ops); + break; + } + case OpRayQueryGetIntersectionFrontFaceKHR: + { + emit_rayquery_function(".CommittedTriangleFrontFace()", ".CandidateTriangleFrontFace()", ops); + break; + } + case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: + { + flush_variable_declaration(ops[0]); + emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".CandidateProceduralPrimitiveNonOpaque()"), false); + break; + } + case OpRayQueryGetIntersectionObjectRayDirectionKHR: + { + emit_rayquery_function(".CommittedObjectRayDirection()", ".CandidateObjectRayDirection()", ops); + break; + } + case OpRayQueryGetIntersectionObjectRayOriginKHR: + { + flush_variable_declaration(ops[0]); + emit_rayquery_function(".CommittedObjectRayOrigin()", ".CandidateObjectRayOrigin()", ops); + break; + } + case OpRayQueryGetIntersectionObjectToWorldKHR: + { + emit_rayquery_function(".CommittedObjectToWorld4x3()", ".CandidateObjectToWorld4x3()", ops); + break; + } + case OpRayQueryGetIntersectionWorldToObjectKHR: + { + emit_rayquery_function(".CommittedWorldToObject4x3()", ".CandidateWorldToObject4x3()", ops); + break; + } + case OpRayQueryGetRayFlagsKHR: + { + flush_variable_declaration(ops[0]); + emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".RayFlags()"), false); + break; + } + case OpRayQueryGetRayTMinKHR: + { + flush_variable_declaration(ops[0]); + emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".RayTMin()"), false); + break; + } + case OpRayQueryGetWorldRayOriginKHR: + { + flush_variable_declaration(ops[0]); + emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".WorldRayOrigin()"), false); + break; + } + case OpRayQueryGetWorldRayDirectionKHR: + { + flush_variable_declaration(ops[0]); + emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".WorldRayDirection()"), false); + break; + } + case OpSetMeshOutputsEXT: + { + statement("SetMeshOutputCounts(", to_unpacked_expression(ops[0]), ", ", to_unpacked_expression(ops[1]), ");"); + break; + } default: CompilerGLSL::emit_instruction(instruction); break; @@ -5645,7 +6560,7 @@ void CompilerHLSL::require_texture_query_variant(uint32_t var_id) void CompilerHLSL::set_root_constant_layouts(std::vector layout) { - root_constants_layout = move(layout); + root_constants_layout = std::move(layout); } void CompilerHLSL::add_vertex_attribute_remap(const HLSLVertexAttributeRemap &vertex_attributes) @@ -5668,14 +6583,14 @@ VariableID CompilerHLSL::remap_num_workgroups_builtin() uint32_t block_pointer_type_id = offset + 2; uint32_t variable_id = offset + 3; - SPIRType uint_type; + SPIRType uint_type { OpTypeVector }; uint_type.basetype = SPIRType::UInt; uint_type.width = 32; uint_type.vecsize = 3; uint_type.columns = 1; set(uint_type_id, uint_type); - SPIRType block_type; + SPIRType block_type { OpTypeStruct }; block_type.basetype = SPIRType::Struct; block_type.member_types.push_back(uint_type_id); set(block_type_id, block_type); @@ -5766,10 +6681,13 @@ string CompilerHLSL::compile() backend.can_return_array = false; backend.nonuniform_qualifier = "NonUniformResourceIndex"; backend.support_case_fallthrough = false; + backend.force_merged_mesh_block = get_execution_model() == ExecutionModelMeshEXT; + backend.force_gl_in_out_block = backend.force_merged_mesh_block; // SM 4.1 does not support precise for some reason. backend.support_precise_qualifier = hlsl_options.shader_model >= 50 || hlsl_options.shader_model == 40; + fixup_anonymous_struct_names(); fixup_type_alias(); reorder_type_alias(); build_function_control_flow_graphs_and_analyze(); @@ -5777,6 +6695,8 @@ string CompilerHLSL::compile() update_active_builtins(); analyze_image_and_sampler_usage(); analyze_interlocked_resource_usage(); + if (get_execution_model() == ExecutionModelMeshEXT) + analyze_meshlet_writes(); // Subpass input needs SV_Position. if (need_subpass_input) @@ -5785,10 +6705,7 @@ string CompilerHLSL::compile() uint32_t pass_count = 0; do { - if (pass_count >= 3) - SPIRV_CROSS_THROW("Over 3 compilation loops detected. Must be a bug!"); - - reset(); + reset(pass_count); // Move constructor for this type is broken on GCC 4.9 ... buffer.reset(); @@ -5881,7 +6798,16 @@ void CompilerHLSL::set_hlsl_force_storage_buffer_as_uav(uint32_t desc_set, uint3 force_uav_buffer_bindings.insert(pair); } -bool CompilerHLSL::builtin_translates_to_nonarray(spv::BuiltIn builtin) const +bool CompilerHLSL::is_user_type_structured(uint32_t id) const { - return (builtin == BuiltInSampleMask); + if (hlsl_options.preserve_structured_buffers) + { + // Compare left hand side of string only as these user types can contain more meta data such as their subtypes, + // e.g. "structuredbuffer:int" + const std::string &user_type = get_decoration_string(id, DecorationUserTypeGOOGLE); + return user_type.compare(0, 16, "structuredbuffer") == 0 || + user_type.compare(0, 18, "rwstructuredbuffer") == 0 || + user_type.compare(0, 33, "rasterizerorderedstructuredbuffer") == 0; + } + return false; } diff --git a/src/libraries/spirv_cross/spirv_hlsl.hpp b/src/libraries/spirv_cross/spirv_hlsl.hpp index 54a49dafa..bec458c61 100644 --- a/src/libraries/spirv_cross/spirv_hlsl.hpp +++ b/src/libraries/spirv_cross/spirv_hlsl.hpp @@ -98,6 +98,11 @@ struct HLSLResourceBinding } cbv, uav, srv, sampler; }; +enum HLSLAuxBinding +{ + HLSL_AUX_BINDING_BASE_VERTEX_INSTANCE = 0 +}; + class CompilerHLSL : public CompilerGLSL { public: @@ -105,7 +110,7 @@ class CompilerHLSL : public CompilerGLSL { uint32_t shader_model = 30; // TODO: map ps_4_0_level_9_0,... somehow - // Allows the PointSize builtin, and ignores it, as PointSize is not supported in HLSL. + // Allows the PointSize builtin in SM 4.0+, and ignores it, as PointSize is not supported in SM 4+. bool point_size_compat = false; // Allows the PointCoord builtin, returns float2(0.5, 0.5), as PointCoord is not supported in HLSL. @@ -121,7 +126,7 @@ class CompilerHLSL : public CompilerGLSL // By default, a readonly storage buffer will be declared as ByteAddressBuffer (SRV) instead. // Alternatively, use set_hlsl_force_storage_buffer_as_uav to specify individually. bool force_storage_buffer_as_uav = false; - + // Forces any storage image type marked as NonWritable to be considered an SRV instead. // For this to work with function call parameters, NonWritable must be considered to be part of the type system // so that NonWritable image arguments are also translated to Texture rather than RWTexture. @@ -137,6 +142,14 @@ class CompilerHLSL : public CompilerGLSL // If add_vertex_attribute_remap is used and this feature is used, // the semantic name will be queried once per active location. bool flatten_matrix_vertex_input_semantics = false; + + // Rather than emitting main() for the entry point, use the name in SPIR-V. + bool use_entry_point_name = false; + + // Preserve (RW)StructuredBuffer types if the input source was HLSL. + // This relies on UserTypeGOOGLE to encode the buffer type either as "structuredbuffer" or "rwstructuredbuffer" + // whereas the type can be extended with an optional subtype, e.g. "structuredbuffer:int". + bool preserve_structured_buffers = false; }; explicit CompilerHLSL(std::vector spirv_) @@ -208,6 +221,11 @@ class CompilerHLSL : public CompilerGLSL // Controls which storage buffer bindings will be forced to be declared as UAVs. void set_hlsl_force_storage_buffer_as_uav(uint32_t desc_set, uint32_t binding); + // By default, these magic buffers are not assigned a specific binding. + void set_hlsl_aux_buffer_binding(HLSLAuxBinding binding, uint32_t register_index, uint32_t register_space); + void unset_hlsl_aux_buffer_binding(HLSLAuxBinding binding); + bool is_hlsl_aux_buffer_binding_used(HLSLAuxBinding binding) const; + private: std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override; std::string image_type_hlsl(const SPIRType &type, uint32_t id); @@ -217,14 +235,13 @@ class CompilerHLSL : public CompilerGLSL void emit_hlsl_entry_point(); void emit_header() override; void emit_resources(); - void declare_undefined_values() override; void emit_interface_block_globally(const SPIRVariable &type); void emit_interface_block_in_struct(const SPIRVariable &var, std::unordered_set &active_locations); - void emit_interface_block_member_in_struct(const SPIRVariable &var, uint32_t member_index, - uint32_t location, + void emit_interface_block_member_in_struct(const SPIRVariable &var, uint32_t member_index, uint32_t location, std::unordered_set &active_locations); void emit_builtin_inputs_in_struct(); void emit_builtin_outputs_in_struct(); + void emit_builtin_primitive_outputs_in_struct(); void emit_texture_op(const Instruction &i, bool sparse) override; void emit_instruction(const Instruction &instruction) override; void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args, @@ -267,10 +284,14 @@ class CompilerHLSL : public CompilerGLSL void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index, const std::string &qualifier, uint32_t base_offset = 0) override; + void emit_rayquery_function(const char *commited, const char *candidate, const uint32_t *ops); + void emit_mesh_tasks(SPIRBlock &block) override; const char *to_storage_qualifiers_glsl(const SPIRVariable &var) override; void replace_illegal_names() override; + SPIRType::BaseType get_builtin_basetype(spv::BuiltIn builtin, SPIRType::BaseType default_type) override; + bool is_hlsl_force_storage_buffer_as_uav(ID id) const; Options hlsl_options; @@ -341,6 +362,10 @@ class CompilerHLSL : public CompilerGLSL TypeUnpackUint64 }; + void analyze_meshlet_writes(); + void analyze_meshlet_writes(uint32_t func_id, uint32_t id_per_vertex, uint32_t id_per_primitive, + std::unordered_set &processed_func_ids); + BitcastType get_bitcast_type(uint32_t result_type, uint32_t op0); void emit_builtin_variables(); @@ -369,10 +394,20 @@ class CompilerHLSL : public CompilerGLSL std::unordered_set force_uav_buffer_bindings; - // Returns true for BuiltInSampleMask because gl_SampleMask[] is an array in SPIR-V, but SV_Coverage is a scalar in HLSL. - bool builtin_translates_to_nonarray(spv::BuiltIn builtin) const override; + struct + { + uint32_t register_index = 0; + uint32_t register_space = 0; + bool explicit_binding = false; + bool used = false; + } base_vertex_info; + + // Returns true if the specified ID has a UserTypeGOOGLE decoration for StructuredBuffer or RWStructuredBuffer resources. + bool is_user_type_structured(uint32_t id) const override; std::vector composite_selection_workaround_types; + + std::string get_inner_entry_point_name() const; }; } // namespace SPIRV_CROSS_NAMESPACE diff --git a/src/libraries/spirv_cross/spirv_msl.cpp b/src/libraries/spirv_cross/spirv_msl.cpp index ffa69bfe7..200167a2e 100644 --- a/src/libraries/spirv_cross/spirv_msl.cpp +++ b/src/libraries/spirv_cross/spirv_msl.cpp @@ -37,7 +37,7 @@ static const uint32_t k_unknown_component = ~0u; static const char *force_inline = "static inline __attribute__((always_inline))"; CompilerMSL::CompilerMSL(std::vector spirv_) - : CompilerGLSL(move(spirv_)) + : CompilerGLSL(std::move(spirv_)) { } @@ -56,13 +56,20 @@ CompilerMSL::CompilerMSL(ParsedIR &&ir_) { } -void CompilerMSL::add_msl_shader_input(const MSLShaderInput &si) +void CompilerMSL::add_msl_shader_input(const MSLShaderInterfaceVariable &si) { inputs_by_location[{si.location, si.component}] = si; if (si.builtin != BuiltInMax && !inputs_by_builtin.count(si.builtin)) inputs_by_builtin[si.builtin] = si; } +void CompilerMSL::add_msl_shader_output(const MSLShaderInterfaceVariable &so) +{ + outputs_by_location[{so.location, so.component}] = so; + if (so.builtin != BuiltInMax && !outputs_by_builtin.count(so.builtin)) + outputs_by_builtin[so.builtin] = so; +} + void CompilerMSL::add_msl_resource_binding(const MSLResourceBinding &binding) { StageSetBinding tuple = { binding.stage, binding.desc_set, binding.binding }; @@ -150,6 +157,13 @@ bool CompilerMSL::is_msl_shader_input_used(uint32_t location) location_inputs_in_use_fallback.count(location) == 0; } +bool CompilerMSL::is_msl_shader_output_used(uint32_t location) +{ + // Don't report internal location allocations to app. + return location_outputs_in_use.count(location) != 0 && + location_outputs_in_use_fallback.count(location) == 0; +} + uint32_t CompilerMSL::get_automatic_builtin_input_location(spv::BuiltIn builtin) const { auto itr = builtin_to_automatic_input_location.find(builtin); @@ -159,6 +173,15 @@ uint32_t CompilerMSL::get_automatic_builtin_input_location(spv::BuiltIn builtin) return itr->second; } +uint32_t CompilerMSL::get_automatic_builtin_output_location(spv::BuiltIn builtin) const +{ + auto itr = builtin_to_automatic_output_location.find(builtin); + if (itr == builtin_to_automatic_output_location.end()) + return k_unknown_location; + else + return itr->second; +} + bool CompilerMSL::is_msl_resource_binding_used(ExecutionModel model, uint32_t desc_set, uint32_t binding) const { StageSetBinding tuple = { model, desc_set, binding }; @@ -166,10 +189,21 @@ bool CompilerMSL::is_msl_resource_binding_used(ExecutionModel model, uint32_t de return itr != end(resource_bindings) && itr->second.second; } -// Returns the size of the array of resources used by the variable with the specified id. -// The returned value is retrieved from the resource binding added using add_msl_resource_binding(). -uint32_t CompilerMSL::get_resource_array_size(uint32_t id) const +bool CompilerMSL::is_var_runtime_size_array(const SPIRVariable &var) const +{ + auto& type = get_variable_data_type(var); + return is_runtime_size_array(type) && get_resource_array_size(type, var.self) == 0; +} + +// Returns the size of the array of resources used by the variable with the specified type and id. +// The size is first retrieved from the type, but in the case of runtime array sizing, +// the size is retrieved from the resource binding added using add_msl_resource_binding(). +uint32_t CompilerMSL::get_resource_array_size(const SPIRType &type, uint32_t id) const { + uint32_t array_size = to_array_size_literal(type); + if (array_size) + return array_size; + StageSetBinding tuple = { get_entry_point().model, get_decoration(id, DecorationDescriptorSet), get_decoration(id, DecorationBinding) }; auto itr = resource_bindings.find(tuple); @@ -211,7 +245,8 @@ void CompilerMSL::build_implicit_builtins() bool need_sample_pos = active_input_builtins.get(BuiltInSamplePosition); bool need_vertex_params = capture_output_to_buffer && get_execution_model() == ExecutionModelVertex && !msl_options.vertex_for_tessellation; - bool need_tesc_params = get_execution_model() == ExecutionModelTessellationControl; + bool need_tesc_params = is_tesc_shader(); + bool need_tese_params = is_tese_shader() && msl_options.raw_buffer_tese_input; bool need_subgroup_mask = active_input_builtins.get(BuiltInSubgroupEqMask) || active_input_builtins.get(BuiltInSubgroupGeMask) || active_input_builtins.get(BuiltInSubgroupGtMask) || active_input_builtins.get(BuiltInSubgroupLeMask) || @@ -234,9 +269,9 @@ void CompilerMSL::build_implicit_builtins() bool need_workgroup_size = msl_options.emulate_subgroups && active_input_builtins.get(BuiltInNumSubgroups); if (need_subpass_input || need_sample_pos || need_subgroup_mask || need_vertex_params || need_tesc_params || - need_multiview || need_dispatch_base || need_vertex_base_params || need_grid_params || needs_sample_id || - needs_subgroup_invocation_id || needs_subgroup_size || has_additional_fixed_sample_mask() || need_local_invocation_index || - need_workgroup_size) + need_tese_params || need_multiview || need_dispatch_base || need_vertex_base_params || need_grid_params || + needs_sample_id || needs_subgroup_invocation_id || needs_subgroup_size || needs_helper_invocation || + has_additional_fixed_sample_mask() || need_local_invocation_index || need_workgroup_size) { bool has_frag_coord = false; bool has_sample_id = false; @@ -250,6 +285,7 @@ void CompilerMSL::build_implicit_builtins() bool has_subgroup_size = false; bool has_view_idx = false; bool has_layer = false; + bool has_helper_invocation = false; bool has_local_invocation_index = false; bool has_workgroup_size = false; uint32_t workgroup_id_type = 0; @@ -342,23 +378,28 @@ void CompilerMSL::build_implicit_builtins() } } - if (need_tesc_params) + if (need_tesc_params && builtin == BuiltInInvocationId) { - switch (builtin) - { - case BuiltInInvocationId: - builtin_invocation_id_id = var.self; - mark_implicit_builtin(StorageClassInput, BuiltInInvocationId, var.self); - has_invocation_id = true; - break; - case BuiltInPrimitiveId: - builtin_primitive_id_id = var.self; - mark_implicit_builtin(StorageClassInput, BuiltInPrimitiveId, var.self); - has_primitive_id = true; - break; - default: - break; - } + builtin_invocation_id_id = var.self; + mark_implicit_builtin(StorageClassInput, BuiltInInvocationId, var.self); + has_invocation_id = true; + } + + if ((need_tesc_params || need_tese_params) && builtin == BuiltInPrimitiveId) + { + builtin_primitive_id_id = var.self; + mark_implicit_builtin(StorageClassInput, BuiltInPrimitiveId, var.self); + has_primitive_id = true; + } + + if (need_tese_params && builtin == BuiltInTessLevelOuter) + { + tess_level_outer_var_id = var.self; + } + + if (need_tese_params && builtin == BuiltInTessLevelInner) + { + tess_level_inner_var_id = var.self; } if ((need_subgroup_mask || needs_subgroup_invocation_id) && builtin == BuiltInSubgroupLocalInvocationId) @@ -401,6 +442,13 @@ void CompilerMSL::build_implicit_builtins() } } + if (needs_helper_invocation && builtin == BuiltInHelperInvocation) + { + builtin_helper_invocation_id = var.self; + mark_implicit_builtin(StorageClassInput, BuiltInHelperInvocation, var.self); + has_helper_invocation = true; + } + if (need_local_invocation_index && builtin == BuiltInLocalInvocationIndex) { builtin_local_invocation_index_id = var.self; @@ -436,14 +484,14 @@ void CompilerMSL::build_implicit_builtins() uint32_t var_id = offset + 2; // Create gl_FragCoord. - SPIRType vec4_type; + SPIRType vec4_type { OpTypeVector }; vec4_type.basetype = SPIRType::Float; vec4_type.width = 32; vec4_type.vecsize = 4; set(type_id, vec4_type); - SPIRType vec4_type_ptr; - vec4_type_ptr = vec4_type; + SPIRType vec4_type_ptr = vec4_type; + vec4_type_ptr.op = OpTypePointer; vec4_type_ptr.pointer = true; vec4_type_ptr.pointer_depth++; vec4_type_ptr.parent_type = type_id; @@ -464,8 +512,8 @@ void CompilerMSL::build_implicit_builtins() uint32_t var_id = offset + 1; // Create gl_Layer. - SPIRType uint_type_ptr; - uint_type_ptr = get_uint_type(); + SPIRType uint_type_ptr = get_uint_type(); + uint_type_ptr.op = OpTypePointer; uint_type_ptr.pointer = true; uint_type_ptr.pointer_depth++; uint_type_ptr.parent_type = get_uint_type_id(); @@ -486,8 +534,8 @@ void CompilerMSL::build_implicit_builtins() uint32_t var_id = offset + 1; // Create gl_ViewIndex. - SPIRType uint_type_ptr; - uint_type_ptr = get_uint_type(); + SPIRType uint_type_ptr = get_uint_type(); + uint_type_ptr.op = OpTypePointer; uint_type_ptr.pointer = true; uint_type_ptr.pointer_depth++; uint_type_ptr.parent_type = get_uint_type_id(); @@ -509,8 +557,8 @@ void CompilerMSL::build_implicit_builtins() uint32_t var_id = offset + 1; // Create gl_SampleID. - SPIRType uint_type_ptr; - uint_type_ptr = get_uint_type(); + SPIRType uint_type_ptr = get_uint_type(); + uint_type_ptr.op = OpTypePointer; uint_type_ptr.pointer = true; uint_type_ptr.pointer_depth++; uint_type_ptr.parent_type = get_uint_type_id(); @@ -529,8 +577,8 @@ void CompilerMSL::build_implicit_builtins() { uint32_t type_ptr_id = ir.increase_bound_by(1); - SPIRType uint_type_ptr; - uint_type_ptr = get_uint_type(); + SPIRType uint_type_ptr = get_uint_type(); + uint_type_ptr.op = OpTypePointer; uint_type_ptr.pointer = true; uint_type_ptr.pointer_depth++; uint_type_ptr.parent_type = get_uint_type_id(); @@ -589,8 +637,8 @@ void CompilerMSL::build_implicit_builtins() // Note that we can't just abuse gl_ViewIndex for this purpose: it's an input, but // gl_Layer is an output in vertex-pipeline shaders. uint32_t type_ptr_out_id = ir.increase_bound_by(2); - SPIRType uint_type_ptr_out; - uint_type_ptr_out = get_uint_type(); + SPIRType uint_type_ptr_out = get_uint_type(); + uint_type_ptr.op = OpTypePointer; uint_type_ptr_out.pointer = true; uint_type_ptr_out.pointer_depth++; uint_type_ptr_out.parent_type = get_uint_type_id(); @@ -617,12 +665,12 @@ void CompilerMSL::build_implicit_builtins() } if ((need_tesc_params && (msl_options.multi_patch_workgroup || !has_invocation_id || !has_primitive_id)) || - need_grid_params) + (need_tese_params && !has_primitive_id) || need_grid_params) { uint32_t type_ptr_id = ir.increase_bound_by(1); - SPIRType uint_type_ptr; - uint_type_ptr = get_uint_type(); + SPIRType uint_type_ptr = get_uint_type(); + uint_type_ptr.op = OpTypePointer; uint_type_ptr.pointer = true; uint_type_ptr.pointer_depth++; uint_type_ptr.parent_type = get_uint_type_id(); @@ -630,7 +678,7 @@ void CompilerMSL::build_implicit_builtins() auto &ptr_type = set(type_ptr_id, uint_type_ptr); ptr_type.self = get_uint_type_id(); - if (msl_options.multi_patch_workgroup || need_grid_params) + if ((need_tesc_params && msl_options.multi_patch_workgroup) || need_grid_params) { uint32_t var_id = ir.increase_bound_by(1); @@ -651,7 +699,7 @@ void CompilerMSL::build_implicit_builtins() mark_implicit_builtin(StorageClassInput, BuiltInInvocationId, var_id); } - if (need_tesc_params && !has_primitive_id) + if ((need_tesc_params || need_tese_params) && !has_primitive_id) { uint32_t var_id = ir.increase_bound_by(1); @@ -681,8 +729,8 @@ void CompilerMSL::build_implicit_builtins() uint32_t var_id = offset + 1; // Create gl_SubgroupInvocationID. - SPIRType uint_type_ptr; - uint_type_ptr = get_uint_type(); + SPIRType uint_type_ptr = get_uint_type(); + uint_type_ptr.op = OpTypePointer; uint_type_ptr.pointer = true; uint_type_ptr.pointer_depth++; uint_type_ptr.parent_type = get_uint_type_id(); @@ -703,8 +751,8 @@ void CompilerMSL::build_implicit_builtins() uint32_t var_id = offset + 1; // Create gl_SubgroupSize. - SPIRType uint_type_ptr; - uint_type_ptr = get_uint_type(); + SPIRType uint_type_ptr = get_uint_type(); + uint_type_ptr.op = OpTypePointer; uint_type_ptr.pointer = true; uint_type_ptr.pointer_depth++; uint_type_ptr.parent_type = get_uint_type_id(); @@ -762,8 +810,8 @@ void CompilerMSL::build_implicit_builtins() uint32_t var_id = offset + 1; // Create gl_SampleMask. - SPIRType uint_type_ptr_out; - uint_type_ptr_out = get_uint_type(); + SPIRType uint_type_ptr_out = get_uint_type(); + uint_type_ptr_out.op = OpTypePointer; uint_type_ptr_out.pointer = true; uint_type_ptr_out.pointer_depth++; uint_type_ptr_out.parent_type = get_uint_type_id(); @@ -777,6 +825,35 @@ void CompilerMSL::build_implicit_builtins() mark_implicit_builtin(StorageClassOutput, BuiltInSampleMask, var_id); } + if (!has_helper_invocation && needs_helper_invocation) + { + uint32_t offset = ir.increase_bound_by(3); + uint32_t type_id = offset; + uint32_t type_ptr_id = offset + 1; + uint32_t var_id = offset + 2; + + // Create gl_HelperInvocation. + SPIRType bool_type { OpTypeBool }; + bool_type.basetype = SPIRType::Boolean; + bool_type.width = 8; + bool_type.vecsize = 1; + set(type_id, bool_type); + + SPIRType bool_type_ptr_in = bool_type; + bool_type_ptr_in.op = spv::OpTypePointer; + bool_type_ptr_in.pointer = true; + bool_type_ptr_in.pointer_depth++; + bool_type_ptr_in.parent_type = type_id; + bool_type_ptr_in.storage = StorageClassInput; + + auto &ptr_in_type = set(type_ptr_id, bool_type_ptr_in); + ptr_in_type.self = type_id; + set(var_id, type_ptr_id, StorageClassInput); + set_decoration(var_id, DecorationBuiltIn, BuiltInHelperInvocation); + builtin_helper_invocation_id = var_id; + mark_implicit_builtin(StorageClassInput, BuiltInHelperInvocation, var_id); + } + if (need_local_invocation_index && !has_local_invocation_index) { uint32_t offset = ir.increase_bound_by(2); @@ -784,8 +861,8 @@ void CompilerMSL::build_implicit_builtins() uint32_t var_id = offset + 1; // Create gl_LocalInvocationIndex. - SPIRType uint_type_ptr; - uint_type_ptr = get_uint_type(); + SPIRType uint_type_ptr = get_uint_type(); + uint_type_ptr.op = OpTypePointer; uint_type_ptr.pointer = true; uint_type_ptr.pointer_depth++; uint_type_ptr.parent_type = get_uint_type_id(); @@ -808,6 +885,7 @@ void CompilerMSL::build_implicit_builtins() // Create gl_WorkgroupSize. uint32_t type_id = build_extended_vector_type(get_uint_type_id(), 3); SPIRType uint_type_ptr = get(type_id); + uint_type_ptr.op = OpTypePointer; uint_type_ptr.pointer = true; uint_type_ptr.pointer_depth++; uint_type_ptr.parent_type = type_id; @@ -833,7 +911,7 @@ void CompilerMSL::build_implicit_builtins() swizzle_buffer_id = var_id; } - if (!buffers_requiring_array_length.empty()) + if (needs_buffer_size_buffer()) { uint32_t var_id = build_constant_uint_array_pointer(); set_name(var_id, "spvBufferSizeConstants"); @@ -868,11 +946,9 @@ void CompilerMSL::build_implicit_builtins() } // If we're returning a struct from a vertex-like entry point, we must return a position attribute. - bool need_position = - (get_execution_model() == ExecutionModelVertex || - get_execution_model() == ExecutionModelTessellationEvaluation) && - !capture_output_to_buffer && !get_is_rasterization_disabled() && - !active_output_builtins.get(BuiltInPosition); + bool need_position = (get_execution_model() == ExecutionModelVertex || is_tese_shader()) && + !capture_output_to_buffer && !get_is_rasterization_disabled() && + !active_output_builtins.get(BuiltInPosition); if (need_position) { @@ -917,14 +993,14 @@ void CompilerMSL::build_implicit_builtins() uint32_t var_id = offset + 2; // Create gl_Position. - SPIRType vec4_type; + SPIRType vec4_type { OpTypeVector }; vec4_type.basetype = SPIRType::Float; vec4_type.width = 32; vec4_type.vecsize = 4; set(type_id, vec4_type); - SPIRType vec4_type_ptr; - vec4_type_ptr = vec4_type; + SPIRType vec4_type_ptr = vec4_type; + vec4_type_ptr.op = OpTypePointer; vec4_type_ptr.pointer = true; vec4_type_ptr.pointer_depth++; vec4_type_ptr.parent_type = type_id; @@ -1001,6 +1077,7 @@ uint32_t CompilerMSL::build_constant_uint_array_pointer() // Create a buffer to hold extra data, including the swizzle constants. SPIRType uint_type_pointer = get_uint_type(); + uint_type_pointer.op = OpTypePointer; uint_type_pointer.pointer = true; uint_type_pointer.pointer_depth++; uint_type_pointer.parent_type = get_uint_type_id(); @@ -1062,7 +1139,7 @@ SPIRType &CompilerMSL::get_patch_stage_out_struct_type() std::string CompilerMSL::get_tess_factor_struct_name() { - if (get_entry_point().flags.get(ExecutionModeTriangles)) + if (is_tessellating_triangles()) return "MTLTriangleTessellationFactorsHalf"; return "MTLQuadTessellationFactorsHalf"; } @@ -1079,7 +1156,7 @@ uint32_t CompilerMSL::get_uint_type_id() uint_type_id = ir.increase_bound_by(1); - SPIRType type; + SPIRType type { OpTypeInt }; type.basetype = SPIRType::UInt; type.width = 32; set(uint_type_id, type); @@ -1205,8 +1282,7 @@ void CompilerMSL::emit_entry_point_declarations() args.push_back(join("max_anisotropy(", s.max_anisotropy, ")")); if (s.lod_clamp_enable) { - args.push_back(join("lod_clamp(", convert_to_string(s.lod_clamp_min, current_locale_radix_character), ", ", - convert_to_string(s.lod_clamp_max, current_locale_radix_character), ")")); + args.push_back(join("lod_clamp(", format_float(s.lod_clamp_min), ", ", format_float(s.lod_clamp_max), ")")); } // If we would emit no arguments, then omit the parentheses entirely. Otherwise, @@ -1248,7 +1324,7 @@ void CompilerMSL::emit_entry_point_declarations() else { is_using_builtin_array = true; - statement(get_argument_address_space(var), " ", type_to_glsl(type), "* ", to_restrict(var_id), name, + statement(get_argument_address_space(var), " ", type_to_glsl(type), "* ", to_restrict(var_id, true), name, type_to_array_glsl(type), " ="); uint32_t dim = uint32_t(type.array.size()); @@ -1283,30 +1359,111 @@ void CompilerMSL::emit_entry_point_declarations() } else { - statement(get_argument_address_space(var), " auto& ", to_restrict(var_id), name, " = *(", + statement(get_argument_address_space(var), " auto& ", to_restrict(var_id, true), name, " = *(", get_argument_address_space(var), " ", type_to_glsl(type), "* ", to_restrict(var_id, false), ")((", get_argument_address_space(var), " char* ", to_restrict(var_id, false), ")", to_name(arg_id), ".", ensure_valid_name(name, "m"), " + ", to_name(dynamic_offsets_buffer_id), "[", base_index, "]);"); } } - // Emit buffer arrays here. - for (uint32_t array_id : buffer_arrays) + bool has_runtime_array_declaration = false; + for (SPIRVariable *arg : entry_point_bindings) { - const auto &var = get(array_id); + const auto &var = *arg; const auto &type = get_variable_data_type(var); const auto &buffer_type = get_variable_element_type(var); - string name = to_name(array_id); - statement(get_argument_address_space(var), " ", type_to_glsl(buffer_type), "* ", to_restrict(array_id), name, - "[] ="); - begin_scope(); - for (uint32_t i = 0; i < to_array_size_literal(type); ++i) - statement(name, "_", i, ","); - end_scope_decl(); + const string name = to_name(var.self); + if (is_var_runtime_size_array(var)) + { + if (msl_options.argument_buffers_tier < Options::ArgumentBuffersTier::Tier2) + { + SPIRV_CROSS_THROW("Unsized array of descriptors requires argument buffer tier 2"); + } + switch (type.basetype) + { + case SPIRType::Image: + case SPIRType::Sampler: + case SPIRType::AccelerationStructure: + statement("spvDescriptorArray<", type_to_glsl(buffer_type), "> ", name, " {", name, "_};"); + break; + case SPIRType::SampledImage: + statement("spvDescriptorArray<", type_to_glsl(buffer_type), "> ", name, " {", name, "_};"); + statement("spvDescriptorArray ", name, "Smplr {", name, "Smplr_};"); + break; + case SPIRType::Struct: + statement("spvDescriptorArray<", get_argument_address_space(var), " ", type_to_glsl(buffer_type), "*> ", + name, " {", name, "_};"); + break; + default: + break; + } + has_runtime_array_declaration = true; + } + else if (!type.array.empty() && type.basetype == SPIRType::Struct) + { + // Emit only buffer arrays here. + statement(get_argument_address_space(var), " ", type_to_glsl(buffer_type), "* ", + to_restrict(var.self, true), name, "[] ="); + begin_scope(); + uint32_t array_size = get_resource_array_size(type, var.self); + for (uint32_t i = 0; i < array_size; ++i) + statement(name, "_", i, ","); + end_scope_decl(); + statement_no_indent(""); + } + } + + if (has_runtime_array_declaration) statement_no_indent(""); + + // Emit buffer aliases here. + for (auto &var_id : buffer_aliases_discrete) + { + const auto &var = get(var_id); + const auto &type = get_variable_data_type(var); + auto addr_space = get_argument_address_space(var); + auto name = to_name(var_id); + + uint32_t desc_set = get_decoration(var_id, DecorationDescriptorSet); + uint32_t desc_binding = get_decoration(var_id, DecorationBinding); + auto alias_name = join("spvBufferAliasSet", desc_set, "Binding", desc_binding); + + statement(addr_space, " auto& ", to_restrict(var_id, true), + name, + " = *(", addr_space, " ", type_to_glsl(type), "*)", alias_name, ";"); + } + // Discrete descriptors are processed in entry point emission every compiler iteration. + buffer_aliases_discrete.clear(); + + for (auto &var_pair : buffer_aliases_argument) + { + uint32_t var_id = var_pair.first; + uint32_t alias_id = var_pair.second; + + const auto &var = get(var_id); + const auto &type = get_variable_data_type(var); + auto addr_space = get_argument_address_space(var); + + if (type.array.empty()) + { + statement(addr_space, " auto& ", to_restrict(var_id, true), to_name(var_id), " = (", addr_space, " ", + type_to_glsl(type), "&)", ir.meta[alias_id].decoration.qualified_alias, ";"); + } + else + { + const char *desc_addr_space = descriptor_address_space(var_id, var.storage, "thread"); + + // Esoteric type cast. Reference to array of pointers. + // Auto here defers to UBO or SSBO. The address space of the reference needs to refer to the + // address space of the argument buffer itself, which is usually constant, but can be const device for + // large argument buffers. + is_using_builtin_array = true; + statement(desc_addr_space, " auto& ", to_restrict(var_id, true), to_name(var_id), " = (", addr_space, " ", + type_to_glsl(type), "* ", desc_addr_space, " (&)", + type_to_array_glsl(type), ")", ir.meta[alias_id].decoration.qualified_alias, ";"); + is_using_builtin_array = false; + } } - // For some reason, without this, we end up emitting the arrays twice. - buffer_arrays.clear(); // Emit disabled fragment outputs. std::sort(disabled_frag_outputs.begin(), disabled_frag_outputs.end()); @@ -1314,7 +1471,7 @@ void CompilerMSL::emit_entry_point_declarations() { auto &var = get(var_id); add_local_variable_name(var_id); - statement(variable_decl(var), ";"); + statement(CompilerGLSL::variable_decl(var), ";"); var.deferred_declaration = false; } } @@ -1339,8 +1496,6 @@ string CompilerMSL::compile() backend.basic_uint8_type = "uchar"; backend.basic_int16_type = "short"; backend.basic_uint16_type = "ushort"; - backend.discard_literal = "discard_fragment()"; - backend.demote_literal = "discard_fragment()"; backend.boolean_mix_function = "select"; backend.swizzle_is_function = false; backend.shared_is_implied = false; @@ -1356,13 +1511,15 @@ string CompilerMSL::compile() backend.support_small_type_sampling_result = true; backend.supports_empty_struct = true; backend.support_64bit_switch = true; + backend.boolean_in_struct_remapped_type = SPIRType::Short; // Allow Metal to use the array template unless we force it off. backend.can_return_array = !msl_options.force_native_arrays; backend.array_is_value_type = !msl_options.force_native_arrays; - // Arrays which are part of buffer objects are never considered to be native arrays. - backend.buffer_offset_array_is_value_type = false; + // Arrays which are part of buffer objects are never considered to be value types (just plain C-style). + backend.array_is_value_type_in_buffer_blocks = false; backend.support_pointer_to_pointer = true; + backend.implicit_c_integer_promotion_rules = true; capture_output_to_buffer = msl_options.capture_output_to_buffer; is_rasterization_disabled = msl_options.disable_rasterization || capture_output_to_buffer; @@ -1371,6 +1528,7 @@ string CompilerMSL::compile() for (auto &id : next_metal_resource_ids) id = 0; + fixup_anonymous_struct_names(); fixup_type_alias(); replace_illegal_names(); sync_entry_point_aliases_and_names(); @@ -1383,6 +1541,20 @@ string CompilerMSL::compile() preprocess_op_codes(); build_implicit_builtins(); + if (needs_manual_helper_invocation_updates() && + (active_input_builtins.get(BuiltInHelperInvocation) || needs_helper_invocation)) + { + string discard_expr = + join(builtin_to_glsl(BuiltInHelperInvocation, StorageClassInput), " = true, discard_fragment()"); + backend.discard_literal = discard_expr; + backend.demote_literal = discard_expr; + } + else + { + backend.discard_literal = "discard_fragment()"; + backend.demote_literal = "discard_fragment()"; + } + fixup_image_load_store_access(); set_enabled_interface_variables(get_active_interface_variables()); @@ -1390,19 +1562,19 @@ string CompilerMSL::compile() activate_argument_buffer_resources(); if (swizzle_buffer_id) - active_interface_variables.insert(swizzle_buffer_id); + add_active_interface_variable(swizzle_buffer_id); if (buffer_size_buffer_id) - active_interface_variables.insert(buffer_size_buffer_id); + add_active_interface_variable(buffer_size_buffer_id); if (view_mask_buffer_id) - active_interface_variables.insert(view_mask_buffer_id); + add_active_interface_variable(view_mask_buffer_id); if (dynamic_offsets_buffer_id) - active_interface_variables.insert(dynamic_offsets_buffer_id); + add_active_interface_variable(dynamic_offsets_buffer_id); if (builtin_layer_id) - active_interface_variables.insert(builtin_layer_id); + add_active_interface_variable(builtin_layer_id); if (builtin_dispatch_base_id && !msl_options.supports_msl_version(1, 2)) - active_interface_variables.insert(builtin_dispatch_base_id); + add_active_interface_variable(builtin_dispatch_base_id); if (builtin_sample_mask_id) - active_interface_variables.insert(builtin_sample_mask_id); + add_active_interface_variable(builtin_sample_mask_id); // Create structs to hold input, output and uniform variables. // Do output first to ensure out. is declared at top of entry function. @@ -1410,10 +1582,10 @@ string CompilerMSL::compile() stage_out_var_id = add_interface_block(StorageClassOutput); patch_stage_out_var_id = add_interface_block(StorageClassOutput, true); stage_in_var_id = add_interface_block(StorageClassInput); - if (get_execution_model() == ExecutionModelTessellationEvaluation) + if (is_tese_shader()) patch_stage_in_var_id = add_interface_block(StorageClassInput, true); - if (get_execution_model() == ExecutionModelTessellationControl) + if (is_tesc_shader()) stage_out_ptr_var_id = add_interface_block_pointer(stage_out_var_id, StorageClassOutput); if (is_tessellation_shader()) stage_in_ptr_var_id = add_interface_block_pointer(stage_in_var_id, StorageClassInput); @@ -1446,10 +1618,7 @@ string CompilerMSL::compile() uint32_t pass_count = 0; do { - if (pass_count >= 3) - SPIRV_CROSS_THROW("Over 3 compilation loops detected. Must be a bug!"); - - reset(); + reset(pass_count); // Start bindings at zero. next_metal_resource_index_buffer = 0; @@ -1490,13 +1659,13 @@ void CompilerMSL::preprocess_op_codes() // Before MSL 2.1 (2.2 for textures), Metal vertex functions that write to // resources must disable rasterization and return void. - if (preproc.uses_resource_write) + if ((preproc.uses_buffer_write && !msl_options.supports_msl_version(2, 1)) || + (preproc.uses_image_write && !msl_options.supports_msl_version(2, 2))) is_rasterization_disabled = true; // Tessellation control shaders are run as compute functions in Metal, and so // must capture their output to a buffer. - if (get_execution_model() == ExecutionModelTessellationControl || - (get_execution_model() == ExecutionModelVertex && msl_options.vertex_for_tessellation)) + if (is_tesc_shader() || (get_execution_model() == ExecutionModelVertex && msl_options.vertex_for_tessellation)) { is_rasterization_disabled = true; capture_output_to_buffer = true; @@ -1511,8 +1680,29 @@ void CompilerMSL::preprocess_op_codes() // that function would add gl_FragCoord. if (preproc.needs_sample_id || msl_options.force_sample_rate_shading || (is_sample_rate() && (active_input_builtins.get(BuiltInFragCoord) || - (need_subpass_input && !msl_options.use_framebuffer_fetch_subpasses)))) + (need_subpass_input_ms && !msl_options.use_framebuffer_fetch_subpasses)))) needs_sample_id = true; + if (preproc.needs_helper_invocation) + needs_helper_invocation = true; + + // OpKill is removed by the parser, so we need to identify those by inspecting + // blocks. + ir.for_each_typed_id([&preproc](uint32_t, SPIRBlock &block) { + if (block.terminator == SPIRBlock::Kill) + preproc.uses_discard = true; + }); + + // Fragment shaders that both write to storage resources and discard fragments + // need checks on the writes, to work around Metal allowing these writes despite + // the fragment being dead. + if (msl_options.check_discarded_frag_stores && preproc.uses_discard && + (preproc.uses_buffer_write || preproc.uses_image_write)) + { + frag_shader_needs_discard_checks = true; + needs_helper_invocation = true; + // Fragment discard store checks imply manual HelperInvocation updates. + msl_options.manual_helper_invocation_updates = true; + } if (is_intersection_query()) { @@ -1551,6 +1741,30 @@ void CompilerMSL::extract_global_variables_from_functions() // Uniforms unordered_set global_var_ids; ir.for_each_typed_id([&](uint32_t, SPIRVariable &var) { + // Some builtins resolve directly to a function call which does not need any declared variables. + // Skip these. + if (var.storage == StorageClassInput && has_decoration(var.self, DecorationBuiltIn)) + { + auto bi_type = BuiltIn(get_decoration(var.self, DecorationBuiltIn)); + if (bi_type == BuiltInHelperInvocation && !needs_manual_helper_invocation_updates()) + return; + if (bi_type == BuiltInHelperInvocation && needs_manual_helper_invocation_updates()) + { + if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3)) + SPIRV_CROSS_THROW("simd_is_helper_thread() requires version 2.3 on iOS."); + else if (msl_options.is_macos() && !msl_options.supports_msl_version(2, 1)) + SPIRV_CROSS_THROW("simd_is_helper_thread() requires version 2.1 on macOS."); + // Make sure this is declared and initialized. + // Force this to have the proper name. + set_name(var.self, builtin_to_glsl(BuiltInHelperInvocation, StorageClassInput)); + auto &entry_func = this->get(ir.default_entry_point); + entry_func.add_local_variable(var.self); + vars_needing_early_declaration.push_back(var.self); + entry_func.fixup_hooks_in.push_back([this, &var]() + { statement(to_name(var.self), " = simd_is_helper_thread();"); }); + } + } + if (var.storage == StorageClassInput || var.storage == StorageClassOutput || var.storage == StorageClassUniform || var.storage == StorageClassUniformConstant || var.storage == StorageClassPushConstant || var.storage == StorageClassStorageBuffer) @@ -1664,6 +1878,9 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std:: if (global_var_ids.find(rvalue_id) != global_var_ids.end()) added_arg_ids.insert(rvalue_id); + if (needs_frag_discard_checks()) + added_arg_ids.insert(builtin_helper_invocation_id); + break; } @@ -1678,14 +1895,46 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std:: break; } + case OpAtomicExchange: + case OpAtomicCompareExchange: + case OpAtomicStore: + case OpAtomicIIncrement: + case OpAtomicIDecrement: + case OpAtomicIAdd: + case OpAtomicFAddEXT: + case OpAtomicISub: + case OpAtomicSMin: + case OpAtomicUMin: + case OpAtomicSMax: + case OpAtomicUMax: + case OpAtomicAnd: + case OpAtomicOr: + case OpAtomicXor: + case OpImageWrite: + { + if (needs_frag_discard_checks()) + added_arg_ids.insert(builtin_helper_invocation_id); + uint32_t ptr = 0; + if (op == OpAtomicStore || op == OpImageWrite) + ptr = ops[0]; + else + ptr = ops[2]; + if (global_var_ids.find(ptr) != global_var_ids.end()) + added_arg_ids.insert(ptr); + break; + } + // Emulate texture2D atomic operations case OpImageTexelPointer: { // When using the pointer, we need to know which variable it is actually loaded from. uint32_t base_id = ops[2]; auto *var = maybe_get_backing_variable(base_id); - if (var && atomic_image_vars.count(var->self)) + if (var && atomic_image_vars_emulated.count(var->self)) { + if (!get(var->basetype).array.empty()) + SPIRV_CROSS_THROW("Cannot emulate array of storage images with atomics. Use MSL 3.1 for native support."); + if (global_var_ids.find(base_id) != global_var_ids.end()) added_arg_ids.insert(base_id); } @@ -1759,10 +2008,64 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std:: break; } + case OpDemoteToHelperInvocation: + if (needs_manual_helper_invocation_updates() && + (active_input_builtins.get(BuiltInHelperInvocation) || needs_helper_invocation)) + added_arg_ids.insert(builtin_helper_invocation_id); + break; + + case OpIsHelperInvocationEXT: + if (needs_manual_helper_invocation_updates()) + added_arg_ids.insert(builtin_helper_invocation_id); + break; + + case OpRayQueryInitializeKHR: + case OpRayQueryProceedKHR: + case OpRayQueryTerminateKHR: + case OpRayQueryGenerateIntersectionKHR: + case OpRayQueryConfirmIntersectionKHR: + { + // Ray query accesses memory directly, need check pass down object if using Private storage class. + uint32_t base_id = ops[0]; + if (global_var_ids.find(base_id) != global_var_ids.end()) + added_arg_ids.insert(base_id); + break; + } + + case OpRayQueryGetRayTMinKHR: + case OpRayQueryGetRayFlagsKHR: + case OpRayQueryGetWorldRayOriginKHR: + case OpRayQueryGetWorldRayDirectionKHR: + case OpRayQueryGetIntersectionCandidateAABBOpaqueKHR: + case OpRayQueryGetIntersectionTypeKHR: + case OpRayQueryGetIntersectionTKHR: + case OpRayQueryGetIntersectionInstanceCustomIndexKHR: + case OpRayQueryGetIntersectionInstanceIdKHR: + case OpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: + case OpRayQueryGetIntersectionGeometryIndexKHR: + case OpRayQueryGetIntersectionPrimitiveIndexKHR: + case OpRayQueryGetIntersectionBarycentricsKHR: + case OpRayQueryGetIntersectionFrontFaceKHR: + case OpRayQueryGetIntersectionObjectRayDirectionKHR: + case OpRayQueryGetIntersectionObjectRayOriginKHR: + case OpRayQueryGetIntersectionObjectToWorldKHR: + case OpRayQueryGetIntersectionWorldToObjectKHR: + { + // Ray query accesses memory directly, need check pass down object if using Private storage class. + uint32_t base_id = ops[2]; + if (global_var_ids.find(base_id) != global_var_ids.end()) + added_arg_ids.insert(base_id); + break; + } + default: break; } + if (needs_manual_helper_invocation_updates() && b.terminator == SPIRBlock::Kill && + (active_input_builtins.get(BuiltInHelperInvocation) || needs_helper_invocation)) + added_arg_ids.insert(builtin_helper_invocation_id); + // TODO: Add all other operations which can affect memory. // We should consider a more unified system here to reduce boiler-plate. // This kind of analysis is done in several places ... @@ -1789,9 +2092,8 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std:: bool is_patch = has_decoration(arg_id, DecorationPatch) || is_patch_block(*p_type); bool is_block = has_decoration(p_type->self, DecorationBlock); bool is_control_point_storage = - !is_patch && - ((is_tessellation_shader() && var.storage == StorageClassInput) || - (get_execution_model() == ExecutionModelTessellationControl && var.storage == StorageClassOutput)); + !is_patch && ((is_tessellation_shader() && var.storage == StorageClassInput) || + (is_tesc_shader() && var.storage == StorageClassOutput)); bool is_patch_block_storage = is_patch && is_block && var.storage == StorageClassOutput; bool is_builtin = is_builtin_variable(var); bool variable_is_stage_io = @@ -1807,8 +2109,8 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std:: if (is_redirected_to_global_stage_io) { - // Tessellation control shaders see inputs and per-vertex outputs as arrays. - // Similarly, tessellation evaluation shaders see per-vertex inputs as arrays. + // Tessellation control shaders see inputs and per-point outputs as arrays. + // Similarly, tessellation evaluation shaders see per-point inputs as arrays. // We collected them into a structure; we must pass the array of this // structure to the function. std::string name; @@ -1831,10 +2133,6 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std:: } } - // Tessellation control shaders see inputs and per-vertex outputs as arrays. - // Similarly, tessellation evaluation shaders see per-vertex inputs as arrays. - // We collected them into a structure; we must pass the array of this - // structure to the function. if (var.storage == StorageClassInput) { auto &added_in = is_patch ? patch_added_in : control_point_added_in; @@ -1858,6 +2156,8 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std:: set(next_id, type_id, StorageClassFunction, 0, arg_id); set_name(next_id, name); + if (is_tese_shader() && msl_options.raw_buffer_tese_input && var.storage == StorageClassInput) + set_decoration(next_id, DecorationNonWritable); } else if (is_builtin && has_decoration(p_type->self, DecorationBlock)) { @@ -1899,8 +2199,7 @@ void CompilerMSL::extract_global_variables_from_function(uint32_t func_id, std:: func.add_parameter(type_id, next_id, true); set(next_id, type_id, StorageClassFunction, 0, arg_id); - // Ensure the existing variable has a valid name and the new variable has all the same meta info - set_name(arg_id, ensure_valid_name(to_name(arg_id), "v")); + // Ensure the new variable has all the same meta info ir.meta[next_id] = ir.meta[arg_id]; } } @@ -1921,6 +2220,20 @@ void CompilerMSL::mark_packable_structs() (has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock))) mark_as_packable(type); } + + if (var.storage == StorageClassWorkgroup) + { + auto *type = &this->get(var.basetype); + if (type->basetype == SPIRType::Struct) + mark_as_workgroup_struct(*type); + } + }); + + // Physical storage buffer pointers can appear outside of the context of a variable, if the address + // is calculated from a ulong or uvec2 and cast to a pointer, so check if they need to be packed too. + ir.for_each_typed_id([&](uint32_t, SPIRType &type) { + if (type.basetype == SPIRType::Struct && type.pointer && type.storage == StorageClassPhysicalStorageBuffer) + mark_as_packable(type); }); } @@ -1935,7 +2248,8 @@ void CompilerMSL::mark_as_packable(SPIRType &type) return; } - if (type.basetype == SPIRType::Struct) + // Handle possible recursion when a struct contains a pointer to its own type nested somewhere. + if (type.basetype == SPIRType::Struct && !has_extended_decoration(type.self, SPIRVCrossDecorationBufferBlockRepacked)) { set_extended_decoration(type.self, SPIRVCrossDecorationBufferBlockRepacked); @@ -1955,19 +2269,63 @@ void CompilerMSL::mark_as_packable(SPIRType &type) } } +// If the specified type is a struct, it and any nested structs +// are marked as used with workgroup storage using the SPIRVCrossDecorationWorkgroupStruct decoration. +void CompilerMSL::mark_as_workgroup_struct(SPIRType &type) +{ + // If this is not the base type (eg. it's a pointer or array), tunnel down + if (type.parent_type) + { + mark_as_workgroup_struct(get(type.parent_type)); + return; + } + + // Handle possible recursion when a struct contains a pointer to its own type nested somewhere. + if (type.basetype == SPIRType::Struct && !has_extended_decoration(type.self, SPIRVCrossDecorationWorkgroupStruct)) + { + set_extended_decoration(type.self, SPIRVCrossDecorationWorkgroupStruct); + + // Recurse + uint32_t mbr_cnt = uint32_t(type.member_types.size()); + for (uint32_t mbr_idx = 0; mbr_idx < mbr_cnt; mbr_idx++) + { + uint32_t mbr_type_id = type.member_types[mbr_idx]; + auto &mbr_type = get(mbr_type_id); + mark_as_workgroup_struct(mbr_type); + if (mbr_type.type_alias) + { + auto &mbr_type_alias = get(mbr_type.type_alias); + mark_as_workgroup_struct(mbr_type_alias); + } + } + } +} + // If a shader input exists at the location, it is marked as being used by this shader void CompilerMSL::mark_location_as_used_by_shader(uint32_t location, const SPIRType &type, StorageClass storage, bool fallback) { - if (storage != StorageClassInput) - return; - uint32_t count = type_to_location_count(type); - for (uint32_t i = 0; i < count; i++) + switch (storage) { - location_inputs_in_use.insert(location + i); - if (fallback) - location_inputs_in_use_fallback.insert(location + i); + case StorageClassInput: + for (uint32_t i = 0; i < count; i++) + { + location_inputs_in_use.insert(location + i); + if (fallback) + location_inputs_in_use_fallback.insert(location + i); + } + break; + case StorageClassOutput: + for (uint32_t i = 0; i < count; i++) + { + location_outputs_in_use.insert(location + i); + if (fallback) + location_outputs_in_use_fallback.insert(location + i); + } + break; + default: + return; } } @@ -1982,9 +2340,27 @@ uint32_t CompilerMSL::get_target_components_for_fragment_location(uint32_t locat uint32_t CompilerMSL::build_extended_vector_type(uint32_t type_id, uint32_t components, SPIRType::BaseType basetype) { + assert(components > 1); uint32_t new_type_id = ir.increase_bound_by(1); - auto &old_type = get(type_id); - auto *type = &set(new_type_id, old_type); + const auto *p_old_type = &get(type_id); + const SPIRType *old_ptr_t = nullptr; + const SPIRType *old_array_t = nullptr; + + if (is_pointer(*p_old_type)) + { + old_ptr_t = p_old_type; + p_old_type = &get_pointee_type(*old_ptr_t); + } + + if (is_array(*p_old_type)) + { + old_array_t = p_old_type; + p_old_type = &get_type(old_array_t->parent_type); + } + + auto *type = &set(new_type_id, *p_old_type); + assert(is_scalar(*type) || is_vector(*type)); + type->op = OpTypeVector; type->vecsize = components; if (basetype != SPIRType::Unknown) type->basetype = basetype; @@ -1994,23 +2370,24 @@ uint32_t CompilerMSL::build_extended_vector_type(uint32_t type_id, uint32_t comp type->array_size_literal.clear(); type->pointer = false; - if (is_array(old_type)) + if (old_array_t) { uint32_t array_type_id = ir.increase_bound_by(1); type = &set(array_type_id, *type); + type->op = OpTypeArray; type->parent_type = new_type_id; - type->array = old_type.array; - type->array_size_literal = old_type.array_size_literal; + type->array = old_array_t->array; + type->array_size_literal = old_array_t->array_size_literal; new_type_id = array_type_id; } - if (old_type.pointer) + if (old_ptr_t) { uint32_t ptr_type_id = ir.increase_bound_by(1); type = &set(ptr_type_id, *type); - type->self = new_type_id; + type->op = OpTypePointer; type->parent_type = new_type_id; - type->storage = old_type.storage; + type->storage = old_ptr_t->storage; type->pointer = true; type->pointer_depth++; new_type_id = ptr_type_id; @@ -2063,7 +2440,7 @@ bool CompilerMSL::add_component_variable_to_interface_block(spv::StorageClass st if (pad_fragment_output) { uint32_t locn = get_decoration(var.self, DecorationLocation); - num_components = std::max(num_components, get_target_components_for_fragment_location(locn)); + num_components = max(num_components, get_target_components_for_fragment_location(locn)); } // We have already declared an IO block member as m_location_N. @@ -2268,6 +2645,12 @@ void CompilerMSL::add_plain_variable_to_interface_block(StorageClass storage, co set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); mark_location_as_used_by_shader(locn, type, storage); } + else if (is_builtin && capture_output_to_buffer && storage == StorageClassOutput && outputs_by_builtin.count(builtin)) + { + uint32_t locn = outputs_by_builtin[builtin].location; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); + mark_location_as_used_by_shader(locn, type, storage); + } if (get_decoration_bitset(var.self).get(DecorationComponent)) { @@ -2433,6 +2816,12 @@ void CompilerMSL::add_composite_variable_to_interface_block(StorageClass storage set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); mark_location_as_used_by_shader(locn, *usable_type, storage); } + else if (is_builtin && capture_output_to_buffer && storage == StorageClassOutput && outputs_by_builtin.count(builtin)) + { + uint32_t locn = outputs_by_builtin[builtin].location + i; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); + mark_location_as_used_by_shader(locn, *usable_type, storage); + } else if (is_builtin && (builtin == BuiltInClipDistance || builtin == BuiltInCullDistance)) { // Declare the Clip/CullDistance as [[user(clip/cullN)]]. @@ -2511,12 +2900,15 @@ void CompilerMSL::add_composite_variable_to_interface_block(StorageClass storage } } -void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass storage, const string &ib_var_ref, - SPIRType &ib_type, SPIRVariable &var, - uint32_t mbr_idx, InterfaceBlockMeta &meta) +void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass storage, + const string &ib_var_ref, SPIRType &ib_type, + SPIRVariable &var, SPIRType &var_type, + uint32_t mbr_idx, InterfaceBlockMeta &meta, + const string &mbr_name_qual, + const string &var_chain_qual, + uint32_t &location, uint32_t &var_mbr_idx) { auto &entry_func = get(ir.default_entry_point); - auto &var_type = meta.strip_array ? get_variable_element_type(var) : get_variable_data_type(var); BuiltIn builtin = BuiltInMax; bool is_builtin = is_member_builtin(var_type, mbr_idx, &builtin); @@ -2531,13 +2923,15 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass uint32_t mbr_type_id = var_type.member_types[mbr_idx]; auto &mbr_type = get(mbr_type_id); - uint32_t elem_cnt = 0; + bool mbr_is_indexable = false; + uint32_t elem_cnt = 1; if (is_matrix(mbr_type)) { if (is_array(mbr_type)) SPIRV_CROSS_THROW("MSL cannot emit arrays-of-matrices in input and output variables."); + mbr_is_indexable = true; elem_cnt = mbr_type.columns; } else if (is_array(mbr_type)) @@ -2545,6 +2939,7 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass if (mbr_type.array.size() != 1) SPIRV_CROSS_THROW("MSL cannot emit arrays-of-arrays in input and output variables."); + mbr_is_indexable = true; elem_cnt = to_array_size_literal(mbr_type); } @@ -2575,6 +2970,27 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass return; } + // Recursively handle nested structures. + if (mbr_type.basetype == SPIRType::Struct) + { + for (uint32_t i = 0; i < elem_cnt; i++) + { + string mbr_name = append_member_name(mbr_name_qual, var_type, mbr_idx) + (mbr_is_indexable ? join("_", i) : ""); + string var_chain = join(var_chain_qual, ".", to_member_name(var_type, mbr_idx), (mbr_is_indexable ? join("[", i, "]") : "")); + uint32_t sub_mbr_cnt = uint32_t(mbr_type.member_types.size()); + for (uint32_t sub_mbr_idx = 0; sub_mbr_idx < sub_mbr_cnt; sub_mbr_idx++) + { + add_composite_member_variable_to_interface_block(storage, ib_var_ref, ib_type, + var, mbr_type, sub_mbr_idx, + meta, mbr_name, var_chain, + location, var_mbr_idx); + // FIXME: Recursive structs and tessellation breaks here. + var_mbr_idx++; + } + } + return; + } + for (uint32_t i = 0; i < elem_cnt; i++) { // Add a reference to the variable type to the interface struct. @@ -2585,26 +3001,47 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass ib_type.member_types.push_back(usable_type->self); // Give the member a name - string mbr_name = ensure_valid_name(join(to_qualified_member_name(var_type, mbr_idx), "_", i), "m"); + string mbr_name = ensure_valid_name(append_member_name(mbr_name_qual, var_type, mbr_idx) + (mbr_is_indexable ? join("_", i) : ""), "m"); set_member_name(ib_type.self, ib_mbr_idx, mbr_name); - if (has_member_decoration(var_type.self, mbr_idx, DecorationLocation)) + // Once we determine the location of the first member within nested structures, + // from a var of the topmost structure, the remaining flattened members of + // the nested structures will have consecutive location values. At this point, + // we've recursively tunnelled into structs, arrays, and matrices, and are + // down to a single location for each member now. + if (!is_builtin && location != UINT32_MAX) { - uint32_t locn = get_member_decoration(var_type.self, mbr_idx, DecorationLocation) + i; - set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); - mark_location_as_used_by_shader(locn, *usable_type, storage); + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, *usable_type, storage); + location++; + } + else if (has_member_decoration(var_type.self, mbr_idx, DecorationLocation)) + { + location = get_member_decoration(var_type.self, mbr_idx, DecorationLocation) + i; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, *usable_type, storage); + location++; } else if (has_decoration(var.self, DecorationLocation)) { - uint32_t locn = get_accumulated_member_location(var, mbr_idx, meta.strip_array) + i; - set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); - mark_location_as_used_by_shader(locn, *usable_type, storage); + location = get_accumulated_member_location(var, mbr_idx, meta.strip_array) + i; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, *usable_type, storage); + location++; } else if (is_builtin && is_tessellation_shader() && storage == StorageClassInput && inputs_by_builtin.count(builtin)) { - uint32_t locn = inputs_by_builtin[builtin].location + i; - set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); - mark_location_as_used_by_shader(locn, *usable_type, storage); + location = inputs_by_builtin[builtin].location + i; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, *usable_type, storage); + location++; + } + else if (is_builtin && capture_output_to_buffer && storage == StorageClassOutput && outputs_by_builtin.count(builtin)) + { + location = outputs_by_builtin[builtin].location + i; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, *usable_type, storage); + location++; } else if (is_builtin && (builtin == BuiltInClipDistance || builtin == BuiltInCullDistance)) { @@ -2614,7 +3051,7 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass } if (has_member_decoration(var_type.self, mbr_idx, DecorationComponent)) - SPIRV_CROSS_THROW("DecorationComponent on matrices and arrays make little sense."); + SPIRV_CROSS_THROW("DecorationComponent on matrices and arrays is not supported."); if (storage != StorageClassInput || !pull_model_inputs.count(var.self)) { @@ -2630,47 +3067,36 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass } set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceOrigID, var.self); - set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceMemberIndex, mbr_idx); + set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceMemberIndex, var_mbr_idx); // Unflatten or flatten from [[stage_in]] or [[stage_out]] as appropriate. if (!meta.strip_array && meta.allow_local_declaration) { + string var_chain = join(var_chain_qual, ".", to_member_name(var_type, mbr_idx), (mbr_is_indexable ? join("[", i, "]") : "")); switch (storage) { case StorageClassInput: - entry_func.fixup_hooks_in.push_back([=, &var, &var_type]() { + entry_func.fixup_hooks_in.push_back([=, &var]() { + string lerp_call; if (pull_model_inputs.count(var.self)) { - string lerp_call; if (is_centroid) lerp_call = ".interpolate_at_centroid()"; else if (is_sample) lerp_call = join(".interpolate_at_sample(", to_expression(builtin_sample_id_id), ")"); else lerp_call = ".interpolate_at_center()"; - statement(to_name(var.self), ".", to_member_name(var_type, mbr_idx), "[", i, "] = ", ib_var_ref, - ".", mbr_name, lerp_call, ";"); - } - else - { - statement(to_name(var.self), ".", to_member_name(var_type, mbr_idx), "[", i, "] = ", ib_var_ref, - ".", mbr_name, ";"); } + statement(var_chain, " = ", ib_var_ref, ".", mbr_name, lerp_call, ";"); }); break; case StorageClassOutput: - entry_func.fixup_hooks_out.push_back([=, &var, &var_type]() { + entry_func.fixup_hooks_out.push_back([=]() { if (flatten_from_ib_var) - { - statement(ib_var_ref, ".", mbr_name, " = ", ib_var_ref, ".", flatten_from_ib_mbr_name, "[", i, - "];"); - } + statement(ib_var_ref, ".", mbr_name, " = ", ib_var_ref, ".", flatten_from_ib_mbr_name, "[", i, "];"); else - { - statement(ib_var_ref, ".", mbr_name, " = ", to_name(var.self), ".", - to_member_name(var_type, mbr_idx), "[", i, "];"); - } + statement(ib_var_ref, ".", mbr_name, " = ", var_chain, ";"); }); break; @@ -2681,11 +3107,14 @@ void CompilerMSL::add_composite_member_variable_to_interface_block(StorageClass } } -void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass storage, const string &ib_var_ref, - SPIRType &ib_type, SPIRVariable &var, uint32_t mbr_idx, - InterfaceBlockMeta &meta) +void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass storage, + const string &ib_var_ref, SPIRType &ib_type, + SPIRVariable &var, SPIRType &var_type, + uint32_t mbr_idx, InterfaceBlockMeta &meta, + const string &mbr_name_qual, + const string &var_chain_qual, + uint32_t &location, uint32_t &var_mbr_idx) { - auto &var_type = meta.strip_array ? get_variable_element_type(var) : get_variable_data_type(var); auto &entry_func = get(ir.default_entry_point); BuiltIn builtin = BuiltInMax; @@ -2710,7 +3139,7 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor ib_type.member_types.push_back(mbr_type_id); // Give the member a name - string mbr_name = ensure_valid_name(to_qualified_member_name(var_type, mbr_idx), "m"); + string mbr_name = ensure_valid_name(append_member_name(mbr_name_qual, var_type, mbr_idx), "m"); set_member_name(ib_type.self, ib_mbr_idx, mbr_name); // Update the original variable reference to include the structure reference @@ -2727,7 +3156,7 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor } bool flatten_stage_out = false; - + string var_chain = var_chain_qual + "." + to_member_name(var_type, mbr_idx); if (is_builtin && !meta.strip_array) { // For the builtin gl_PerVertex, we cannot treat it as a block anyways, @@ -2740,15 +3169,15 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor switch (storage) { case StorageClassInput: - entry_func.fixup_hooks_in.push_back([=, &var, &var_type]() { - statement(to_name(var.self), ".", to_member_name(var_type, mbr_idx), " = ", qual_var_name, ";"); + entry_func.fixup_hooks_in.push_back([=]() { + statement(var_chain, " = ", qual_var_name, ";"); }); break; case StorageClassOutput: flatten_stage_out = true; - entry_func.fixup_hooks_out.push_back([=, &var, &var_type]() { - statement(qual_var_name, " = ", to_name(var.self), ".", to_member_name(var_type, mbr_idx), ";"); + entry_func.fixup_hooks_out.push_back([=]() { + statement(qual_var_name, " = ", var_chain, ";"); }); break; @@ -2757,48 +3186,63 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor } } - // Copy the variable location from the original variable to the member - if (has_member_decoration(var_type.self, mbr_idx, DecorationLocation)) + // Once we determine the location of the first member within nested structures, + // from a var of the topmost structure, the remaining flattened members of + // the nested structures will have consecutive location values. At this point, + // we've recursively tunnelled into structs, arrays, and matrices, and are + // down to a single location for each member now. + if (!is_builtin && location != UINT32_MAX) + { + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, get(mbr_type_id), storage); + location += type_to_location_count(get(mbr_type_id)); + } + else if (has_member_decoration(var_type.self, mbr_idx, DecorationLocation)) { - uint32_t locn = get_member_decoration(var_type.self, mbr_idx, DecorationLocation); + location = get_member_decoration(var_type.self, mbr_idx, DecorationLocation); uint32_t comp = get_member_decoration(var_type.self, mbr_idx, DecorationComponent); if (storage == StorageClassInput) { - mbr_type_id = ensure_correct_input_type(mbr_type_id, locn, comp, 0, meta.strip_array); + mbr_type_id = ensure_correct_input_type(mbr_type_id, location, comp, 0, meta.strip_array); var_type.member_types[mbr_idx] = mbr_type_id; if (storage == StorageClassInput && pull_model_inputs.count(var.self)) ib_type.member_types[ib_mbr_idx] = build_msl_interpolant_type(mbr_type_id, is_noperspective); else ib_type.member_types[ib_mbr_idx] = mbr_type_id; } - set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); - mark_location_as_used_by_shader(locn, get(mbr_type_id), storage); + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, get(mbr_type_id), storage); + location += type_to_location_count(get(mbr_type_id)); } else if (has_decoration(var.self, DecorationLocation)) { - // The block itself might have a location and in this case, all members of the block - // receive incrementing locations. - uint32_t locn = get_accumulated_member_location(var, mbr_idx, meta.strip_array); + location = get_accumulated_member_location(var, mbr_idx, meta.strip_array); if (storage == StorageClassInput) { - mbr_type_id = ensure_correct_input_type(mbr_type_id, locn, 0, 0, meta.strip_array); + mbr_type_id = ensure_correct_input_type(mbr_type_id, location, 0, 0, meta.strip_array); var_type.member_types[mbr_idx] = mbr_type_id; if (storage == StorageClassInput && pull_model_inputs.count(var.self)) ib_type.member_types[ib_mbr_idx] = build_msl_interpolant_type(mbr_type_id, is_noperspective); else ib_type.member_types[ib_mbr_idx] = mbr_type_id; } - set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); - mark_location_as_used_by_shader(locn, get(mbr_type_id), storage); + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, get(mbr_type_id), storage); + location += type_to_location_count(get(mbr_type_id)); } else if (is_builtin && is_tessellation_shader() && storage == StorageClassInput && inputs_by_builtin.count(builtin)) { - uint32_t locn = 0; - auto builtin_itr = inputs_by_builtin.find(builtin); - if (builtin_itr != end(inputs_by_builtin)) - locn = builtin_itr->second.location; - set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, locn); - mark_location_as_used_by_shader(locn, get(mbr_type_id), storage); + location = inputs_by_builtin[builtin].location; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, get(mbr_type_id), storage); + location += type_to_location_count(get(mbr_type_id)); + } + else if (is_builtin && capture_output_to_buffer && storage == StorageClassOutput && outputs_by_builtin.count(builtin)) + { + location = outputs_by_builtin[builtin].location; + set_member_decoration(ib_type.self, ib_mbr_idx, DecorationLocation, location); + mark_location_as_used_by_shader(location, get(mbr_type_id), storage); + location += type_to_location_count(get(mbr_type_id)); } // Copy the component location, if present. @@ -2857,7 +3301,7 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor } set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceOrigID, var.self); - set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceMemberIndex, mbr_idx); + set_extended_member_decoration(ib_type.self, ib_mbr_idx, SPIRVCrossDecorationInterfaceMemberIndex, var_mbr_idx); } // In Metal, the tessellation levels are stored as tightly packed half-precision floating point values. @@ -2868,19 +3312,10 @@ void CompilerMSL::add_plain_member_variable_to_interface_block(StorageClass stor void CompilerMSL::add_tess_level_input_to_interface_block(const std::string &ib_var_ref, SPIRType &ib_type, SPIRVariable &var) { - auto &entry_func = get(ir.default_entry_point); auto &var_type = get_variable_element_type(var); BuiltIn builtin = BuiltIn(get_decoration(var.self, DecorationBuiltIn)); - - // Force the variable to have the proper name. - string var_name = builtin_to_glsl(builtin, StorageClassFunction); - set_name(var.self, var_name); - - // We need to declare the variable early and at entry-point scope. - entry_func.add_local_variable(var.self); - vars_needing_early_declaration.push_back(var.self); - bool triangles = get_execution_mode_bitset().get(ExecutionModeTriangles); + bool triangles = is_tessellating_triangles(); string mbr_name; // Add a reference to the variable type to the interface struct. @@ -2926,7 +3361,7 @@ void CompilerMSL::add_tess_level_input_to_interface_block(const std::string &ib_ } else { - mbr_name = var_name; + mbr_name = builtin_to_glsl(builtin, StorageClassFunction); uint32_t type_id = build_extended_vector_type(var_type.self, builtin == BuiltInTessLevelOuter ? 4 : 2); @@ -2946,27 +3381,49 @@ void CompilerMSL::add_tess_level_input_to_interface_block(const std::string &ib_ mark_locations(new_var_type); } + add_tess_level_input(ib_var_ref, mbr_name, var); +} + +void CompilerMSL::add_tess_level_input(const std::string &base_ref, const std::string &mbr_name, SPIRVariable &var) +{ + auto &entry_func = get(ir.default_entry_point); + BuiltIn builtin = BuiltIn(get_decoration(var.self, DecorationBuiltIn)); + + // Force the variable to have the proper name. + string var_name = builtin_to_glsl(builtin, StorageClassFunction); + set_name(var.self, var_name); + + // We need to declare the variable early and at entry-point scope. + entry_func.add_local_variable(var.self); + vars_needing_early_declaration.push_back(var.self); + bool triangles = is_tessellating_triangles(); + if (builtin == BuiltInTessLevelOuter) { - entry_func.fixup_hooks_in.push_back([=]() { - statement(var_name, "[0] = ", ib_var_ref, ".", mbr_name, ".x;"); - statement(var_name, "[1] = ", ib_var_ref, ".", mbr_name, ".y;"); - statement(var_name, "[2] = ", ib_var_ref, ".", mbr_name, ".z;"); - if (!triangles) - statement(var_name, "[3] = ", ib_var_ref, ".", mbr_name, ".w;"); - }); + entry_func.fixup_hooks_in.push_back( + [=]() + { + statement(var_name, "[0] = ", base_ref, ".", mbr_name, "[0];"); + statement(var_name, "[1] = ", base_ref, ".", mbr_name, "[1];"); + statement(var_name, "[2] = ", base_ref, ".", mbr_name, "[2];"); + if (!triangles) + statement(var_name, "[3] = ", base_ref, ".", mbr_name, "[3];"); + }); } else { entry_func.fixup_hooks_in.push_back([=]() { if (triangles) { - statement(var_name, "[0] = ", ib_var_ref, ".", mbr_name, ".w;"); + if (msl_options.raw_buffer_tese_input) + statement(var_name, "[0] = ", base_ref, ".", mbr_name, ";"); + else + statement(var_name, "[0] = ", base_ref, ".", mbr_name, "[3];"); } else { - statement(var_name, "[0] = ", ib_var_ref, ".", mbr_name, ".x;"); - statement(var_name, "[1] = ", ib_var_ref, ".", mbr_name, ".y;"); + statement(var_name, "[0] = ", base_ref, ".", mbr_name, "[0];"); + statement(var_name, "[1] = ", base_ref, ".", mbr_name, "[1];"); } }); } @@ -2977,7 +3434,8 @@ bool CompilerMSL::variable_storage_requires_stage_io(spv::StorageClass storage) if (storage == StorageClassOutput) return !capture_output_to_buffer; else if (storage == StorageClassInput) - return !(get_execution_model() == ExecutionModelTessellationControl && msl_options.multi_patch_workgroup); + return !(is_tesc_shader() && msl_options.multi_patch_workgroup) && + !(is_tese_shader() && msl_options.raw_buffer_tese_input); else return false; } @@ -3006,9 +3464,6 @@ void CompilerMSL::emit_local_masked_variable(const SPIRVariable &masked_var, boo auto &type = get_variable_data_type(masked_var); add_local_variable_name(masked_var.self); - bool old_is_builtin = is_using_builtin_array; - is_using_builtin_array = true; - const uint32_t max_control_points_per_patch = 32u; uint32_t max_num_instances = (max_control_points_per_patch + get_entry_point().output_vertices - 1u) / @@ -3024,14 +3479,12 @@ void CompilerMSL::emit_local_masked_variable(const SPIRVariable &masked_var, boo // since Metal does not allow that. :( // FIXME: We will likely need an option to support passing down target workgroup size, // so we can emit appropriate size here. - statement("threadgroup ", type_to_glsl(type), " ", - "(&", to_name(masked_var.self), ")", - type_to_array_glsl(type), " = spvStorage", to_name(masked_var.self), "[", + statement("threadgroup auto ", + "&", to_name(masked_var.self), + " = spvStorage", to_name(masked_var.self), "[", "(", to_expression(builtin_invocation_id_id), ".x / ", get_entry_point().output_vertices, ") % ", max_num_instances, "];"); - - is_using_builtin_array = old_is_builtin; }); } else @@ -3089,9 +3542,21 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st return; } + if (storage == StorageClassInput && has_decoration(var.self, DecorationPerVertexKHR)) + SPIRV_CROSS_THROW("PerVertexKHR decoration is not supported in MSL."); + + // If variable names alias, they will end up with wrong names in the interface struct, because + // there might be aliases in the member name cache and there would be a mismatch in fixup_in code. + // Make sure to register the variables as unique resource names ahead of time. + // This would normally conflict with the name cache when emitting local variables, + // but this happens in the setup stage, before we hit compilation loops. + // The name cache is cleared before we actually emit code, so this is safe. + add_resource_name(var.self); + if (var_type.basetype == SPIRType::Struct) { - bool block_requires_flattening = variable_storage_requires_stage_io(storage) || is_block; + bool block_requires_flattening = + variable_storage_requires_stage_io(storage) || (is_block && var_type.array.empty()); bool needs_local_declaration = !is_builtin && block_requires_flattening && meta.allow_local_declaration; if (needs_local_declaration) @@ -3117,74 +3582,110 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st else { bool masked_block = false; + uint32_t location = UINT32_MAX; + uint32_t var_mbr_idx = 0; + uint32_t elem_cnt = 1; + if (is_matrix(var_type)) + { + if (is_array(var_type)) + SPIRV_CROSS_THROW("MSL cannot emit arrays-of-matrices in input and output variables."); - // Flatten the struct members into the interface struct - for (uint32_t mbr_idx = 0; mbr_idx < uint32_t(var_type.member_types.size()); mbr_idx++) + elem_cnt = var_type.columns; + } + else if (is_array(var_type)) { - builtin = BuiltInMax; - is_builtin = is_member_builtin(var_type, mbr_idx, &builtin); - auto &mbr_type = get(var_type.member_types[mbr_idx]); + if (var_type.array.size() != 1) + SPIRV_CROSS_THROW("MSL cannot emit arrays-of-arrays in input and output variables."); - if (storage == StorageClassOutput && is_stage_output_block_member_masked(var, mbr_idx, meta.strip_array)) + elem_cnt = to_array_size_literal(var_type); + } + + for (uint32_t elem_idx = 0; elem_idx < elem_cnt; elem_idx++) + { + // Flatten the struct members into the interface struct + for (uint32_t mbr_idx = 0; mbr_idx < uint32_t(var_type.member_types.size()); mbr_idx++) { - if (is_block) - masked_block = true; + builtin = BuiltInMax; + is_builtin = is_member_builtin(var_type, mbr_idx, &builtin); + auto &mbr_type = get(var_type.member_types[mbr_idx]); - // Non-builtin block output variables are just ignored, since they will still access - // the block variable as-is. They're just not flattened. - if (is_builtin && !meta.strip_array) + if (storage == StorageClassOutput && is_stage_output_block_member_masked(var, mbr_idx, meta.strip_array)) { - // Emit a fake variable instead. - uint32_t ids = ir.increase_bound_by(2); - uint32_t ptr_type_id = ids + 0; - uint32_t var_id = ids + 1; - - auto ptr_type = mbr_type; - ptr_type.pointer = true; - ptr_type.pointer_depth++; - ptr_type.parent_type = var_type.member_types[mbr_idx]; - ptr_type.storage = StorageClassOutput; - - uint32_t initializer = 0; - if (var.initializer) - if (auto *c = maybe_get(var.initializer)) - initializer = c->subconstants[mbr_idx]; - - set(ptr_type_id, ptr_type); - set(var_id, ptr_type_id, StorageClassOutput, initializer); - entry_func.add_local_variable(var_id); - vars_needing_early_declaration.push_back(var_id); - set_name(var_id, builtin_to_glsl(builtin, StorageClassOutput)); - set_decoration(var_id, DecorationBuiltIn, builtin); - } - } - else if (!is_builtin || has_active_builtin(builtin, storage)) - { - bool is_composite_type = is_matrix(mbr_type) || is_array(mbr_type); - bool attribute_load_store = - storage == StorageClassInput && get_execution_model() != ExecutionModelFragment; - bool storage_is_stage_io = variable_storage_requires_stage_io(storage); + location = UINT32_MAX; // Skip this member and resolve location again on next var member - // Clip/CullDistance always need to be declared as user attributes. - if (builtin == BuiltInClipDistance || builtin == BuiltInCullDistance) - is_builtin = false; + if (is_block) + masked_block = true; - if ((!is_builtin || attribute_load_store) && storage_is_stage_io && is_composite_type) - { - add_composite_member_variable_to_interface_block(storage, ib_var_ref, ib_type, var, mbr_idx, - meta); + // Non-builtin block output variables are just ignored, since they will still access + // the block variable as-is. They're just not flattened. + if (is_builtin && !meta.strip_array) + { + // Emit a fake variable instead. + uint32_t ids = ir.increase_bound_by(2); + uint32_t ptr_type_id = ids + 0; + uint32_t var_id = ids + 1; + + auto ptr_type = mbr_type; + ptr_type.pointer = true; + ptr_type.pointer_depth++; + ptr_type.parent_type = var_type.member_types[mbr_idx]; + ptr_type.storage = StorageClassOutput; + + uint32_t initializer = 0; + if (var.initializer) + if (auto *c = maybe_get(var.initializer)) + initializer = c->subconstants[mbr_idx]; + + set(ptr_type_id, ptr_type); + set(var_id, ptr_type_id, StorageClassOutput, initializer); + entry_func.add_local_variable(var_id); + vars_needing_early_declaration.push_back(var_id); + set_name(var_id, builtin_to_glsl(builtin, StorageClassOutput)); + set_decoration(var_id, DecorationBuiltIn, builtin); + } } - else + else if (!is_builtin || has_active_builtin(builtin, storage)) { - add_plain_member_variable_to_interface_block(storage, ib_var_ref, ib_type, var, mbr_idx, meta); + bool is_composite_type = is_matrix(mbr_type) || is_array(mbr_type) || mbr_type.basetype == SPIRType::Struct; + bool attribute_load_store = + storage == StorageClassInput && get_execution_model() != ExecutionModelFragment; + bool storage_is_stage_io = variable_storage_requires_stage_io(storage); + + // Clip/CullDistance always need to be declared as user attributes. + if (builtin == BuiltInClipDistance || builtin == BuiltInCullDistance) + is_builtin = false; + + const string var_name = to_name(var.self); + string mbr_name_qual = var_name; + string var_chain_qual = var_name; + if (elem_cnt > 1) + { + mbr_name_qual += join("_", elem_idx); + var_chain_qual += join("[", elem_idx, "]"); + } + + if ((!is_builtin || attribute_load_store) && storage_is_stage_io && is_composite_type) + { + add_composite_member_variable_to_interface_block(storage, ib_var_ref, ib_type, + var, var_type, mbr_idx, meta, + mbr_name_qual, var_chain_qual, + location, var_mbr_idx); + } + else + { + add_plain_member_variable_to_interface_block(storage, ib_var_ref, ib_type, + var, var_type, mbr_idx, meta, + mbr_name_qual, var_chain_qual, + location, var_mbr_idx); + } } + var_mbr_idx++; } } // If we're redirecting a block, we might still need to access the original block // variable if we're masking some members. - if (masked_block && !needs_local_declaration && - (!is_builtin_variable(var) || get_execution_model() == ExecutionModelTessellationControl)) + if (masked_block && !needs_local_declaration && (!is_builtin_variable(var) || is_tesc_shader())) { if (is_builtin_variable(var)) { @@ -3205,8 +3706,8 @@ void CompilerMSL::add_variable_to_interface_block(StorageClass storage, const st } } } - else if (get_execution_model() == ExecutionModelTessellationEvaluation && storage == StorageClassInput && - !meta.strip_array && is_builtin && (builtin == BuiltInTessLevelOuter || builtin == BuiltInTessLevelInner)) + else if (is_tese_shader() && storage == StorageClassInput && !meta.strip_array && is_builtin && + (builtin == BuiltInTessLevelOuter || builtin == BuiltInTessLevelInner)) { add_tess_level_input_to_interface_block(ib_var_ref, ib_type, var); } @@ -3243,8 +3744,7 @@ void CompilerMSL::fix_up_interface_member_indices(StorageClass storage, uint32_t // Only needed for tessellation shaders and pull-model interpolants. // Need to redirect interface indices back to variables themselves. // For structs, each member of the struct need a separate instance. - if (get_execution_model() != ExecutionModelTessellationControl && - !(get_execution_model() == ExecutionModelTessellationEvaluation && storage == StorageClassInput) && + if (!is_tesc_shader() && !(is_tese_shader() && storage == StorageClassInput) && !(get_execution_model() == ExecutionModelFragment && storage == StorageClassInput && !pull_model_inputs.empty())) return; @@ -3327,15 +3827,14 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch) bool builtin_is_stage_in_out = builtin_is_gl_in_out || bi_type == BuiltInLayer || bi_type == BuiltInViewportIndex || - bi_type == BuiltInBaryCoordNV || bi_type == BuiltInBaryCoordNoPerspNV || + bi_type == BuiltInBaryCoordKHR || bi_type == BuiltInBaryCoordNoPerspKHR || bi_type == BuiltInFragDepth || bi_type == BuiltInFragStencilRefEXT || bi_type == BuiltInSampleMask; // These builtins are part of the stage in/out structs. bool is_interface_block_builtin = - builtin_is_stage_in_out || - (get_execution_model() == ExecutionModelTessellationEvaluation && - (bi_type == BuiltInTessLevelOuter || bi_type == BuiltInTessLevelInner)); + builtin_is_stage_in_out || (is_tese_shader() && !msl_options.raw_buffer_tese_input && + (bi_type == BuiltInTessLevelOuter || bi_type == BuiltInTessLevelInner)); bool is_active = interface_variable_exists_in_entry_point(var.self); if (is_builtin && is_active) @@ -3384,7 +3883,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch) } // Barycentric inputs must be emitted in stage-in, because they can have interpolation arguments. - if (is_active && (bi_type == BuiltInBaryCoordNV || bi_type == BuiltInBaryCoordNoPerspNV)) + if (is_active && (bi_type == BuiltInBaryCoordKHR || bi_type == BuiltInBaryCoordNoPerspKHR)) { if (has_seen_barycentric) SPIRV_CROSS_THROW("Cannot declare both BaryCoordNV and BaryCoordNoPerspNV in same shader in MSL."); @@ -3418,7 +3917,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch) for (uint32_t location_offset = 0; location_offset < array_size; location_offset++) { auto &location_meta = meta.location_meta[location + location_offset]; - location_meta.num_components = std::max(location_meta.num_components, component + type.vecsize); + location_meta.num_components = max(location_meta.num_components, component + type.vecsize); // For variables sharing location, decorations and base type must match. location_meta.base_type_id = type.self; @@ -3431,12 +3930,29 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch) } } } + + if (is_tese_shader() && msl_options.raw_buffer_tese_input && patch && storage == StorageClassInput && + (bi_type == BuiltInTessLevelOuter || bi_type == BuiltInTessLevelInner)) + { + // In this case, we won't add the builtin to the interface struct, + // but we still need the hook to run to populate the arrays. + string base_ref = join(tess_factor_buffer_var_name, "[", to_expression(builtin_primitive_id_id), "]"); + const char *mbr_name = + bi_type == BuiltInTessLevelOuter ? "edgeTessellationFactor" : "insideTessellationFactor"; + add_tess_level_input(base_ref, mbr_name, var); + if (inputs_by_builtin.count(bi_type)) + { + uint32_t locn = inputs_by_builtin[bi_type].location; + mark_location_as_used_by_shader(locn, type, StorageClassInput); + } + } }); // If no variables qualify, leave. // For patch input in a tessellation evaluation shader, the per-vertex stage inputs // are included in a special patch control point array. - if (vars.empty() && !(storage == StorageClassInput && patch && stage_in_var_id)) + if (vars.empty() && + !(!msl_options.raw_buffer_tese_input && storage == StorageClassInput && patch && stage_in_var_id)) return 0; // Add a new typed variable for this interface structure. @@ -3444,7 +3960,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch) // declaraion is emitted, because it is cleared after each compilation pass. uint32_t next_id = ir.increase_bound_by(3); uint32_t ib_type_id = next_id++; - auto &ib_type = set(ib_type_id); + auto &ib_type = set(ib_type_id, OpTypeStruct); ib_type.basetype = SPIRType::Struct; ib_type.storage = storage; set_decoration(ib_type_id, DecorationBlock); @@ -3459,8 +3975,9 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch) { case StorageClassInput: ib_var_ref = patch ? patch_stage_in_var_name : stage_in_var_name; - if (get_execution_model() == ExecutionModelTessellationControl) + switch (get_execution_model()) { + case ExecutionModelTessellationControl: // Add a hook to populate the shared workgroup memory containing the gl_in array. entry_func.fixup_hooks_in.push_back([=]() { // Can't use PatchVertices, PrimitiveId, or InvocationId yet; the hooks for those may not have run yet. @@ -3486,6 +4003,33 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch) statement(" return;"); } }); + break; + case ExecutionModelTessellationEvaluation: + if (!msl_options.raw_buffer_tese_input) + break; + if (patch) + { + entry_func.fixup_hooks_in.push_back( + [=]() + { + statement("const device ", to_name(ir.default_entry_point), "_", ib_var_ref, "& ", ib_var_ref, + " = ", patch_input_buffer_var_name, "[", to_expression(builtin_primitive_id_id), + "];"); + }); + } + else + { + entry_func.fixup_hooks_in.push_back( + [=]() + { + statement("const device ", to_name(ir.default_entry_point), "_", ib_var_ref, "* gl_in = &", + input_buffer_var_name, "[", to_expression(builtin_primitive_id_id), " * ", + get_entry_point().output_vertices, "];"); + }); + } + break; + default: + break; } break; @@ -3611,69 +4155,153 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch) for (auto *p_var : vars) { - bool strip_array = - (get_execution_model() == ExecutionModelTessellationControl || - (get_execution_model() == ExecutionModelTessellationEvaluation && storage == StorageClassInput)) && - !patch; + bool strip_array = (is_tesc_shader() || (is_tese_shader() && storage == StorageClassInput)) && !patch; + + // Fixing up flattened stores in TESC is impossible since the memory is group shared either via + // device (not masked) or threadgroup (masked) storage classes and it's race condition city. + meta.strip_array = strip_array; + meta.allow_local_declaration = !strip_array && !(is_tesc_shader() && storage == StorageClassOutput); + add_variable_to_interface_block(storage, ib_var_ref, ib_type, *p_var, meta); + } + + if (((is_tesc_shader() && msl_options.multi_patch_workgroup) || + (is_tese_shader() && msl_options.raw_buffer_tese_input)) && + storage == StorageClassInput) + { + // For tessellation inputs, add all outputs from the previous stage to ensure + // the struct containing them is the correct size and layout. + for (auto &input : inputs_by_location) + { + if (location_inputs_in_use.count(input.first.location) != 0) + continue; + + if (patch != (input.second.rate == MSL_SHADER_VARIABLE_RATE_PER_PATCH)) + continue; + + // Tessellation levels have their own struct, so there's no need to add them here. + if (input.second.builtin == BuiltInTessLevelOuter || input.second.builtin == BuiltInTessLevelInner) + continue; + + // Create a fake variable to put at the location. + uint32_t offset = ir.increase_bound_by(5); + uint32_t type_id = offset; + uint32_t vec_type_id = offset + 1; + uint32_t array_type_id = offset + 2; + uint32_t ptr_type_id = offset + 3; + uint32_t var_id = offset + 4; + + SPIRType type { OpTypeInt }; + switch (input.second.format) + { + case MSL_SHADER_VARIABLE_FORMAT_UINT16: + case MSL_SHADER_VARIABLE_FORMAT_ANY16: + type.basetype = SPIRType::UShort; + type.width = 16; + break; + case MSL_SHADER_VARIABLE_FORMAT_ANY32: + default: + type.basetype = SPIRType::UInt; + type.width = 32; + break; + } + set(type_id, type); + if (input.second.vecsize > 1) + { + type.op = OpTypeVector; + type.vecsize = input.second.vecsize; + set(vec_type_id, type); + type_id = vec_type_id; + } + + type.op = OpTypeArray; + type.array.push_back(0); + type.array_size_literal.push_back(true); + type.parent_type = type_id; + set(array_type_id, type); + type.self = type_id; + + type.op = OpTypePointer; + type.pointer = true; + type.pointer_depth++; + type.parent_type = array_type_id; + type.storage = storage; + auto &ptr_type = set(ptr_type_id, type); + ptr_type.self = array_type_id; + + auto &fake_var = set(var_id, ptr_type_id, storage); + set_decoration(var_id, DecorationLocation, input.first.location); + if (input.first.component) + set_decoration(var_id, DecorationComponent, input.first.component); - // Fixing up flattened stores in TESC is impossible since the memory is group shared either via - // device (not masked) or threadgroup (masked) storage classes and it's race condition city. - meta.strip_array = strip_array; - meta.allow_local_declaration = !strip_array && !(get_execution_model() == ExecutionModelTessellationControl && - storage == StorageClassOutput); - add_variable_to_interface_block(storage, ib_var_ref, ib_type, *p_var, meta); + meta.strip_array = true; + meta.allow_local_declaration = false; + add_variable_to_interface_block(storage, ib_var_ref, ib_type, fake_var, meta); + } } - if (get_execution_model() == ExecutionModelTessellationControl && msl_options.multi_patch_workgroup && - storage == StorageClassInput) + if (capture_output_to_buffer && storage == StorageClassOutput) { - // For tessellation control inputs, add all outputs from the vertex shader to ensure - // the struct containing them is the correct size and layout. - for (auto &input : inputs_by_location) + // For captured output, add all inputs from the next stage to ensure + // the struct containing them is the correct size and layout. This is + // necessary for certain implicit builtins that may nonetheless be read, + // even when they aren't written. + for (auto &output : outputs_by_location) { - if (location_inputs_in_use.count(input.first.location) != 0) + if (location_outputs_in_use.count(output.first.location) != 0) continue; // Create a fake variable to put at the location. - uint32_t offset = ir.increase_bound_by(4); + uint32_t offset = ir.increase_bound_by(5); uint32_t type_id = offset; - uint32_t array_type_id = offset + 1; - uint32_t ptr_type_id = offset + 2; - uint32_t var_id = offset + 3; + uint32_t vec_type_id = offset + 1; + uint32_t array_type_id = offset + 2; + uint32_t ptr_type_id = offset + 3; + uint32_t var_id = offset + 4; - SPIRType type; - switch (input.second.format) + SPIRType type { OpTypeInt }; + switch (output.second.format) { - case MSL_SHADER_INPUT_FORMAT_UINT16: - case MSL_SHADER_INPUT_FORMAT_ANY16: + case MSL_SHADER_VARIABLE_FORMAT_UINT16: + case MSL_SHADER_VARIABLE_FORMAT_ANY16: type.basetype = SPIRType::UShort; type.width = 16; break; - case MSL_SHADER_INPUT_FORMAT_ANY32: + case MSL_SHADER_VARIABLE_FORMAT_ANY32: default: type.basetype = SPIRType::UInt; type.width = 32; break; } - type.vecsize = input.second.vecsize; set(type_id, type); + if (output.second.vecsize > 1) + { + type.op = OpTypeVector; + type.vecsize = output.second.vecsize; + set(vec_type_id, type); + type_id = vec_type_id; + } - type.array.push_back(0); - type.array_size_literal.push_back(true); - type.parent_type = type_id; - set(array_type_id, type); + if (is_tesc_shader()) + { + type.op = OpTypeArray; + type.array.push_back(0); + type.array_size_literal.push_back(true); + type.parent_type = type_id; + set(array_type_id, type); + } + type.op = OpTypePointer; type.pointer = true; type.pointer_depth++; - type.parent_type = array_type_id; + type.parent_type = is_tesc_shader() ? array_type_id : type_id; type.storage = storage; auto &ptr_type = set(ptr_type_id, type); - ptr_type.self = array_type_id; + ptr_type.self = type.parent_type; auto &fake_var = set(var_id, ptr_type_id, storage); - set_decoration(var_id, DecorationLocation, input.first.location); - if (input.first.component) - set_decoration(var_id, DecorationComponent, input.first.component); + set_decoration(var_id, DecorationLocation, output.first.location); + if (output.first.component) + set_decoration(var_id, DecorationComponent, output.first.component); meta.strip_array = true; meta.allow_local_declaration = false; @@ -3715,7 +4343,7 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch) fix_up_interface_member_indices(storage, ib_type_id); // For patch inputs, add one more member, holding the array of control point data. - if (get_execution_model() == ExecutionModelTessellationEvaluation && storage == StorageClassInput && patch && + if (is_tese_shader() && !msl_options.raw_buffer_tese_input && storage == StorageClassInput && patch && stage_in_var_id) { uint32_t pcp_type_id = ir.increase_bound_by(1); @@ -3729,6 +4357,9 @@ uint32_t CompilerMSL::add_interface_block(StorageClass storage, bool patch) set_member_name(ib_type.self, mbr_idx, "gl_in"); } + if (storage == StorageClassInput) + set_decoration(ib_var_id, DecorationNonWritable); + return ib_var_id; } @@ -3740,19 +4371,22 @@ uint32_t CompilerMSL::add_interface_block_pointer(uint32_t ib_var_id, StorageCla uint32_t ib_ptr_var_id; uint32_t next_id = ir.increase_bound_by(3); auto &ib_type = expression_type(ib_var_id); - if (get_execution_model() == ExecutionModelTessellationControl) + if (is_tesc_shader() || (is_tese_shader() && msl_options.raw_buffer_tese_input)) { // Tessellation control per-vertex I/O is presented as an array, so we must // do the same with our struct here. uint32_t ib_ptr_type_id = next_id++; auto &ib_ptr_type = set(ib_ptr_type_id, ib_type); + ib_ptr_type.op = OpTypePointer; ib_ptr_type.parent_type = ib_ptr_type.type_alias = ib_type.self; ib_ptr_type.pointer = true; ib_ptr_type.pointer_depth++; - ib_ptr_type.storage = - storage == StorageClassInput ? - (msl_options.multi_patch_workgroup ? StorageClassStorageBuffer : StorageClassWorkgroup) : - StorageClassStorageBuffer; + ib_ptr_type.storage = storage == StorageClassInput ? + ((is_tesc_shader() && msl_options.multi_patch_workgroup) || + (is_tese_shader() && msl_options.raw_buffer_tese_input) ? + StorageClassStorageBuffer : + StorageClassWorkgroup) : + StorageClassStorageBuffer; ir.meta[ib_ptr_type_id] = ir.meta[ib_type.self]; // To ensure that get_variable_data_type() doesn't strip off the pointer, // which we need, use another pointer. @@ -3766,6 +4400,8 @@ uint32_t CompilerMSL::add_interface_block_pointer(uint32_t ib_var_id, StorageCla ib_ptr_var_id = next_id; set(ib_ptr_var_id, ib_ptr_ptr_type_id, StorageClassFunction, 0); set_name(ib_ptr_var_id, storage == StorageClassInput ? "gl_in" : "gl_out"); + if (storage == StorageClassInput) + set_decoration(ib_ptr_var_id, DecorationNonWritable); } else { @@ -3796,23 +4432,24 @@ uint32_t CompilerMSL::add_interface_block_pointer(uint32_t ib_var_id, StorageCla uint32_t CompilerMSL::ensure_correct_builtin_type(uint32_t type_id, BuiltIn builtin) { auto &type = get(type_id); + auto &pointee_type = get_pointee_type(type); - if ((builtin == BuiltInSampleMask && is_array(type)) || + if ((builtin == BuiltInSampleMask && is_array(pointee_type)) || ((builtin == BuiltInLayer || builtin == BuiltInViewportIndex || builtin == BuiltInFragStencilRefEXT) && - type.basetype != SPIRType::UInt)) + pointee_type.basetype != SPIRType::UInt)) { - uint32_t next_id = ir.increase_bound_by(type.pointer ? 2 : 1); + uint32_t next_id = ir.increase_bound_by(type_is_pointer(type) ? 2 : 1); uint32_t base_type_id = next_id++; - auto &base_type = set(base_type_id); + auto &base_type = set(base_type_id, OpTypeInt); base_type.basetype = SPIRType::UInt; base_type.width = 32; - if (!type.pointer) + if (!type_is_pointer(type)) return base_type_id; uint32_t ptr_type_id = next_id++; - auto &ptr_type = set(ptr_type_id); - ptr_type = base_type; + auto &ptr_type = set(ptr_type_id, base_type); + ptr_type.op = spv::OpTypePointer; ptr_type.pointer = true; ptr_type.pointer_depth++; ptr_type.storage = type.storage; @@ -3850,7 +4487,7 @@ uint32_t CompilerMSL::ensure_correct_input_type(uint32_t type_id, uint32_t locat switch (p_va->second.format) { - case MSL_SHADER_INPUT_FORMAT_UINT8: + case MSL_SHADER_VARIABLE_FORMAT_UINT8: { switch (type.basetype) { @@ -3874,7 +4511,7 @@ uint32_t CompilerMSL::ensure_correct_input_type(uint32_t type_id, uint32_t locat } } - case MSL_SHADER_INPUT_FORMAT_UINT16: + case MSL_SHADER_VARIABLE_FORMAT_UINT16: { switch (type.basetype) { @@ -3905,6 +4542,10 @@ uint32_t CompilerMSL::ensure_correct_input_type(uint32_t type_id, uint32_t locat void CompilerMSL::mark_struct_members_packed(const SPIRType &type) { + // Handle possible recursion when a struct contains a pointer to its own type nested somewhere. + if (has_extended_decoration(type.self, SPIRVCrossDecorationPhysicalTypePacked)) + return; + set_extended_decoration(type.self, SPIRVCrossDecorationPhysicalTypePacked); // Problem case! Struct needs to be placed at an awkward alignment. @@ -3931,8 +4572,9 @@ void CompilerMSL::mark_scalar_layout_structs(const SPIRType &type) uint32_t mbr_cnt = uint32_t(type.member_types.size()); for (uint32_t i = 0; i < mbr_cnt; i++) { + // Handle possible recursion when a struct contains a pointer to its own type nested somewhere. auto &mbr_type = get(type.member_types[i]); - if (mbr_type.basetype == SPIRType::Struct) + if (mbr_type.basetype == SPIRType::Struct && !(mbr_type.pointer && mbr_type.storage == StorageClassPhysicalStorageBuffer)) { auto *struct_type = &mbr_type; while (!struct_type->array.empty()) @@ -3965,7 +4607,7 @@ void CompilerMSL::mark_scalar_layout_structs(const SPIRType &type) for (uint32_t dim = 0; dim < dimensions; dim++) { uint32_t array_size = to_array_size_literal(mbr_type, dim); - array_stride /= max(array_size, 1u); + array_stride /= max(array_size, 1u); } // Set expected struct size based on ArrayStride. @@ -4144,8 +4786,10 @@ void CompilerMSL::ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t in // This case will be nightmare-ish to deal with. This could possibly happen if struct alignment does not quite // match up with what we want. Scalar block layout comes to mind here where we might have to work around the rule // that struct alignment == max alignment of all members and struct size depends on this alignment. + // Can't repack structs, but can repack pointers to structs. auto &mbr_type = get(ib_type.member_types[index]); - if (mbr_type.basetype == SPIRType::Struct) + bool is_buff_ptr = mbr_type.pointer && mbr_type.storage == StorageClassPhysicalStorageBuffer; + if (mbr_type.basetype == SPIRType::Struct && !is_buff_ptr) SPIRV_CROSS_THROW("Cannot perform any repacking for structs when it is used as a member of another struct."); // Perform remapping here. @@ -4170,18 +4814,39 @@ void CompilerMSL::ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t in // Hack off array-of-arrays until we find the array stride per element we must have to make it work. uint32_t dimensions = uint32_t(mbr_type.array.size() - 1); for (uint32_t dim = 0; dim < dimensions; dim++) - array_stride /= max(to_array_size_literal(mbr_type, dim), 1u); + array_stride /= max(to_array_size_literal(mbr_type, dim), 1u); - uint32_t elems_per_stride = array_stride / (mbr_type.width / 8); + // Pointers are 8 bytes + uint32_t mbr_width_in_bytes = is_buff_ptr ? 8 : (mbr_type.width / 8); + uint32_t elems_per_stride = array_stride / mbr_width_in_bytes; if (elems_per_stride == 3) SPIRV_CROSS_THROW("Cannot use ArrayStride of 3 elements in remapping scenarios."); - else if (elems_per_stride > 4) + else if (elems_per_stride > 4 && elems_per_stride != 8) SPIRV_CROSS_THROW("Cannot represent vectors with more than 4 elements in MSL."); + if (elems_per_stride == 8) + { + if (mbr_type.width == 16) + add_spv_func_and_recompile(SPVFuncImplPaddedStd140); + else + SPIRV_CROSS_THROW("Unexpected type in std140 wide array resolve."); + } + auto physical_type = mbr_type; physical_type.vecsize = elems_per_stride; physical_type.parent_type = 0; + + // If this is a physical buffer pointer, replace type with a ulongn vector. + if (is_buff_ptr) + { + physical_type.width = 64; + physical_type.basetype = to_unsigned_basetype(physical_type.width); + physical_type.pointer = false; + physical_type.pointer_depth = false; + physical_type.forward_pointer = false; + } + uint32_t type_id = ir.increase_bound_by(1); set(type_id, physical_type); set_extended_member_decoration(ib_type.self, index, SPIRVCrossDecorationPhysicalTypeID, type_id); @@ -4199,13 +4864,20 @@ void CompilerMSL::ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t in if (elems_per_stride == 3) SPIRV_CROSS_THROW("Cannot use ArrayStride of 3 elements in remapping scenarios."); - else if (elems_per_stride > 4) + else if (elems_per_stride > 4 && elems_per_stride != 8) SPIRV_CROSS_THROW("Cannot represent vectors with more than 4 elements in MSL."); - bool row_major = has_member_decoration(ib_type.self, index, DecorationRowMajor); + if (elems_per_stride == 8) + { + if (mbr_type.basetype != SPIRType::Half) + SPIRV_CROSS_THROW("Unexpected type in std140 wide matrix stride resolve."); + add_spv_func_and_recompile(SPVFuncImplPaddedStd140); + } + bool row_major = has_member_decoration(ib_type.self, index, DecorationRowMajor); auto physical_type = mbr_type; physical_type.parent_type = 0; + if (row_major) physical_type.columns = elems_per_stride; else @@ -4267,6 +4939,7 @@ void CompilerMSL::ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t in { type.columns = 1; assert(type.array.empty()); + type.op = OpTypeArray; type.array.push_back(1); type.array_size_literal.push_back(true); } @@ -4283,6 +4956,7 @@ void CompilerMSL::ensure_member_packing_rules_msl(SPIRType &ib_type, uint32_t in type.vecsize = type.columns; type.columns = 1; assert(type.array.empty()); + type.op = OpTypeArray; type.array.push_back(1); type.array_size_literal.push_back(true); } @@ -4305,9 +4979,18 @@ void CompilerMSL::emit_store_statement(uint32_t lhs_expression, uint32_t rhs_exp bool transpose = lhs_e && lhs_e->need_transpose; - // No physical type remapping, and no packed type, so can just emit a store directly. - if (!lhs_remapped_type && !lhs_packed_type) + if (has_decoration(lhs_expression, DecorationBuiltIn) && + BuiltIn(get_decoration(lhs_expression, DecorationBuiltIn)) == BuiltInSampleMask && + is_array(type)) + { + // Storing an array to SampleMask, have to remove the array-ness before storing. + statement(to_expression(lhs_expression), " = ", to_enclosed_unpacked_expression(rhs_expression), "[0];"); + register_write(lhs_expression); + } + else if (!lhs_remapped_type && !lhs_packed_type) { + // No physical type remapping, and no packed type, so can just emit a store directly. + // We might not be dealing with remapped physical types or packed types, // but we might be doing a clean store to a row-major matrix. // In this case, we just flip transpose states, and emit the store, a transpose must be in the RHS expression, if any. @@ -4368,6 +5051,11 @@ void CompilerMSL::emit_store_statement(uint32_t lhs_expression, uint32_t rhs_exp auto &physical_type = get(physical_type_id); + string cast_addr_space = "thread"; + auto *p_var_lhs = maybe_get_backing_variable(lhs_expression); + if (p_var_lhs) + cast_addr_space = get_type_address_space(get(p_var_lhs->basetype), lhs_expression); + if (is_matrix(type)) { const char *packed_pfx = lhs_packed_type ? "packed_" : ""; @@ -4395,7 +5083,7 @@ void CompilerMSL::emit_store_statement(uint32_t lhs_expression, uint32_t rhs_exp write_type.columns = 1; if (physical_type.columns != type.columns) - cast_expr = join("(device ", packed_pfx, type_to_glsl(write_type), "&)"); + cast_expr = join("(", cast_addr_space, " ", packed_pfx, type_to_glsl(write_type), "&)"); if (rhs_transpose) { @@ -4437,7 +5125,7 @@ void CompilerMSL::emit_store_statement(uint32_t lhs_expression, uint32_t rhs_exp write_type.columns = 1; if (physical_type.vecsize != type.vecsize) - cast_expr = join("(device ", packed_pfx, type_to_glsl(write_type), "&)"); + cast_expr = join("(", cast_addr_space, " ", packed_pfx, type_to_glsl(write_type), "&)"); if (rhs_transpose) { @@ -4490,9 +5178,16 @@ void CompilerMSL::emit_store_statement(uint32_t lhs_expression, uint32_t rhs_exp { auto lhs_expr = to_enclosed_expression(lhs_expression); auto column_index = lhs_expr.find_last_of('['); + + // Get rid of any ".data" half8 handling here, we're casting to scalar anyway. + auto end_column_index = lhs_expr.find_last_of(']'); + auto end_dot_index = lhs_expr.find_last_of('.'); + if (end_dot_index != string::npos && end_dot_index > end_column_index) + lhs_expr.resize(end_dot_index); + if (column_index != string::npos) { - statement("((device ", type_to_glsl(write_type), "*)&", + statement("((", cast_addr_space, " ", type_to_glsl(write_type), "*)&", lhs_expr.insert(column_index, join('[', c, ']', ")")), " = ", to_extract_component_expression(rhs_expression, c), ";"); } @@ -4500,7 +5195,9 @@ void CompilerMSL::emit_store_statement(uint32_t lhs_expression, uint32_t rhs_exp lhs_e->need_transpose = true; } - else if ((is_matrix(physical_type) || is_array(physical_type)) && physical_type.vecsize > type.vecsize) + else if ((is_matrix(physical_type) || is_array(physical_type)) && + physical_type.vecsize <= 4 && + physical_type.vecsize > type.vecsize) { assert(type.vecsize >= 1 && type.vecsize <= 3); @@ -4515,7 +5212,7 @@ void CompilerMSL::emit_store_statement(uint32_t lhs_expression, uint32_t rhs_exp // Unpack the expression so we can store to it with a float or float2. // It's still an l-value, so it's fine. Most other unpacking of expressions turn them into r-values instead. - lhs = join("(device ", type_to_glsl(type), "&)", enclose_expression(lhs)); + lhs = join("(", cast_addr_space, " ", type_to_glsl(type), "&)", enclose_expression(lhs)); if (!optimize_read_modify_write(expression_type(rhs_expression), lhs, rhs)) statement(lhs, " = ", rhs, ";"); } @@ -4557,19 +5254,26 @@ string CompilerMSL::unpack_expression_type(string expr_str, const SPIRType &type ".x", ".xy", ".xyz", + "", }; + // TODO: Move everything to the template wrapper? + bool uses_std140_wrapper = physical_type && physical_type->vecsize > 4; + if (physical_type && is_vector(*physical_type) && is_array(*physical_type) && + !uses_std140_wrapper && physical_type->vecsize > type.vecsize && !expression_ends_with(expr_str, swizzle_lut[type.vecsize - 1])) { // std140 array cases for vectors. assert(type.vecsize >= 1 && type.vecsize <= 3); return enclose_expression(expr_str) + swizzle_lut[type.vecsize - 1]; } - else if (physical_type && is_matrix(*physical_type) && is_vector(type) && physical_type->vecsize > type.vecsize) + else if (physical_type && is_matrix(*physical_type) && is_vector(type) && + !uses_std140_wrapper && + physical_type->vecsize > type.vecsize) { // Extract column from padded matrix. - assert(type.vecsize >= 1 && type.vecsize <= 3); + assert(type.vecsize >= 1 && type.vecsize <= 4); return enclose_expression(expr_str) + swizzle_lut[type.vecsize - 1]; } else if (is_matrix(type)) @@ -4591,6 +5295,7 @@ string CompilerMSL::unpack_expression_type(string expr_str, const SPIRType &type string unpack_expr = join(base_type, columns, "x", vecsize, "("); const char *load_swiz = ""; + const char *data_swiz = physical_vecsize > 4 ? ".data" : ""; if (physical_vecsize != vecsize) load_swiz = swizzle_lut[vecsize - 1]; @@ -4603,7 +5308,7 @@ string CompilerMSL::unpack_expression_type(string expr_str, const SPIRType &type if (packed) unpack_expr += join(base_type, physical_vecsize, "(", expr_str, "[", i, "]", ")", load_swiz); else - unpack_expr += join(expr_str, "[", i, "]", load_swiz); + unpack_expr += join(expr_str, "[", i, "]", data_swiz, load_swiz); } unpack_expr += ")"; @@ -4666,6 +5371,10 @@ void CompilerMSL::add_typedef_line(const string &line) // Template struct like spvUnsafeArray<> need to be declared *before* any resources are declared void CompilerMSL::emit_custom_templates() { + static const char * const address_spaces[] = { + "thread", "constant", "device", "threadgroup", "threadgroup_imageblock", "ray_data", "object_data" + }; + for (const auto &spv_func : spv_function_implementations) { switch (spv_func) @@ -4711,6 +5420,122 @@ void CompilerMSL::emit_custom_templates() statement(""); break; + case SPVFuncImplStorageMatrix: + statement("template"); + statement("struct spvStorageMatrix"); + begin_scope(); + statement("vec columns[Cols];"); + statement(""); + for (size_t method_idx = 0; method_idx < sizeof(address_spaces) / sizeof(address_spaces[0]); ++method_idx) + { + // Some address spaces require particular features. + if (method_idx == 4) // threadgroup_imageblock + statement("#ifdef __HAVE_IMAGEBLOCKS__"); + else if (method_idx == 5) // ray_data + statement("#ifdef __HAVE_RAYTRACING__"); + else if (method_idx == 6) // object_data + statement("#ifdef __HAVE_MESH__"); + const string &method_as = address_spaces[method_idx]; + statement("spvStorageMatrix() ", method_as, " = default;"); + if (method_idx != 1) // constant + { + statement(method_as, " spvStorageMatrix& operator=(initializer_list> cols) ", + method_as); + begin_scope(); + statement("size_t i;"); + statement("thread vec* col;"); + statement("for (i = 0, col = cols.begin(); i < Cols; ++i, ++col)"); + statement(" columns[i] = *col;"); + statement("return *this;"); + end_scope(); + } + statement(""); + for (size_t param_idx = 0; param_idx < sizeof(address_spaces) / sizeof(address_spaces[0]); ++param_idx) + { + if (param_idx != method_idx) + { + if (param_idx == 4) // threadgroup_imageblock + statement("#ifdef __HAVE_IMAGEBLOCKS__"); + else if (param_idx == 5) // ray_data + statement("#ifdef __HAVE_RAYTRACING__"); + else if (param_idx == 6) // object_data + statement("#ifdef __HAVE_MESH__"); + } + const string ¶m_as = address_spaces[param_idx]; + statement("spvStorageMatrix(const ", param_as, " matrix& m) ", method_as); + begin_scope(); + statement("for (size_t i = 0; i < Cols; ++i)"); + statement(" columns[i] = m.columns[i];"); + end_scope(); + statement("spvStorageMatrix(const ", param_as, " spvStorageMatrix& m) ", method_as, " = default;"); + if (method_idx != 1) // constant + { + statement(method_as, " spvStorageMatrix& operator=(const ", param_as, + " matrix& m) ", method_as); + begin_scope(); + statement("for (size_t i = 0; i < Cols; ++i)"); + statement(" columns[i] = m.columns[i];"); + statement("return *this;"); + end_scope(); + statement(method_as, " spvStorageMatrix& operator=(const ", param_as, " spvStorageMatrix& m) ", + method_as, " = default;"); + } + if (param_idx != method_idx && param_idx >= 4) + statement("#endif"); + statement(""); + } + statement("operator matrix() const ", method_as); + begin_scope(); + statement("matrix m;"); + statement("for (int i = 0; i < Cols; ++i)"); + statement(" m.columns[i] = columns[i];"); + statement("return m;"); + end_scope(); + statement(""); + statement("vec operator[](size_t idx) const ", method_as); + begin_scope(); + statement("return columns[idx];"); + end_scope(); + if (method_idx != 1) // constant + { + statement(method_as, " vec& operator[](size_t idx) ", method_as); + begin_scope(); + statement("return columns[idx];"); + end_scope(); + } + if (method_idx >= 4) + statement("#endif"); + statement(""); + } + end_scope_decl(); + statement(""); + statement("template"); + statement("matrix transpose(spvStorageMatrix m)"); + begin_scope(); + statement("return transpose(matrix(m));"); + end_scope(); + statement(""); + statement("typedef spvStorageMatrix spvStorage_half2x2;"); + statement("typedef spvStorageMatrix spvStorage_half2x3;"); + statement("typedef spvStorageMatrix spvStorage_half2x4;"); + statement("typedef spvStorageMatrix spvStorage_half3x2;"); + statement("typedef spvStorageMatrix spvStorage_half3x3;"); + statement("typedef spvStorageMatrix spvStorage_half3x4;"); + statement("typedef spvStorageMatrix spvStorage_half4x2;"); + statement("typedef spvStorageMatrix spvStorage_half4x3;"); + statement("typedef spvStorageMatrix spvStorage_half4x4;"); + statement("typedef spvStorageMatrix spvStorage_float2x2;"); + statement("typedef spvStorageMatrix spvStorage_float2x3;"); + statement("typedef spvStorageMatrix spvStorage_float2x4;"); + statement("typedef spvStorageMatrix spvStorage_float3x2;"); + statement("typedef spvStorageMatrix spvStorage_float3x3;"); + statement("typedef spvStorageMatrix spvStorage_float3x4;"); + statement("typedef spvStorageMatrix spvStorage_float4x2;"); + statement("typedef spvStorageMatrix spvStorage_float4x3;"); + statement("typedef spvStorageMatrix spvStorage_float4x4;"); + statement(""); + break; + default: break; } @@ -4862,7 +5687,7 @@ void CompilerMSL::emit_custom_functions() for (uint32_t variant = 0; variant < 12; variant++) { - uint32_t dimensions = spv_func - SPVFuncImplArrayCopyMultidimBase; + uint8_t dimensions = spv_func - SPVFuncImplArrayCopyMultidimBase; string tmp = "template= max(absP.y, absP.z);"); + statement("bool yMajor = absP.y >= absP.z;"); + statement("float3 Q = xMajor ? P.yzx : (yMajor ? P.xzy : P);"); + statement("float3 dQdx = xMajor ? dPdx.yzx : (yMajor ? dPdx.xzy : dPdx);"); + statement("float3 dQdy = xMajor ? dPdy.yzx : (yMajor ? dPdy.xzy : dPdy);"); + statement_no_indent(""); + statement("// Skip a couple of operations compared to usual projection"); + statement("float4 d = float4(dQdx.xy, dQdy.xy) - (Q.xy / Q.z).xyxy * float4(dQdx.zz, dQdy.zz);"); + statement_no_indent(""); + statement("// Final swizzle to put the intermediate values into non-ignored components"); + statement("// X major: X and Z"); + statement("// Y major: X and Y"); + statement("// Z major: Y and Z"); + statement("return gradientcube(xMajor ? d.xxy : d.xyx, xMajor ? d.zzw : d.zwz);"); + end_scope(); + statement(""); + break; + // "fadd" intrinsic support case SPVFuncImplFAdd: statement("template"); @@ -5373,7 +6223,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline T spvSubgroupBroadcast(T value, ushort lane)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return quad_broadcast(value, lane);"); else statement("return simd_broadcast(value, lane);"); @@ -5382,7 +6232,7 @@ void CompilerMSL::emit_custom_functions() statement("template<>"); statement("inline bool spvSubgroupBroadcast(bool value, ushort lane)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return !!quad_broadcast((ushort)value, lane);"); else statement("return !!simd_broadcast((ushort)value, lane);"); @@ -5391,7 +6241,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline vec spvSubgroupBroadcast(vec value, ushort lane)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return (vec)quad_broadcast((vec)value, lane);"); else statement("return (vec)simd_broadcast((vec)value, lane);"); @@ -5403,7 +6253,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline T spvSubgroupBroadcastFirst(T value)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return quad_broadcast_first(value);"); else statement("return simd_broadcast_first(value);"); @@ -5412,7 +6262,7 @@ void CompilerMSL::emit_custom_functions() statement("template<>"); statement("inline bool spvSubgroupBroadcastFirst(bool value)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return !!quad_broadcast_first((ushort)value);"); else statement("return !!simd_broadcast_first((ushort)value);"); @@ -5421,7 +6271,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline vec spvSubgroupBroadcastFirst(vec value)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return (vec)quad_broadcast_first((vec)value);"); else statement("return (vec)simd_broadcast_first((vec)value);"); @@ -5432,7 +6282,7 @@ void CompilerMSL::emit_custom_functions() case SPVFuncImplSubgroupBallot: statement("inline uint4 spvSubgroupBallot(bool value)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) { statement("return uint4((quad_vote::vote_t)quad_ballot(value), 0, 0, 0);"); } @@ -5560,7 +6410,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline bool spvSubgroupAllEqual(T value)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return quad_all(all(value == quad_broadcast_first(value)));"); else statement("return simd_all(all(value == simd_broadcast_first(value)));"); @@ -5569,7 +6419,7 @@ void CompilerMSL::emit_custom_functions() statement("template<>"); statement("inline bool spvSubgroupAllEqual(bool value)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return quad_all(value) || !quad_any(value);"); else statement("return simd_all(value) || !simd_any(value);"); @@ -5578,7 +6428,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline bool spvSubgroupAllEqual(vec value)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return quad_all(all(value == (vec)quad_broadcast_first((vec)value)));"); else statement("return simd_all(all(value == (vec)simd_broadcast_first((vec)value)));"); @@ -5590,7 +6440,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline T spvSubgroupShuffle(T value, ushort lane)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return quad_shuffle(value, lane);"); else statement("return simd_shuffle(value, lane);"); @@ -5599,7 +6449,7 @@ void CompilerMSL::emit_custom_functions() statement("template<>"); statement("inline bool spvSubgroupShuffle(bool value, ushort lane)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return !!quad_shuffle((ushort)value, lane);"); else statement("return !!simd_shuffle((ushort)value, lane);"); @@ -5608,7 +6458,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline vec spvSubgroupShuffle(vec value, ushort lane)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return (vec)quad_shuffle((vec)value, lane);"); else statement("return (vec)simd_shuffle((vec)value, lane);"); @@ -5620,7 +6470,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline T spvSubgroupShuffleXor(T value, ushort mask)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return quad_shuffle_xor(value, mask);"); else statement("return simd_shuffle_xor(value, mask);"); @@ -5629,7 +6479,7 @@ void CompilerMSL::emit_custom_functions() statement("template<>"); statement("inline bool spvSubgroupShuffleXor(bool value, ushort mask)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return !!quad_shuffle_xor((ushort)value, mask);"); else statement("return !!simd_shuffle_xor((ushort)value, mask);"); @@ -5638,7 +6488,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline vec spvSubgroupShuffleXor(vec value, ushort mask)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return (vec)quad_shuffle_xor((vec)value, mask);"); else statement("return (vec)simd_shuffle_xor((vec)value, mask);"); @@ -5650,7 +6500,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline T spvSubgroupShuffleUp(T value, ushort delta)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return quad_shuffle_up(value, delta);"); else statement("return simd_shuffle_up(value, delta);"); @@ -5659,7 +6509,7 @@ void CompilerMSL::emit_custom_functions() statement("template<>"); statement("inline bool spvSubgroupShuffleUp(bool value, ushort delta)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return !!quad_shuffle_up((ushort)value, delta);"); else statement("return !!simd_shuffle_up((ushort)value, delta);"); @@ -5668,7 +6518,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline vec spvSubgroupShuffleUp(vec value, ushort delta)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return (vec)quad_shuffle_up((vec)value, delta);"); else statement("return (vec)simd_shuffle_up((vec)value, delta);"); @@ -5680,7 +6530,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline T spvSubgroupShuffleDown(T value, ushort delta)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return quad_shuffle_down(value, delta);"); else statement("return simd_shuffle_down(value, delta);"); @@ -5689,7 +6539,7 @@ void CompilerMSL::emit_custom_functions() statement("template<>"); statement("inline bool spvSubgroupShuffleDown(bool value, ushort delta)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return !!quad_shuffle_down((ushort)value, delta);"); else statement("return !!simd_shuffle_down((ushort)value, delta);"); @@ -5698,7 +6548,7 @@ void CompilerMSL::emit_custom_functions() statement("template"); statement("inline vec spvSubgroupShuffleDown(vec value, ushort delta)"); begin_scope(); - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) statement("return (vec)quad_shuffle_down((vec)value, delta);"); else statement("return (vec)simd_shuffle_down((vec)value, delta);"); @@ -6496,6 +7346,109 @@ void CompilerMSL::emit_custom_functions() end_scope(); end_scope_decl(); statement(""); + break; + + case SPVFuncImplRayQueryIntersectionParams: + statement("intersection_params spvMakeIntersectionParams(uint flags)"); + begin_scope(); + statement("intersection_params ip;"); + statement("if ((flags & ", RayFlagsOpaqueKHRMask, ") != 0)"); + statement(" ip.force_opacity(forced_opacity::opaque);"); + statement("if ((flags & ", RayFlagsNoOpaqueKHRMask, ") != 0)"); + statement(" ip.force_opacity(forced_opacity::non_opaque);"); + statement("if ((flags & ", RayFlagsTerminateOnFirstHitKHRMask, ") != 0)"); + statement(" ip.accept_any_intersection(true);"); + // RayFlagsSkipClosestHitShaderKHRMask is not available in MSL + statement("if ((flags & ", RayFlagsCullBackFacingTrianglesKHRMask, ") != 0)"); + statement(" ip.set_triangle_cull_mode(triangle_cull_mode::back);"); + statement("if ((flags & ", RayFlagsCullFrontFacingTrianglesKHRMask, ") != 0)"); + statement(" ip.set_triangle_cull_mode(triangle_cull_mode::front);"); + statement("if ((flags & ", RayFlagsCullOpaqueKHRMask, ") != 0)"); + statement(" ip.set_opacity_cull_mode(opacity_cull_mode::opaque);"); + statement("if ((flags & ", RayFlagsCullNoOpaqueKHRMask, ") != 0)"); + statement(" ip.set_opacity_cull_mode(opacity_cull_mode::non_opaque);"); + statement("if ((flags & ", RayFlagsSkipTrianglesKHRMask, ") != 0)"); + statement(" ip.set_geometry_cull_mode(geometry_cull_mode::triangle);"); + statement("if ((flags & ", RayFlagsSkipAABBsKHRMask, ") != 0)"); + statement(" ip.set_geometry_cull_mode(geometry_cull_mode::bounding_box);"); + statement("return ip;"); + end_scope(); + statement(""); + break; + + case SPVFuncImplVariableDescriptor: + statement("template"); + statement("struct spvDescriptor"); + begin_scope(); + statement("T value;"); + end_scope_decl(); + statement(""); + break; + + case SPVFuncImplVariableSizedDescriptor: + statement("template"); + statement("struct spvBufferDescriptor"); + begin_scope(); + statement("T value;"); + statement("int length;"); + statement("const device T& operator -> () const device"); + begin_scope(); + statement("return value;"); + end_scope(); + statement("const device T& operator * () const device"); + begin_scope(); + statement("return value;"); + end_scope(); + end_scope_decl(); + statement(""); + break; + + case SPVFuncImplVariableDescriptorArray: + statement("template"); + statement("struct spvDescriptorArray"); + begin_scope(); + statement("spvDescriptorArray(const device spvDescriptor* ptr) : ptr(ptr)"); + begin_scope(); + end_scope(); + statement("const device T& operator [] (size_t i) const"); + begin_scope(); + statement("return ptr[i].value;"); + end_scope(); + statement("const device spvDescriptor* ptr;"); + end_scope_decl(); + statement(""); + + if (msl_options.runtime_array_rich_descriptor && + spv_function_implementations.count(SPVFuncImplVariableSizedDescriptor) != 0) + { + statement("template"); + statement("struct spvDescriptorArray"); + begin_scope(); + statement("spvDescriptorArray(const device spvBufferDescriptor* ptr) : ptr(ptr)"); + begin_scope(); + end_scope(); + statement("const device T* operator [] (size_t i) const"); + begin_scope(); + statement("return ptr[i].value;"); + end_scope(); + statement("const int length(int i) const"); + begin_scope(); + statement("return ptr[i].length;"); + end_scope(); + statement("const device spvBufferDescriptor* ptr;"); + end_scope_decl(); + statement(""); + } + break; + + case SPVFuncImplPaddedStd140: + // .data is used in access chain. + statement("template "); + statement("struct spvPaddedStd140 { alignas(16) T data; };"); + statement("template "); + statement("using spvPaddedStd140Matrix = spvPaddedStd140[n];"); + statement(""); + break; default: break; @@ -6516,7 +7469,7 @@ static string inject_top_level_storage_qualifier(const string &expr, const strin else if (last_pointer == string::npos) last_significant = last_reference; else - last_significant = std::max(last_reference, last_pointer); + last_significant = max(last_reference, last_pointer); if (last_significant == string::npos) return join(qualifier, " ", expr); @@ -6527,28 +7480,6 @@ static string inject_top_level_storage_qualifier(const string &expr, const strin } } -// Undefined global memory is not allowed in MSL. -// Declare constant and init to zeros. Use {}, as global constructors can break Metal. -void CompilerMSL::declare_undefined_values() -{ - bool emitted = false; - ir.for_each_typed_id([&](uint32_t, SPIRUndef &undef) { - auto &type = this->get(undef.basetype); - // OpUndef can be void for some reason ... - if (type.basetype == SPIRType::Void) - return; - - statement(inject_top_level_storage_qualifier( - variable_decl(type, to_name(undef.self), undef.self), - "constant"), - " = {};"); - emitted = true; - }); - - if (emitted) - statement(""); -} - void CompilerMSL::declare_constant_arrays() { bool fully_inlined = ir.ids_for_type[TypeFunction].size() == 1; @@ -6566,8 +7497,9 @@ void CompilerMSL::declare_constant_arrays() // FIXME: However, hoisting constants to main() means we need to pass down constant arrays to leaf functions if they are used there. // If there are multiple functions in the module, drop this case to avoid breaking use cases which do not need to // link into Metal libraries. This is hacky. - if (!type.array.empty() && (!fully_inlined || is_scalar(type) || is_vector(type))) + if (is_array(type) && (!fully_inlined || is_scalar(type) || is_vector(type))) { + add_resource_name(c.self); auto name = to_name(c.self); statement(inject_top_level_storage_qualifier(variable_decl(type, name), "constant"), " = ", constant_expression(c), ";"); @@ -6597,8 +7529,9 @@ void CompilerMSL::declare_complex_constant_arrays() return; auto &type = this->get(c.constant_type); - if (!type.array.empty() && !(is_scalar(type) || is_vector(type))) + if (is_array(type) && !(is_scalar(type) || is_vector(type))) { + add_resource_name(c.self); auto name = to_name(c.self); statement("", variable_decl(type, name), " = ", constant_expression(c), ";"); emitted = true; @@ -6612,7 +7545,6 @@ void CompilerMSL::declare_complex_constant_arrays() void CompilerMSL::emit_resources() { declare_constant_arrays(); - declare_undefined_values(); // Emit the special [[stage_in]] and [[stage_out]] interface blocks which we created. emit_interface_block(stage_out_var_id); @@ -6656,7 +7588,35 @@ void CompilerMSL::emit_specialization_constants_and_structs() // these types for purpose of iterating over them in ir.ids_for_type and friends. auto loop_lock = ir.create_loop_soft_lock(); - for (auto &id_ : ir.ids_for_constant_or_type) + // Physical storage buffer pointers can have cyclical references, + // so emit forward declarations of them before other structs. + // Ignore type_id because we want the underlying struct type from the pointer. + ir.for_each_typed_id([&](uint32_t /* type_id */, const SPIRType &type) { + if (type.basetype == SPIRType::Struct && + type.pointer && type.storage == StorageClassPhysicalStorageBuffer && + declared_structs.count(type.self) == 0) + { + statement("struct ", to_name(type.self), ";"); + declared_structs.insert(type.self); + emitted = true; + } + }); + if (emitted) + statement(""); + + emitted = false; + declared_structs.clear(); + + // It is possible to have multiple spec constants that use the same spec constant ID. + // The most common cause of this is defining spec constants in GLSL while also declaring + // the workgroup size to use those spec constants. But, Metal forbids declaring more than + // one variable with the same function constant ID. + // In this case, we must only declare one variable with the [[function_constant(id)]] + // attribute, and use its initializer to initialize all the spec constants with + // that ID. + std::unordered_map unique_func_constants; + + for (auto &id_ : ir.ids_for_constant_undef_or_type) { auto &id = ir.ids[id_]; @@ -6677,8 +7637,8 @@ void CompilerMSL::emit_specialization_constants_and_structs() { auto &type = get(c.constant_type); string sc_type_name = type_to_glsl(type); + add_resource_name(c.self); string sc_name = to_name(c.self); - string sc_tmp_name = sc_name + "_tmp"; // Function constants are only supported in MSL 1.2 and later. // If we don't support it just declare the "default" directly. @@ -6688,12 +7648,18 @@ void CompilerMSL::emit_specialization_constants_and_structs() if (msl_options.supports_msl_version(1, 2) && has_decoration(c.self, DecorationSpecId) && !c.is_used_as_array_length) { - uint32_t constant_id = get_decoration(c.self, DecorationSpecId); // Only scalar, non-composite values can be function constants. - statement("constant ", sc_type_name, " ", sc_tmp_name, " [[function_constant(", constant_id, - ")]];"); + uint32_t constant_id = get_decoration(c.self, DecorationSpecId); + if (!unique_func_constants.count(constant_id)) + unique_func_constants.insert(make_pair(constant_id, c.self)); + SPIRType::BaseType sc_tmp_type = expression_type(unique_func_constants[constant_id]).basetype; + string sc_tmp_name = to_name(unique_func_constants[constant_id]) + "_tmp"; + if (unique_func_constants[constant_id] == c.self) + statement("constant ", sc_type_name, " ", sc_tmp_name, " [[function_constant(", constant_id, + ")]];"); statement("constant ", sc_type_name, " ", sc_name, " = is_function_constant_defined(", sc_tmp_name, - ") ? ", sc_tmp_name, " : ", constant_expression(c), ";"); + ") ? ", bitcast_expression(type, sc_tmp_type, sc_tmp_name), " : ", constant_expression(c), + ";"); } else if (has_decoration(c.self, DecorationSpecId)) { @@ -6719,6 +7685,7 @@ void CompilerMSL::emit_specialization_constants_and_structs() { auto &c = id.get(); auto &type = get(c.basetype); + add_resource_name(c.self); auto name = to_name(c.self); statement("constant ", variable_decl(type, name), " = ", constant_op_expression(c), ";"); emitted = true; @@ -6767,12 +7734,44 @@ void CompilerMSL::emit_specialization_constants_and_structs() emit_struct(get(type_id)); } } + else if (id.get_type() == TypeUndef) + { + auto &undef = id.get(); + auto &type = get(undef.basetype); + // OpUndef can be void for some reason ... + if (type.basetype == SPIRType::Void) + return; + + // Undefined global memory is not allowed in MSL. + // Declare constant and init to zeros. Use {}, as global constructors can break Metal. + statement( + inject_top_level_storage_qualifier(variable_decl(type, to_name(undef.self), undef.self), "constant"), + " = {};"); + emitted = true; + } } if (emitted) statement(""); } +void CompilerMSL::emit_binary_ptr_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op) +{ + bool forward = should_forward(op0) && should_forward(op1); + emit_op(result_type, result_id, join(to_ptr_expression(op0), " ", op, " ", to_ptr_expression(op1)), forward); + inherit_expression_dependencies(result_id, op0); + inherit_expression_dependencies(result_id, op1); +} + +string CompilerMSL::to_ptr_expression(uint32_t id, bool register_expression_read) +{ + auto *e = maybe_get(id); + auto expr = enclose_expression(e && e->need_transpose ? e->expression : to_expression(id, register_expression_read)); + if (!should_dereference(id)) + expr = address_of_expression(expr); + return expr; +} + void CompilerMSL::emit_binary_unord_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op) { @@ -6793,7 +7792,7 @@ bool CompilerMSL::emit_tessellation_io_load(uint32_t result_type_id, uint32_t id auto &result_type = get(result_type_id); if (ptr_type.storage != StorageClassInput && ptr_type.storage != StorageClassOutput) return false; - if (ptr_type.storage == StorageClassOutput && get_execution_model() == ExecutionModelTessellationEvaluation) + if (ptr_type.storage == StorageClassOutput && is_tese_shader()) return false; if (has_decoration(ptr, DecorationPatch)) @@ -7115,21 +8114,22 @@ bool CompilerMSL::emit_tessellation_access_chain(const uint32_t *ops, uint32_t l bool flatten_composites = false; bool is_block = false; - - if (var) - is_block = has_decoration(get_variable_data_type(*var).self, DecorationBlock); + bool is_arrayed = false; if (var) { + auto &type = get_variable_data_type(*var); + is_block = has_decoration(type.self, DecorationBlock); + is_arrayed = !type.array.empty(); + flatten_composites = variable_storage_requires_stage_io(var->storage); - patch = has_decoration(ops[2], DecorationPatch) || is_patch_block(get_variable_data_type(*var)); + patch = has_decoration(ops[2], DecorationPatch) || is_patch_block(type); // Should match strip_array in add_interface_block. - flat_data = var->storage == StorageClassInput || - (var->storage == StorageClassOutput && get_execution_model() == ExecutionModelTessellationControl); + flat_data = var->storage == StorageClassInput || (var->storage == StorageClassOutput && is_tesc_shader()); // Patch inputs are treated as normal block IO variables, so they don't deal with this path at all. - if (patch && (!is_block || var->storage == StorageClassInput)) + if (patch && (!is_block || is_arrayed || var->storage == StorageClassInput)) flat_data = false; // We might have a chained access chain, where @@ -7268,8 +8268,9 @@ bool CompilerMSL::emit_tessellation_access_chain(const uint32_t *ops, uint32_t l // We're not going to emit the actual member name, we let any further OpLoad take care of that. // Tag the access chain with the member index we're referencing. - bool defer_access_chain = flatten_composites && (is_matrix(result_ptr_type) || is_array(result_ptr_type) || - result_ptr_type.basetype == SPIRType::Struct); + auto &result_pointee_type = get_pointee_type(result_ptr_type); + bool defer_access_chain = flatten_composites && (is_matrix(result_pointee_type) || is_array(result_pointee_type) || + result_pointee_type.basetype == SPIRType::Struct); if (!defer_access_chain) { @@ -7367,7 +8368,7 @@ bool CompilerMSL::emit_tessellation_access_chain(const uint32_t *ops, uint32_t l expr_type->vecsize > result_ptr_type.vecsize) e += vector_swizzle(result_ptr_type.vecsize, 0); - auto &expr = set(ops[1], move(e), ops[0], should_forward(ops[2])); + auto &expr = set(ops[1], std::move(e), ops[0], should_forward(ops[2])); expr.loaded_from = var->self; expr.need_transpose = meta.need_transpose; expr.access_chain = true; @@ -7410,8 +8411,8 @@ bool CompilerMSL::emit_tessellation_access_chain(const uint32_t *ops, uint32_t l // Don't do this if the index is a constant 1, though. We need to drop stores // to that one. auto *m = ir.find_meta(var ? var->self : ID(0)); - if (get_execution_model() == ExecutionModelTessellationControl && var && m && - m->decoration.builtin_type == BuiltInTessLevelInner && get_entry_point().flags.get(ExecutionModeTriangles)) + if (is_tesc_shader() && var && m && m->decoration.builtin_type == BuiltInTessLevelInner && + is_tessellating_triangles()) { auto *c = maybe_get(ops[3]); if (c && c->scalar() == 1) @@ -7428,7 +8429,7 @@ bool CompilerMSL::emit_tessellation_access_chain(const uint32_t *ops, uint32_t l bool CompilerMSL::is_out_of_bounds_tessellation_level(uint32_t id_lhs) { - if (!get_entry_point().flags.get(ExecutionModeTriangles)) + if (!is_tessellating_triangles()) return false; // In SPIR-V, TessLevelInner always has two elements and TessLevelOuter always has @@ -7438,7 +8439,7 @@ bool CompilerMSL::is_out_of_bounds_tessellation_level(uint32_t id_lhs) // In Metal, however, only the first element of TessLevelInner and the first three // of TessLevelOuter are accessible. This stems from how in Metal, the tessellation // levels must be stored to a dedicated buffer in a particular format that depends - // on the patch type. Therefore, in Triangles mode, any access to the second + // on the patch type. Therefore, in Triangles mode, any store to the second // inner level or the fourth outer level must be dropped. const auto *e = maybe_get(id_lhs); if (!e || !e->access_chain) @@ -7453,7 +8454,7 @@ bool CompilerMSL::is_out_of_bounds_tessellation_level(uint32_t id_lhs) (builtin == BuiltInTessLevelOuter && c->scalar() == 3); } -void CompilerMSL::prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, +bool CompilerMSL::prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, spv::StorageClass storage, bool &is_packed) { // If there is any risk of writes happening with the access chain in question, @@ -7467,7 +8468,10 @@ void CompilerMSL::prepare_access_chain_for_scalar_access(std::string &expr, cons // Further indexing should happen with packed rules (array index, not swizzle). is_packed = true; + return true; } + else + return false; } bool CompilerMSL::access_chain_needs_stage_io_builtin_translation(uint32_t base) @@ -7480,8 +8484,7 @@ bool CompilerMSL::access_chain_needs_stage_io_builtin_translation(uint32_t base) // Avoid overriding it back to just gl_ClipDistance. // This can only happen in scenarios where we cannot flatten/unflatten access chains, so, the only case // where this triggers is evaluation shader inputs. - bool redirect_builtin = get_execution_model() == ExecutionModelTessellationEvaluation ? - var->storage == StorageClassOutput : false; + bool redirect_builtin = is_tese_shader() ? var->storage == StorageClassOutput : false; return redirect_builtin; } @@ -7540,12 +8543,31 @@ void CompilerMSL::fix_up_interpolant_access_chain(const uint32_t *ops, uint32_t set_extended_decoration(ops[1], SPIRVCrossDecorationInterfaceMemberIndex, interface_index); } + +// If the physical type of a physical buffer pointer has been changed +// to a ulong or ulongn vector, add a cast back to the pointer type. +void CompilerMSL::check_physical_type_cast(std::string &expr, const SPIRType *type, uint32_t physical_type) +{ + auto *p_physical_type = maybe_get(physical_type); + if (p_physical_type && + p_physical_type->storage == StorageClassPhysicalStorageBuffer && + p_physical_type->basetype == to_unsigned_basetype(64)) + { + if (p_physical_type->vecsize > 1) + expr += ".x"; + + expr = join("((", type_to_glsl(*type), ")", expr, ")"); + } +} + // Override for MSL-specific syntax instructions void CompilerMSL::emit_instruction(const Instruction &instruction) { #define MSL_BOP(op) emit_binary_op(ops[0], ops[1], ops[2], ops[3], #op) +#define MSL_PTR_BOP(op) emit_binary_ptr_op(ops[0], ops[1], ops[2], ops[3], #op) + // MSL does care about implicit integer promotion, but those cases are all handled in common code. #define MSL_BOP_CAST(op, type) \ - emit_binary_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, opcode_is_sign_invariant(opcode)) + emit_binary_op_cast(ops[0], ops[1], ops[2], ops[3], #op, type, opcode_is_sign_invariant(opcode), false) #define MSL_UOP(op) emit_unary_op(ops[0], ops[1], ops[2], #op) #define MSL_QFOP(op) emit_quaternary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], ops[5], #op) #define MSL_TFOP(op) emit_trinary_func_op(ops[0], ops[1], ops[2], ops[3], ops[4], #op) @@ -7558,6 +8580,8 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) auto ops = stream(instruction); auto opcode = static_cast(instruction.op); + opcode = get_remapped_spirv_op(opcode); + // If we need to do implicit bitcasts, make sure we do it with the correct type. uint32_t integer_width = get_integer_width_for_instruction(instruction); auto int_type = to_signed_basetype(integer_width); @@ -7600,6 +8624,10 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) case OpLogicalNotEqual: case OpFOrdNotEqual: + // TODO: Should probably negate the == result here. + // Typically OrdNotEqual comes from GLSL which itself does not really specify what + // happens with NaN. + // Consider fixing this if we run into real issues. MSL_BOP(!=); break; @@ -7656,7 +8684,9 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) break; case OpFUnordNotEqual: - MSL_UNORD_BOP(!=); + // not equal in MSL generates une opcodes to begin with. + // Since unordered not equal is how it works in C, just inherit that behavior. + MSL_BOP(!=); break; case OpFUnordGreaterThan: @@ -7675,6 +8705,19 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) MSL_UNORD_BOP(<=); break; + // Pointer math + case OpPtrEqual: + MSL_PTR_BOP(==); + break; + + case OpPtrNotEqual: + MSL_PTR_BOP(!=); + break; + + case OpPtrDiff: + MSL_PTR_BOP(-); + break; + // Derivatives case OpDPdx: case OpDPdxFine: @@ -7763,7 +8806,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) uint32_t ptr = ops[2]; uint32_t mem_sem = ops[4]; uint32_t val = ops[5]; - emit_atomic_func_op(result_type, id, "atomic_exchange_explicit", mem_sem, mem_sem, false, ptr, val); + emit_atomic_func_op(result_type, id, "atomic_exchange", opcode, mem_sem, mem_sem, false, ptr, val); break; } @@ -7776,7 +8819,8 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) uint32_t mem_sem_fail = ops[5]; uint32_t val = ops[6]; uint32_t comp = ops[7]; - emit_atomic_func_op(result_type, id, "atomic_compare_exchange_weak_explicit", mem_sem_pass, mem_sem_fail, true, + emit_atomic_func_op(result_type, id, "atomic_compare_exchange_weak", opcode, + mem_sem_pass, mem_sem_fail, true, ptr, comp, true, false, val); break; } @@ -7790,7 +8834,8 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) uint32_t id = ops[1]; uint32_t ptr = ops[2]; uint32_t mem_sem = ops[4]; - emit_atomic_func_op(result_type, id, "atomic_load_explicit", mem_sem, mem_sem, false, ptr, 0); + check_atomic_image(ptr); + emit_atomic_func_op(result_type, id, "atomic_load", opcode, mem_sem, mem_sem, false, ptr, 0); break; } @@ -7801,7 +8846,8 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) uint32_t ptr = ops[0]; uint32_t mem_sem = ops[2]; uint32_t val = ops[3]; - emit_atomic_func_op(result_type, id, "atomic_store_explicit", mem_sem, mem_sem, false, ptr, val); + check_atomic_image(ptr); + emit_atomic_func_op(result_type, id, "atomic_store", opcode, mem_sem, mem_sem, false, ptr, val); break; } @@ -7813,7 +8859,8 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) uint32_t ptr = ops[2]; \ uint32_t mem_sem = ops[4]; \ uint32_t val = valsrc; \ - emit_atomic_func_op(result_type, id, "atomic_fetch_" #op "_explicit", mem_sem, mem_sem, false, ptr, val, \ + emit_atomic_func_op(result_type, id, "atomic_fetch_" #op, opcode, \ + mem_sem, mem_sem, false, ptr, val, \ false, valconst); \ } while (false) @@ -7829,6 +8876,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) break; case OpAtomicIAdd: + case OpAtomicFAddEXT: MSL_AFMO(add); break; @@ -7866,9 +8914,9 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) // Mark that this shader reads from this image uint32_t img_id = ops[2]; auto &type = expression_type(img_id); + auto *p_var = maybe_get_backing_variable(img_id); if (type.image.dim != DimSubpassData) { - auto *p_var = maybe_get_backing_variable(img_id); if (p_var && has_decoration(p_var->self, DecorationNonReadable)) { unset_decoration(p_var->self, DecorationNonReadable); @@ -7876,6 +8924,10 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) } } + // Metal requires explicit fences to break up RAW hazards, even within the same shader invocation + if (msl_options.readwrite_texture_fences && p_var && !has_decoration(p_var->self, DecorationNonWritable)) + statement(to_expression(img_id), ".fence();"); + emit_texture_op(instruction, false); break; } @@ -7885,7 +8937,7 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) { // When using the pointer, we need to know which variable it is actually loaded from. auto *var = maybe_get_backing_variable(ops[2]); - if (var && atomic_image_vars.count(var->self)) + if (var && atomic_image_vars_emulated.count(var->self)) { uint32_t result_type = ops[0]; uint32_t id = ops[1]; @@ -7905,8 +8957,14 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) { uint32_t result_type = ops[0]; uint32_t id = ops[1]; + + // Virtual expression. Split this up in the actual image atomic. + // In GLSL and HLSL we are able to resolve the dereference inline, but MSL has + // image.op(coord, ...) syntax. auto &e = - set(id, join(to_expression(ops[2]), ", ", to_expression(ops[3])), result_type, true); + set(id, join(to_expression(ops[2]), "@", + bitcast_expression(SPIRType::UInt, ops[3])), + result_type, true); // When using the pointer, we need to know which variable it is actually loaded from. e.loaded_from = var ? var->self : ID(0); @@ -7968,9 +9026,16 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) args.base.is_fetch = true; args.coord = coord_id; args.lod = lod; - statement(join(to_expression(img_id), ".write(", - remap_swizzle(store_type, texel_type.vecsize, to_expression(texel_id)), ", ", - CompilerMSL::to_function_args(args, &forward), ");")); + + string expr; + if (needs_frag_discard_checks()) + expr = join("(", builtin_to_glsl(BuiltInHelperInvocation, StorageClassInput), " ? ((void)0) : "); + expr += join(to_expression(img_id), ".write(", + remap_swizzle(store_type, texel_type.vecsize, to_expression(texel_id)), ", ", + CompilerMSL::to_function_args(args, &forward), ")"); + if (needs_frag_discard_checks()) + expr += ")"; + statement(expr, ";"); if (p_var && variable_storage_is_aliased(*p_var)) flush_all_aliased_variables(); @@ -8125,14 +9190,34 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) break; case OpStore: - if (is_out_of_bounds_tessellation_level(ops[0])) - break; + { + const auto &type = expression_type(ops[0]); - if (maybe_emit_array_assignment(ops[0], ops[1])) + if (is_out_of_bounds_tessellation_level(ops[0])) break; - CompilerGLSL::emit_instruction(instruction); + if (needs_frag_discard_checks() && + (type.storage == StorageClassStorageBuffer || type.storage == StorageClassUniform)) + { + // If we're in a continue block, this kludge will make the block too complex + // to emit normally. + assert(current_emitting_block); + auto cont_type = continue_block_type(*current_emitting_block); + if (cont_type != SPIRBlock::ContinueNone && cont_type != SPIRBlock::ComplexLoop) + { + current_emitting_block->complex_continue = true; + force_recompile(); + } + statement("if (!", builtin_to_glsl(BuiltInHelperInvocation, StorageClassInput), ")"); + begin_scope(); + } + if (!maybe_emit_array_assignment(ops[0], ops[1])) + CompilerGLSL::emit_instruction(instruction); + if (needs_frag_discard_checks() && + (type.storage == StorageClassStorageBuffer || type.storage == StorageClassUniform)) + end_scope(); break; + } // Compute barriers case OpMemoryBarrier: @@ -8289,12 +9374,33 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) uint32_t op0 = ops[2]; uint32_t op1 = ops[3]; auto &type = get(result_type); + auto input_type = opcode == OpSMulExtended ? int_type : uint_type; + auto &output_type = get_type(result_type); + string cast_op0, cast_op1; + + auto expected_type = binary_op_bitcast_helper(cast_op0, cast_op1, input_type, op0, op1, false); + emit_uninitialized_temporary_expression(result_type, result_id); - statement(to_expression(result_id), ".", to_member_name(type, 0), " = ", - to_enclosed_unpacked_expression(op0), " * ", to_enclosed_unpacked_expression(op1), ";"); - statement(to_expression(result_id), ".", to_member_name(type, 1), " = mulhi(", - to_unpacked_expression(op0), ", ", to_unpacked_expression(op1), ");"); + string mullo_expr, mulhi_expr; + mullo_expr = join(cast_op0, " * ", cast_op1); + mulhi_expr = join("mulhi(", cast_op0, ", ", cast_op1, ")"); + + auto &low_type = get_type(output_type.member_types[0]); + auto &high_type = get_type(output_type.member_types[1]); + if (low_type.basetype != input_type) + { + expected_type.basetype = input_type; + mullo_expr = join(bitcast_glsl_op(low_type, expected_type), "(", mullo_expr, ")"); + } + if (high_type.basetype != input_type) + { + expected_type.basetype = input_type; + mulhi_expr = join(bitcast_glsl_op(high_type, expected_type), "(", mulhi_expr, ")"); + } + + statement(to_expression(result_id), ".", to_member_name(type, 0), " = ", mullo_expr, ";"); + statement(to_expression(result_id), ".", to_member_name(type, 1), " = ", mulhi_expr, ";"); break; } @@ -8309,6 +9415,16 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) break; } + // Legacy sub-group stuff ... + case OpSubgroupBallotKHR: + case OpSubgroupFirstInvocationKHR: + case OpSubgroupReadInvocationKHR: + case OpSubgroupAllKHR: + case OpSubgroupAnyKHR: + case OpSubgroupAllEqualKHR: + emit_subgroup_op(instruction); + break; + // SPV_INTEL_shader_integer_functions2 case OpUCountLeadingZerosINTEL: MSL_UFOP(clz); @@ -8379,7 +9495,10 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) SPIRV_CROSS_THROW("simd_is_helper_thread() requires MSL 2.3 on iOS."); else if (msl_options.is_macos() && !msl_options.supports_msl_version(2, 1)) SPIRV_CROSS_THROW("simd_is_helper_thread() requires MSL 2.1 on macOS."); - emit_op(ops[0], ops[1], "simd_is_helper_thread()", false); + emit_op(ops[0], ops[1], + needs_manual_helper_invocation_updates() ? builtin_to_glsl(BuiltInHelperInvocation, StorageClassInput) : + "simd_is_helper_thread()", + false); break; case OpBeginInvocationInterlockEXT: @@ -8396,15 +9515,18 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) case OpRayQueryInitializeKHR: { flush_variable_declaration(ops[0]); + register_write(ops[0]); + add_spv_func_and_recompile(SPVFuncImplRayQueryIntersectionParams); statement(to_expression(ops[0]), ".reset(", "ray(", to_expression(ops[4]), ", ", to_expression(ops[6]), ", ", - to_expression(ops[5]), ", ", to_expression(ops[7]), "), ", to_expression(ops[1]), - ", intersection_params());"); + to_expression(ops[5]), ", ", to_expression(ops[7]), "), ", to_expression(ops[1]), ", ", to_expression(ops[3]), + ", spvMakeIntersectionParams(", to_expression(ops[2]), "));"); break; } case OpRayQueryProceedKHR: { flush_variable_declaration(ops[0]); + register_write(ops[2]); emit_op(ops[0], ops[1], join(to_expression(ops[2]), ".next()"), false); break; } @@ -8429,8 +9551,8 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) #define MSL_RAY_QUERY_IS_OP2(op, msl_op) MSL_RAY_QUERY_OP_INNER2(op, .is, msl_op) MSL_RAY_QUERY_GET_OP(RayTMin, ray_min_distance); - MSL_RAY_QUERY_GET_OP(WorldRayOrigin, world_space_ray_direction); - MSL_RAY_QUERY_GET_OP(WorldRayDirection, world_space_ray_origin); + MSL_RAY_QUERY_GET_OP(WorldRayOrigin, world_space_ray_origin); + MSL_RAY_QUERY_GET_OP(WorldRayDirection, world_space_ray_direction); MSL_RAY_QUERY_GET_OP2(IntersectionInstanceId, instance_id); MSL_RAY_QUERY_GET_OP2(IntersectionInstanceCustomIndex, user_instance_id); MSL_RAY_QUERY_GET_OP2(IntersectionBarycentrics, triangle_barycentric_coord); @@ -8465,21 +9587,52 @@ void CompilerMSL::emit_instruction(const Instruction &instruction) } case OpRayQueryConfirmIntersectionKHR: flush_variable_declaration(ops[0]); + register_write(ops[0]); statement(to_expression(ops[0]), ".commit_triangle_intersection();"); break; case OpRayQueryGenerateIntersectionKHR: flush_variable_declaration(ops[0]); + register_write(ops[0]); statement(to_expression(ops[0]), ".commit_bounding_box_intersection(", to_expression(ops[1]), ");"); break; case OpRayQueryTerminateKHR: flush_variable_declaration(ops[0]); + register_write(ops[0]); statement(to_expression(ops[0]), ".abort();"); break; -#undef MSL_RAY_QUERY_GET_OP -#undef MSL_RAY_QUERY_IS_CANDIDATE -#undef MSL_RAY_QUERY_IS_OP2 -#undef MSL_RAY_QUERY_GET_OP2 -#undef MSL_RAY_QUERY_OP_INNER2 +#undef MSL_RAY_QUERY_GET_OP +#undef MSL_RAY_QUERY_IS_CANDIDATE +#undef MSL_RAY_QUERY_IS_OP2 +#undef MSL_RAY_QUERY_GET_OP2 +#undef MSL_RAY_QUERY_OP_INNER2 + + case OpConvertPtrToU: + case OpConvertUToPtr: + case OpBitcast: + { + auto &type = get(ops[0]); + auto &input_type = expression_type(ops[2]); + + if (opcode != OpBitcast || type.pointer || input_type.pointer) + { + string op; + + if (type.vecsize == 1 && input_type.vecsize == 1) + op = join("reinterpret_cast<", type_to_glsl(type), ">(", to_unpacked_expression(ops[2]), ")"); + else if (input_type.vecsize == 2) + op = join("reinterpret_cast<", type_to_glsl(type), ">(as_type(", to_unpacked_expression(ops[2]), "))"); + else + op = join("as_type<", type_to_glsl(type), ">(reinterpret_cast(", to_unpacked_expression(ops[2]), "))"); + + emit_op(ops[0], ops[1], op, should_forward(ops[2])); + inherit_expression_dependencies(ops[1], ops[2]); + } + else + CompilerGLSL::emit_instruction(instruction); + + break; + } + default: CompilerGLSL::emit_instruction(instruction); break; @@ -8521,7 +9674,7 @@ void CompilerMSL::emit_texture_op(const Instruction &i, bool sparse) void CompilerMSL::emit_barrier(uint32_t id_exe_scope, uint32_t id_mem_scope, uint32_t id_mem_sem) { - if (get_execution_model() != ExecutionModelGLCompute && get_execution_model() != ExecutionModelTessellationControl) + if (get_execution_model() != ExecutionModelGLCompute && !is_tesc_shader()) return; uint32_t exe_scope = id_exe_scope ? evaluate_constant_u32(id_exe_scope) : uint32_t(ScopeInvocation); @@ -8548,13 +9701,12 @@ void CompilerMSL::emit_barrier(uint32_t id_exe_scope, uint32_t id_mem_scope, uin string mem_flags = ""; // For tesc shaders, this also affects objects in the Output storage class. // Since in Metal, these are placed in a device buffer, we have to sync device memory here. - if (get_execution_model() == ExecutionModelTessellationControl || + if (is_tesc_shader() || (mem_sem & (MemorySemanticsUniformMemoryMask | MemorySemanticsCrossWorkgroupMemoryMask))) mem_flags += "mem_flags::mem_device"; // Fix tessellation patch function processing - if (get_execution_model() == ExecutionModelTessellationControl || - (mem_sem & (MemorySemanticsSubgroupMemoryMask | MemorySemanticsWorkgroupMemoryMask))) + if (is_tesc_shader() || (mem_sem & (MemorySemanticsSubgroupMemoryMask | MemorySemanticsWorkgroupMemoryMask))) { if (!mem_flags.empty()) mem_flags += " | "; @@ -8612,7 +9764,7 @@ static bool storage_class_array_is_thread(StorageClass storage) } } -void CompilerMSL::emit_array_copy(const string &lhs, uint32_t lhs_id, uint32_t rhs_id, +bool CompilerMSL::emit_array_copy(const char *expr, uint32_t lhs_id, uint32_t rhs_id, StorageClass lhs_storage, StorageClass rhs_storage) { // Allow Metal to use the array template to make arrays a value type. @@ -8620,8 +9772,8 @@ void CompilerMSL::emit_array_copy(const string &lhs, uint32_t lhs_id, uint32_t r bool lhs_is_thread_storage = storage_class_array_is_thread(lhs_storage); bool rhs_is_thread_storage = storage_class_array_is_thread(rhs_storage); - bool lhs_is_array_template = lhs_is_thread_storage; - bool rhs_is_array_template = rhs_is_thread_storage; + bool lhs_is_array_template = lhs_is_thread_storage || lhs_storage == StorageClassWorkgroup; + bool rhs_is_array_template = rhs_is_thread_storage || rhs_storage == StorageClassWorkgroup; // Special considerations for stage IO variables. // If the variable is actually backed by non-user visible device storage, we use array templates for those. @@ -8636,25 +9788,34 @@ void CompilerMSL::emit_array_copy(const string &lhs, uint32_t lhs_id, uint32_t r auto *lhs_var = maybe_get_backing_variable(lhs_id); if (lhs_var && lhs_storage == StorageClassStorageBuffer && storage_class_array_is_thread(lhs_var->storage)) lhs_is_array_template = true; - else if (lhs_var && (lhs_storage == StorageClassFunction || lhs_storage == StorageClassPrivate) && - type_is_block_like(get(lhs_var->basetype))) + else if (lhs_var && lhs_storage != StorageClassGeneric && type_is_block_like(get(lhs_var->basetype))) lhs_is_array_template = false; auto *rhs_var = maybe_get_backing_variable(rhs_id); if (rhs_var && rhs_storage == StorageClassStorageBuffer && storage_class_array_is_thread(rhs_var->storage)) rhs_is_array_template = true; - else if (rhs_var && (rhs_storage == StorageClassFunction || rhs_storage == StorageClassPrivate) && - type_is_block_like(get(rhs_var->basetype))) + else if (rhs_var && rhs_storage != StorageClassGeneric && type_is_block_like(get(rhs_var->basetype))) rhs_is_array_template = false; // If threadgroup storage qualifiers are *not* used: // Avoid spvCopy* wrapper functions; Otherwise, spvUnsafeArray<> template cannot be used with that storage qualifier. if (lhs_is_array_template && rhs_is_array_template && !using_builtin_array()) { - statement(lhs, " = ", to_expression(rhs_id), ";"); + // Fall back to normal copy path. + return false; } else { + // Ensure the LHS variable has been declared + if (lhs_var) + flush_variable_declaration(lhs_var->self); + + string lhs; + if (expr) + lhs = expr; + else + lhs = to_expression(lhs_id); + // Assignment from an array initializer is fine. auto &type = expression_type(rhs_id); auto *var = maybe_get_backing_variable(rhs_id); @@ -8671,7 +9832,7 @@ void CompilerMSL::emit_array_copy(const string &lhs, uint32_t lhs_id, uint32_t r { is_constant = true; } - else if (rhs_storage == StorageClassUniform) + else if (rhs_storage == StorageClassUniform || rhs_storage == StorageClassUniformConstant) { is_constant = true; } @@ -8728,11 +9889,13 @@ void CompilerMSL::emit_array_copy(const string &lhs, uint32_t lhs_id, uint32_t r else statement("spvArrayCopy", tag, type.array.size(), "(", lhs, ", ", to_expression(rhs_id), ");"); } + + return true; } uint32_t CompilerMSL::get_physical_tess_level_array_size(spv::BuiltIn builtin) const { - if (get_execution_mode_bitset().get(ExecutionModeTriangles)) + if (is_tessellating_triangles()) return builtin == BuiltInTessLevelInner ? 1 : 3; else return builtin == BuiltInTessLevelInner ? 2 : 4; @@ -8745,8 +9908,8 @@ uint32_t CompilerMSL::get_physical_tess_level_array_size(spv::BuiltIn builtin) c bool CompilerMSL::maybe_emit_array_assignment(uint32_t id_lhs, uint32_t id_rhs) { // We only care about assignments of an entire array - auto &type = expression_type(id_rhs); - if (type.array.size() == 0) + auto &type = expression_type(id_lhs); + if (!is_array(get_pointee_type(type))) return false; auto *var = maybe_get(id_lhs); @@ -8766,8 +9929,7 @@ bool CompilerMSL::maybe_emit_array_assignment(uint32_t id_lhs, uint32_t id_rhs) return true; } - if (get_execution_model() == ExecutionModelTessellationControl && - has_decoration(id_lhs, DecorationBuiltIn)) + if (is_tesc_shader() && has_decoration(id_lhs, DecorationBuiltIn)) { auto builtin = BuiltIn(get_decoration(id_lhs, DecorationBuiltIn)); // Need to manually unroll the array store. @@ -8785,99 +9947,220 @@ bool CompilerMSL::maybe_emit_array_assignment(uint32_t id_lhs, uint32_t id_rhs) } } - // Ensure the LHS variable has been declared - auto *p_v_lhs = maybe_get_backing_variable(id_lhs); - if (p_v_lhs) - flush_variable_declaration(p_v_lhs->self); - auto lhs_storage = get_expression_effective_storage_class(id_lhs); auto rhs_storage = get_expression_effective_storage_class(id_rhs); - emit_array_copy(to_expression(id_lhs), id_lhs, id_rhs, lhs_storage, rhs_storage); + if (!emit_array_copy(nullptr, id_lhs, id_rhs, lhs_storage, rhs_storage)) + return false; + register_write(id_lhs); return true; } // Emits one of the atomic functions. In MSL, the atomic functions operate on pointers -void CompilerMSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id, const char *op, uint32_t mem_order_1, - uint32_t mem_order_2, bool has_mem_order_2, uint32_t obj, uint32_t op1, +void CompilerMSL::emit_atomic_func_op(uint32_t result_type, uint32_t result_id, const char *op, Op opcode, + uint32_t mem_order_1, uint32_t mem_order_2, bool has_mem_order_2, uint32_t obj, uint32_t op1, bool op1_is_pointer, bool op1_is_literal, uint32_t op2) { - string exp = string(op) + "("; + string exp; auto &type = get_pointee_type(expression_type(obj)); - exp += "("; + auto expected_type = type.basetype; + if (opcode == OpAtomicUMax || opcode == OpAtomicUMin) + expected_type = to_unsigned_basetype(type.width); + else if (opcode == OpAtomicSMax || opcode == OpAtomicSMin) + expected_type = to_signed_basetype(type.width); + + bool use_native_image_atomic; + if (msl_options.supports_msl_version(3, 1)) + use_native_image_atomic = check_atomic_image(obj); + else + use_native_image_atomic = false; + + if (type.width == 64) + SPIRV_CROSS_THROW("MSL currently does not support 64-bit atomics."); + + auto remapped_type = type; + remapped_type.basetype = expected_type; + auto *var = maybe_get_backing_variable(obj); if (!var) SPIRV_CROSS_THROW("No backing variable for atomic operation."); - - // Emulate texture2D atomic operations const auto &res_type = get(var->basetype); - if (res_type.storage == StorageClassUniformConstant && res_type.basetype == SPIRType::Image) + + bool is_atomic_compare_exchange_strong = op1_is_pointer && op1; + + bool check_discard = opcode != OpAtomicLoad && needs_frag_discard_checks() && + ((res_type.storage == StorageClassUniformConstant && res_type.basetype == SPIRType::Image) || + var->storage == StorageClassStorageBuffer || var->storage == StorageClassUniform); + + // Even compare exchange atomics are vec4 on metal for ... reasons :v + uint32_t vec4_temporary_id = 0; + if (use_native_image_atomic && is_atomic_compare_exchange_strong) { - exp += "device"; + uint32_t &tmp_id = extra_sub_expressions[result_id]; + if (!tmp_id) + { + tmp_id = ir.increase_bound_by(2); + + auto vec4_type = get(result_type); + vec4_type.vecsize = 4; + set(tmp_id + 1, vec4_type); + } + + vec4_temporary_id = tmp_id; } - else + + if (check_discard) { - exp += get_argument_address_space(*var); + if (is_atomic_compare_exchange_strong) + { + // We're already emitting a CAS loop here; a conditional won't hurt. + emit_uninitialized_temporary_expression(result_type, result_id); + if (vec4_temporary_id) + emit_uninitialized_temporary_expression(vec4_temporary_id + 1, vec4_temporary_id); + statement("if (!", builtin_to_glsl(BuiltInHelperInvocation, StorageClassInput), ")"); + begin_scope(); + } + else + exp = join("(!", builtin_to_glsl(BuiltInHelperInvocation, StorageClassInput), " ? "); } - exp += " atomic_"; - exp += type_to_glsl(type); - exp += "*)"; + if (use_native_image_atomic) + { + auto obj_expression = to_expression(obj); + auto split_index = obj_expression.find_first_of('@'); + + // Will only be false if we're in "force recompile later" mode. + if (split_index != string::npos) + exp += join(obj_expression.substr(0, split_index), ".", op, "(", obj_expression.substr(split_index + 1)); + else + exp += obj_expression; + } + else + { + exp += string(op) + "_explicit("; + exp += "("; + // Emulate texture2D atomic operations + if (res_type.storage == StorageClassUniformConstant && res_type.basetype == SPIRType::Image) + { + exp += "device"; + } + else + { + exp += get_argument_address_space(*var); + } - exp += "&"; - exp += to_enclosed_expression(obj); + exp += " atomic_"; + // For signed and unsigned min/max, we can signal this through the pointer type. + // There is no other way, since C++ does not have explicit signage for atomics. + exp += type_to_glsl(remapped_type); + exp += "*)"; - bool is_atomic_compare_exchange_strong = op1_is_pointer && op1; + exp += "&"; + exp += to_enclosed_expression(obj); + } if (is_atomic_compare_exchange_strong) { - assert(strcmp(op, "atomic_compare_exchange_weak_explicit") == 0); + assert(strcmp(op, "atomic_compare_exchange_weak") == 0); assert(op2); assert(has_mem_order_2); exp += ", &"; - exp += to_name(result_id); + exp += to_name(vec4_temporary_id ? vec4_temporary_id : result_id); exp += ", "; exp += to_expression(op2); - exp += ", "; - exp += get_memory_order(mem_order_1); - exp += ", "; - exp += get_memory_order(mem_order_2); + + if (!use_native_image_atomic) + { + exp += ", "; + exp += get_memory_order(mem_order_1); + exp += ", "; + exp += get_memory_order(mem_order_2); + } exp += ")"; // MSL only supports the weak atomic compare exchange, so emit a CAS loop here. // The MSL function returns false if the atomic write fails OR the comparison test fails, // so we must validate that it wasn't the comparison test that failed before continuing // the CAS loop, otherwise it will loop infinitely, with the comparison test always failing. - // The function updates the comparitor value from the memory value, so the additional + // The function updates the comparator value from the memory value, so the additional // comparison test evaluates the memory value against the expected value. - emit_uninitialized_temporary_expression(result_type, result_id); + if (!check_discard) + { + emit_uninitialized_temporary_expression(result_type, result_id); + if (vec4_temporary_id) + emit_uninitialized_temporary_expression(vec4_temporary_id + 1, vec4_temporary_id); + } + statement("do"); begin_scope(); - statement(to_name(result_id), " = ", to_expression(op1), ";"); - end_scope_decl(join("while (!", exp, " && ", to_name(result_id), " == ", to_enclosed_expression(op1), ")")); + + string scalar_expression; + if (vec4_temporary_id) + scalar_expression = join(to_expression(vec4_temporary_id), ".x"); + else + scalar_expression = to_expression(result_id); + + statement(scalar_expression, " = ", to_expression(op1), ";"); + end_scope_decl(join("while (!", exp, " && ", scalar_expression, " == ", to_enclosed_expression(op1), ")")); + if (vec4_temporary_id) + statement(to_expression(result_id), " = ", scalar_expression, ";"); + + // Vulkan: (section 9.29: ... and values returned by atomic instructions in helper invocations are undefined) + if (check_discard) + { + end_scope(); + statement("else"); + begin_scope(); + statement(to_expression(result_id), " = {};"); + end_scope(); + } } else { - assert(strcmp(op, "atomic_compare_exchange_weak_explicit") != 0); + assert(strcmp(op, "atomic_compare_exchange_weak") != 0); + if (op1) { + exp += ", "; if (op1_is_literal) - exp += join(", ", op1); + exp += to_string(op1); else - exp += ", " + to_expression(op1); + exp += bitcast_expression(expected_type, op1); } + if (op2) exp += ", " + to_expression(op2); - exp += string(", ") + get_memory_order(mem_order_1); - if (has_mem_order_2) - exp += string(", ") + get_memory_order(mem_order_2); + if (!use_native_image_atomic) + { + exp += string(", ") + get_memory_order(mem_order_1); + if (has_mem_order_2) + exp += string(", ") + get_memory_order(mem_order_2); + } exp += ")"; - if (strcmp(op, "atomic_store_explicit") != 0) + // For some particular reason, atomics return vec4 in Metal ... + if (use_native_image_atomic) + exp += ".x"; + + // Vulkan: (section 9.29: ... and values returned by atomic instructions in helper invocations are undefined) + if (check_discard) + { + exp += " : "; + if (strcmp(op, "atomic_store") != 0) + exp += join(type_to_glsl(get(result_type)), "{}"); + else + exp += "((void)0)"; + exp += ")"; + } + + if (expected_type != type.basetype) + exp = bitcast_expression(type, expected_type, exp); + + if (strcmp(op, "atomic_store") != 0) emit_op(result_type, result_id, exp, false); else statement(exp, ";"); @@ -8903,6 +10186,8 @@ void CompilerMSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, auto int_type = to_signed_basetype(integer_width); auto uint_type = to_unsigned_basetype(integer_width); + op = get_remapped_glsl_op(op); + switch (op) { case GLSLstd450Sinh: @@ -9147,14 +10432,19 @@ void CompilerMSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, break; case GLSLstd450Normalize: + { + auto &exp_type = expression_type(args[0]); // MSL does not support scalar versions here. + // MSL has no implementation for normalize in the fast:: namespace for half2 and half3 // Returns -1 or 1 for valid input, sign() does the job. - if (expression_type(args[0]).vecsize == 1) + if (exp_type.vecsize == 1) emit_unary_func_op(result_type, id, args[0], "sign"); + else if (exp_type.vecsize <= 3 && exp_type.basetype == SPIRType::Half) + emit_unary_func_op(result_type, id, args[0], "normalize"); else emit_unary_func_op(result_type, id, args[0], "fast::normalize"); break; - + } case GLSLstd450Reflect: if (get(result_type).vecsize == 1) emit_binary_func_op(result_type, id, args[0], args[1], "spvReflect"); @@ -9210,6 +10500,11 @@ void CompilerMSL::emit_glsl_op(uint32_t result_type, uint32_t id, uint32_t eop, break; } + case GLSLstd450Pow: + // powr makes x < 0.0 undefined, just like SPIR-V. + emit_binary_func_op(result_type, id, args[0], args[1], "powr"); + break; + default: CompilerGLSL::emit_glsl_op(result_type, id, eop, args, count); break; @@ -9313,6 +10608,9 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &) else decl += entry_point_args_classic(!func.arguments.empty()); + // append entry point args to avoid conflicts in local variable names. + local_variable_names.insert(resource_names.begin(), resource_names.end()); + // If entry point function has variables that require early declaration, // ensure they each have an empty initializer, creating one if needed. // This is done at this late stage because the initialization expression @@ -9364,7 +10662,21 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &) // Manufacture automatic sampler arg for SampledImage texture if (arg_type.image.dim != DimBuffer) - decl += join(", thread const ", sampler_type(arg_type, arg.id), " ", to_sampler_expression(arg.id)); + { + if (arg_type.array.empty() || (var ? is_var_runtime_size_array(*var) : is_runtime_size_array(arg_type))) + { + decl += join(", ", sampler_type(arg_type, arg.id), " ", to_sampler_expression(name_id)); + } + else + { + const char *sampler_address_space = + descriptor_address_space(name_id, + StorageClassUniformConstant, + "thread const"); + decl += join(", ", sampler_address_space, " ", sampler_type(arg_type, name_id), "& ", + to_sampler_expression(name_id)); + } + } } // Manufacture automatic swizzle arg. @@ -9372,10 +10684,10 @@ void CompilerMSL::emit_function_prototype(SPIRFunction &func, const Bitset &) !is_dynamic_img_sampler) { bool arg_is_array = !arg_type.array.empty(); - decl += join(", constant uint", arg_is_array ? "* " : "& ", to_swizzle_expression(arg.id)); + decl += join(", constant uint", arg_is_array ? "* " : "& ", to_swizzle_expression(name_id)); } - if (buffers_requiring_array_length.count(name_id)) + if (buffer_requires_array_length(name_id)) { bool arg_is_array = !arg_type.array.empty(); decl += join(", constant uint", arg_is_array ? "* " : "& ", to_buffer_size_expression(name_id)); @@ -9547,7 +10859,7 @@ string CompilerMSL::to_function_name(const TextureFunctionNameArguments &args) string CompilerMSL::convert_to_f32(const string &expr, uint32_t components) { - SPIRType t; + SPIRType t { components > 1 ? OpTypeVector : OpTypeFloat }; t.basetype = SPIRType::Float; t.vecsize = components; t.columns = 1; @@ -9739,25 +11051,24 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool break; } - if (args.base.is_fetch && (args.offset || args.coffset)) + if (args.base.is_fetch && args.offset) { - uint32_t offset_expr = args.offset ? args.offset : args.coffset; // Fetch offsets must be applied directly to the coordinate. - forward = forward && should_forward(offset_expr); - auto &type = expression_type(offset_expr); + forward = forward && should_forward(args.offset); + auto &type = expression_type(args.offset); if (imgtype.image.dim == Dim1D && msl_options.texture_1D_as_2D) { if (type.basetype != SPIRType::UInt) - tex_coords += join(" + uint2(", bitcast_expression(SPIRType::UInt, offset_expr), ", 0)"); + tex_coords += join(" + uint2(", bitcast_expression(SPIRType::UInt, args.offset), ", 0)"); else - tex_coords += join(" + uint2(", to_enclosed_expression(offset_expr), ", 0)"); + tex_coords += join(" + uint2(", to_enclosed_expression(args.offset), ", 0)"); } else { if (type.basetype != SPIRType::UInt) - tex_coords += " + " + bitcast_expression(SPIRType::UInt, offset_expr); + tex_coords += " + " + bitcast_expression(SPIRType::UInt, args.offset); else - tex_coords += " + " + to_enclosed_expression(offset_expr); + tex_coords += " + " + to_enclosed_expression(args.offset); } } @@ -9862,7 +11173,8 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool // We will detect a compile-time constant 0 value for gradient and promote that to level(0) on MSL. bool constant_zero_x = !grad_x || expression_is_constant_null(grad_x); bool constant_zero_y = !grad_y || expression_is_constant_null(grad_y); - if (constant_zero_x && constant_zero_y) + if (constant_zero_x && constant_zero_y && + (!imgtype.image.arrayed || !msl_options.sample_dref_lod_array_as_grad)) { lod = 0; grad_x = 0; @@ -9908,6 +11220,64 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool { farg_str += ", " + to_expression(lod); } + else if (msl_options.sample_dref_lod_array_as_grad && args.dref && imgtype.image.arrayed) + { + if (msl_options.is_macos() && !msl_options.supports_msl_version(2, 3)) + SPIRV_CROSS_THROW("Using non-constant 0.0 gradient() qualifier for sample_compare. This is not " + "supported on macOS prior to MSL 2.3."); + // Some Metal devices have a bug where the LoD is erroneously biased upward + // when using a level() argument. Since this doesn't happen as much with gradient2d(), + // if we perform the LoD calculation in reverse, we can pass a gradient + // instead. + // lod = log2(rhoMax/eta) -> exp2(lod) = rhoMax/eta + // If we make all of the scale factors the same, eta will be 1 and + // exp2(lod) = rho. + // rhoX = dP/dx * extent; rhoY = dP/dy * extent + // Therefore, dP/dx = dP/dy = exp2(lod)/extent. + // (Subtracting 0.5 before exponentiation gives better results.) + string grad_opt, extent, grad_coord; + VariableID base_img = img; + if (auto *combined = maybe_get(img)) + base_img = combined->image; + switch (imgtype.image.dim) + { + case Dim1D: + grad_opt = "gradient2d"; + extent = join("float2(", to_expression(base_img), ".get_width(), 1.0)"); + break; + case Dim2D: + grad_opt = "gradient2d"; + extent = join("float2(", to_expression(base_img), ".get_width(), ", to_expression(base_img), ".get_height())"); + break; + case DimCube: + if (imgtype.image.arrayed && msl_options.emulate_cube_array) + { + grad_opt = "gradient2d"; + extent = join("float2(", to_expression(base_img), ".get_width())"); + } + else + { + if (msl_options.agx_manual_cube_grad_fixup) + { + add_spv_func_and_recompile(SPVFuncImplGradientCube); + grad_opt = "spvGradientCube"; + grad_coord = tex_coords + ", "; + } + else + { + grad_opt = "gradientcube"; + } + extent = join("float3(", to_expression(base_img), ".get_width())"); + } + break; + default: + grad_opt = "unsupported_gradient_dimension"; + extent = "float3(1.0)"; + break; + } + farg_str += join(", ", grad_opt, "(", grad_coord, "exp2(", to_expression(lod), " - 0.5) / ", extent, + ", exp2(", to_expression(lod), " - 0.5) / ", extent, ")"); + } else { farg_str += ", level(" + to_expression(lod) + ")"; @@ -9926,27 +11296,37 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool { forward = forward && should_forward(grad_x); forward = forward && should_forward(grad_y); - string grad_opt; + string grad_opt, grad_coord; switch (imgtype.image.dim) { case Dim1D: case Dim2D: - grad_opt = "2d"; + grad_opt = "gradient2d"; break; case Dim3D: - grad_opt = "3d"; + grad_opt = "gradient3d"; break; case DimCube: if (imgtype.image.arrayed && msl_options.emulate_cube_array) - grad_opt = "2d"; + { + grad_opt = "gradient2d"; + } + else if (msl_options.agx_manual_cube_grad_fixup) + { + add_spv_func_and_recompile(SPVFuncImplGradientCube); + grad_opt = "spvGradientCube"; + grad_coord = tex_coords + ", "; + } else - grad_opt = "cube"; + { + grad_opt = "gradientcube"; + } break; default: grad_opt = "unsupported_gradient_dimension"; break; } - farg_str += ", gradient" + grad_opt + "(" + to_expression(grad_x) + ", " + to_expression(grad_y) + ")"; + farg_str += join(", ", grad_opt, "(", grad_coord, to_expression(grad_x), ", ", to_expression(grad_y), ")"); } if (args.min_lod) @@ -9961,13 +11341,7 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool // Add offsets string offset_expr; const SPIRType *offset_type = nullptr; - if (args.coffset && !args.base.is_fetch) - { - forward = forward && should_forward(args.coffset); - offset_expr = to_expression(args.coffset); - offset_type = &expression_type(args.coffset); - } - else if (args.offset && !args.base.is_fetch) + if (args.offset && !args.base.is_fetch) { forward = forward && should_forward(args.offset); offset_expr = to_expression(args.offset); @@ -10047,7 +11421,7 @@ string CompilerMSL::to_function_args(const TextureFunctionArguments &args, bool // If the texture coordinates are floating point, invokes MSL round() function to round them. string CompilerMSL::round_fp_tex_coords(string tex_coords, bool coord_is_fp) { - return coord_is_fp ? ("round(" + tex_coords + ")") : tex_coords; + return coord_is_fp ? ("rint(" + tex_coords + ")") : tex_coords; } // Returns a string to use in an image sampling function argument. @@ -10313,6 +11687,10 @@ string CompilerMSL::to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_ constants.push_back(id); } } + // Dereference pointer variables where needed. + // FIXME: This dereference is actually backwards. We should really just support passing pointer variables between functions. + else if (should_dereference(id)) + arg_str += dereference_expression(type, CompilerGLSL::to_func_call_arg(arg, id)); else arg_str += CompilerGLSL::to_func_call_arg(arg, id); @@ -10408,7 +11786,7 @@ string CompilerMSL::to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_ else if (msl_options.swizzle_texture_samples && has_sampled_images && is_sampled_image_type(type)) arg_str += ", " + to_swizzle_expression(var_id ? var_id : id); - if (buffers_requiring_array_length.count(var_id)) + if (buffer_requires_array_length(var_id)) arg_str += ", " + to_buffer_size_expression(var_id ? var_id : id); if (is_dynamic_img_sampler) @@ -10417,7 +11795,7 @@ string CompilerMSL::to_func_call_arg(const SPIRFunction::Parameter &arg, uint32_ // Emulate texture2D atomic operations auto *backing_var = maybe_get_backing_variable(var_id); - if (backing_var && atomic_image_vars.count(backing_var->self)) + if (backing_var && atomic_image_vars_emulated.count(backing_var->self)) { arg_str += ", " + to_expression(var_id) + "_atomic"; } @@ -10492,6 +11870,18 @@ string CompilerMSL::to_buffer_size_expression(uint32_t id) { auto buffer_expr = expr.substr(0, index); auto array_expr = expr.substr(index); + if (auto var = maybe_get_backing_variable(id)) + { + if (is_var_runtime_size_array(*var)) + { + if (!msl_options.runtime_array_rich_descriptor) + SPIRV_CROSS_THROW("OpArrayLength requires rich descriptor format"); + + auto last_pos = array_expr.find_last_of(']'); + if (last_pos != std::string::npos) + return buffer_expr + ".length(" + array_expr.substr(1, last_pos - 1) + ")"; + } + } return buffer_expr + buffer_size_name_suffix + array_expr; } } @@ -10528,11 +11918,11 @@ bool CompilerMSL::member_is_non_native_row_major_matrix(const SPIRType &type, ui } string CompilerMSL::convert_row_major_matrix(string exp_str, const SPIRType &exp_type, uint32_t physical_type_id, - bool is_packed) + bool is_packed, bool relaxed) { if (!is_matrix(exp_type)) { - return CompilerGLSL::convert_row_major_matrix(move(exp_str), exp_type, physical_type_id, is_packed); + return CompilerGLSL::convert_row_major_matrix(std::move(exp_str), exp_type, physical_type_id, is_packed, relaxed); } else { @@ -10561,6 +11951,7 @@ void CompilerMSL::emit_fixup() string CompilerMSL::to_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index, const string &qualifier) { + uint32_t orig_member_type_id = member_type_id; if (member_is_remapped_physical_type(type, index)) member_type_id = get_extended_member_decoration(type.self, index, SPIRVCrossDecorationPhysicalTypeID); auto &physical_type = get(member_type_id); @@ -10577,7 +11968,7 @@ string CompilerMSL::to_struct_member(const SPIRType &type, uint32_t member_type_ if (is_matrix(physical_type)) row_major = has_member_decoration(type.self, index, DecorationRowMajor); - SPIRType row_major_physical_type; + SPIRType row_major_physical_type { OpTypeMatrix }; const SPIRType *declared_type = &physical_type; // If a struct is being declared with physical layout, @@ -10623,19 +12014,33 @@ string CompilerMSL::to_struct_member(const SPIRType &type, uint32_t member_type_ else if (!is_scalar(physical_type)) // scalar type is already packed. pack_pfx = "packed_"; } - else if (row_major) + else if (is_matrix(physical_type)) { - // Need to declare type with flipped vecsize/columns. - row_major_physical_type = physical_type; - swap(row_major_physical_type.vecsize, row_major_physical_type.columns); - declared_type = &row_major_physical_type; + if (!msl_options.supports_msl_version(3, 0) && + has_extended_decoration(type.self, SPIRVCrossDecorationWorkgroupStruct)) + { + pack_pfx = "spvStorage_"; + add_spv_func_and_recompile(SPVFuncImplStorageMatrix); + // The pack prefix causes problems with array wrappers. + is_using_builtin_array = true; + } + if (row_major) + { + // Need to declare type with flipped vecsize/columns. + row_major_physical_type = physical_type; + swap(row_major_physical_type.vecsize, row_major_physical_type.columns); + declared_type = &row_major_physical_type; + } } - // Very specifically, image load-store in argument buffers are disallowed on MSL on iOS. - if (msl_options.is_ios() && physical_type.basetype == SPIRType::Image && physical_type.image.sampled == 2) + // iOS Tier 1 argument buffers do not support writable images. + if (physical_type.basetype == SPIRType::Image && + physical_type.image.sampled == 2 && + msl_options.is_ios() && + msl_options.argument_buffers_tier <= Options::ArgumentBuffersTier::Tier1 && + !has_decoration(orig_id, DecorationNonWritable)) { - if (!has_decoration(orig_id, DecorationNonWritable)) - SPIRV_CROSS_THROW("Writable images are not allowed in argument buffers on iOS."); + SPIRV_CROSS_THROW("Writable images are not allowed on Tier1 argument buffers on iOS."); } // Array information is baked into these types. @@ -10658,8 +12063,25 @@ string CompilerMSL::to_struct_member(const SPIRType &type, uint32_t member_type_ array_type = type_to_array_glsl(physical_type); } - auto result = join(pack_pfx, type_to_glsl(*declared_type, orig_id), " ", qualifier, to_member_name(type, index), - member_attribute_qualifier(type, index), array_type, ";"); + string decl_type; + if (declared_type->vecsize > 4) + { + auto orig_type = get(orig_member_type_id); + if (is_matrix(orig_type) && row_major) + swap(orig_type.vecsize, orig_type.columns); + orig_type.columns = 1; + decl_type = type_to_glsl(orig_type, orig_id, true); + + if (declared_type->columns > 1) + decl_type = join("spvPaddedStd140Matrix<", decl_type, ", ", declared_type->columns, ">"); + else + decl_type = join("spvPaddedStd140<", decl_type, ">"); + } + else + decl_type = type_to_glsl(*declared_type, orig_id, true); + + auto result = join(pack_pfx, decl_type, " ", qualifier, + to_member_name(type, index), member_attribute_qualifier(type, index), array_type, ";"); is_using_builtin_array = false; return result; @@ -10750,8 +12172,7 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in } // Vertex and tessellation evaluation function outputs - if (((execution.model == ExecutionModelVertex && !msl_options.vertex_for_tessellation) || - execution.model == ExecutionModelTessellationEvaluation) && + if (((execution.model == ExecutionModelVertex && !msl_options.vertex_for_tessellation) || is_tese_shader()) && type.storage == StorageClassOutput) { if (is_builtin) @@ -10794,8 +12215,18 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in return join(" [[", loc_qual, "]]"); } + if (execution.model == ExecutionModelVertex && msl_options.vertex_for_tessellation && type.storage == StorageClassOutput) + { + // For this type of shader, we always arrange for it to capture its + // output to a buffer. For this reason, qualifiers are irrelevant here. + if (is_builtin) + // We still have to assign a location so the output struct will sort correctly. + get_or_allocate_builtin_output_member_location(builtin, type.self, index); + return ""; + } + // Tessellation control function inputs - if (execution.model == ExecutionModelTessellationControl && type.storage == StorageClassInput) + if (is_tesc_shader() && type.storage == StorageClassInput) { if (is_builtin) { @@ -10832,15 +12263,18 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in } // Tessellation control function outputs - if (execution.model == ExecutionModelTessellationControl && type.storage == StorageClassOutput) + if (is_tesc_shader() && type.storage == StorageClassOutput) { // For this type of shader, we always arrange for it to capture its // output to a buffer. For this reason, qualifiers are irrelevant here. + if (is_builtin) + // We still have to assign a location so the output struct will sort correctly. + get_or_allocate_builtin_output_member_location(builtin, type.self, index); return ""; } // Tessellation evaluation function inputs - if (execution.model == ExecutionModelTessellationEvaluation && type.storage == StorageClassInput) + if (is_tese_shader() && type.storage == StorageClassInput) { if (is_builtin) { @@ -10856,6 +12290,10 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in break; } } + + if (msl_options.raw_buffer_tese_input) + return ""; + // The special control point array must not be marked with an attribute. if (get_type(type.member_types[index]).basetype == SPIRType::ControlPointArray) return ""; @@ -10890,8 +12328,8 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in case BuiltInSampleId: case BuiltInSampleMask: case BuiltInLayer: - case BuiltInBaryCoordNV: - case BuiltInBaryCoordNoPerspNV: + case BuiltInBaryCoordKHR: + case BuiltInBaryCoordNoPerspKHR: quals = builtin_qualifier(builtin); break; @@ -10907,7 +12345,7 @@ string CompilerMSL::member_attribute_qualifier(const SPIRType &type, uint32_t in else quals = member_location_attribute_qualifier(type, index); - if (builtin == BuiltInBaryCoordNV || builtin == BuiltInBaryCoordNoPerspNV) + if (builtin == BuiltInBaryCoordKHR || builtin == BuiltInBaryCoordNoPerspKHR) { if (has_member_decoration(type.self, index, DecorationFlat) || has_member_decoration(type.self, index, DecorationCentroid) || @@ -11113,7 +12551,7 @@ uint32_t CompilerMSL::get_or_allocate_builtin_input_member_location(spv::BuiltIn // Triangle tess level inputs are shared in one packed float4, // mark both builtins as sharing one location. - if (get_execution_mode_bitset().get(ExecutionModeTriangles) && + if (!msl_options.raw_buffer_tese_input && is_tessellating_triangles() && (builtin == BuiltInTessLevelInner || builtin == BuiltInTessLevelOuter)) { builtin_to_automatic_input_location[BuiltInTessLevelInner] = loc; @@ -11126,6 +12564,49 @@ uint32_t CompilerMSL::get_or_allocate_builtin_input_member_location(spv::BuiltIn return loc; } +uint32_t CompilerMSL::get_or_allocate_builtin_output_member_location(spv::BuiltIn builtin, + uint32_t type_id, uint32_t index, + uint32_t *comp) +{ + uint32_t loc = get_member_location(type_id, index, comp); + if (loc != k_unknown_location) + return loc; + loc = 0; + + if (comp) + *comp = k_unknown_component; + + // Late allocation. Find a location which is unused by the application. + // This can happen for built-in outputs in tessellation which are mixed and matched with user inputs. + auto &mbr_type = get(get(type_id).member_types[index]); + uint32_t count = type_to_location_count(mbr_type); + + const auto location_range_in_use = [this](uint32_t location, uint32_t location_count) -> bool { + for (uint32_t i = 0; i < location_count; i++) + if (location_outputs_in_use.count(location + i) != 0) + return true; + return false; + }; + + while (location_range_in_use(loc, count)) + loc++; + + set_member_decoration(type_id, index, DecorationLocation, loc); + + // Triangle tess level inputs are shared in one packed float4; + // mark both builtins as sharing one location. + if (is_tessellating_triangles() && (builtin == BuiltInTessLevelInner || builtin == BuiltInTessLevelOuter)) + { + builtin_to_automatic_output_location[BuiltInTessLevelInner] = loc; + builtin_to_automatic_output_location[BuiltInTessLevelOuter] = loc; + } + else + builtin_to_automatic_output_location[builtin] = loc; + + mark_location_as_used_by_shader(loc, mbr_type, StorageClassOutput, true); + return loc; +} + // Returns the type declaration for a function, including the // entry type if the current function is the entry point function string CompilerMSL::func_type_decl(SPIRType &type) @@ -11156,10 +12637,9 @@ string CompilerMSL::func_type_decl(SPIRType &type) if (execution.flags.get(ExecutionModeIsolines)) SPIRV_CROSS_THROW("Metal does not support isoline tessellation."); if (msl_options.is_ios()) - entry_type = - join("[[ patch(", execution.flags.get(ExecutionModeTriangles) ? "triangle" : "quad", ") ]] vertex"); + entry_type = join("[[ patch(", is_tessellating_triangles() ? "triangle" : "quad", ") ]] vertex"); else - entry_type = join("[[ patch(", execution.flags.get(ExecutionModeTriangles) ? "triangle" : "quad", ", ", + entry_type = join("[[ patch(", is_tessellating_triangles() ? "triangle" : "quad", ", ", execution.output_vertices, ") ]] vertex"); break; case ExecutionModelFragment: @@ -11183,6 +12663,16 @@ string CompilerMSL::func_type_decl(SPIRType &type) return entry_type + " " + return_type; } +bool CompilerMSL::is_tesc_shader() const +{ + return get_execution_model() == ExecutionModelTessellationControl; +} + +bool CompilerMSL::is_tese_shader() const +{ + return get_execution_model() == ExecutionModelTessellationEvaluation; +} + bool CompilerMSL::uses_explicit_early_fragment_test() { auto &ep_flags = get_entry_point().flags; @@ -11215,6 +12705,7 @@ string CompilerMSL::get_type_address_space(const SPIRType &type, uint32_t id, bo break; case StorageClassStorageBuffer: + case StorageClassPhysicalStorageBuffer: { // For arguments from variable pointers, we use the write count deduction, so // we should not assume any constness here. Only for global SSBOs. @@ -11253,9 +12744,20 @@ string CompilerMSL::get_type_address_space(const SPIRType &type, uint32_t id, bo break; case StorageClassInput: - if (get_execution_model() == ExecutionModelTessellationControl && var && - var->basevariable == stage_in_ptr_var_id) - addr_space = msl_options.multi_patch_workgroup ? "constant" : "threadgroup"; + if (is_tesc_shader() && var && var->basevariable == stage_in_ptr_var_id) + addr_space = msl_options.multi_patch_workgroup ? "const device" : "threadgroup"; + // Don't pass tessellation levels in the device AS; we load and convert them + // to float manually. + if (is_tese_shader() && msl_options.raw_buffer_tese_input && var) + { + bool is_stage_in = var->basevariable == stage_in_ptr_var_id; + bool is_patch_stage_in = has_decoration(var->self, DecorationPatch); + bool is_builtin = has_decoration(var->self, DecorationBuiltIn); + BuiltIn builtin = (BuiltIn)get_decoration(var->self, DecorationBuiltIn); + bool is_tess_level = is_builtin && (builtin == BuiltInTessLevelOuter || builtin == BuiltInTessLevelInner); + if (is_stage_in || (is_patch_stage_in && !is_tess_level)) + addr_space = "const device"; + } if (get_execution_model() == ExecutionModelFragment && var && var->basevariable == stage_in_var_id) addr_space = "thread"; break; @@ -11313,19 +12815,21 @@ const char *CompilerMSL::to_restrict(uint32_t id, bool space) else flags = get_decoration_bitset(id); - return flags.get(DecorationRestrict) ? (space ? "restrict " : "restrict") : ""; + return flags.get(DecorationRestrict) || flags.get(DecorationRestrictPointerEXT) ? + (space ? "__restrict " : "__restrict") : ""; } string CompilerMSL::entry_point_arg_stage_in() { string decl; - if (get_execution_model() == ExecutionModelTessellationControl && msl_options.multi_patch_workgroup) + if ((is_tesc_shader() && msl_options.multi_patch_workgroup) || + (is_tese_shader() && msl_options.raw_buffer_tese_input)) return decl; // Stage-in structure uint32_t stage_in_id; - if (get_execution_model() == ExecutionModelTessellationEvaluation) + if (is_tese_shader()) stage_in_id = patch_stage_in_var_id; else stage_in_id = stage_in_var_id; @@ -11365,7 +12869,7 @@ bool CompilerMSL::is_direct_input_builtin(BuiltIn bi_type) return false; case BuiltInInvocationId: case BuiltInPrimitiveId: - return get_execution_model() != ExecutionModelTessellationControl || !msl_options.multi_patch_workgroup; + return !is_tesc_shader() || !msl_options.multi_patch_workgroup; // Tess. evaluation function in case BuiltInTessLevelInner: case BuiltInTessLevelOuter: @@ -11373,8 +12877,8 @@ bool CompilerMSL::is_direct_input_builtin(BuiltIn bi_type) // Fragment function in case BuiltInSamplePosition: case BuiltInHelperInvocation: - case BuiltInBaryCoordNV: - case BuiltInBaryCoordNoPerspNV: + case BuiltInBaryCoordKHR: + case BuiltInBaryCoordNoPerspKHR: return false; case BuiltInViewIndex: return get_execution_model() == ExecutionModelFragment && msl_options.multiview && @@ -11409,7 +12913,7 @@ bool CompilerMSL::is_sample_rate() const return get_execution_model() == ExecutionModelFragment && (msl_options.force_sample_rate_shading || std::find(caps.begin(), caps.end(), CapabilitySampleRateShading) != caps.end() || - (msl_options.use_framebuffer_fetch_subpasses && need_subpass_input)); + (msl_options.use_framebuffer_fetch_subpasses && need_subpass_input_ms)); } bool CompilerMSL::is_intersection_query() const @@ -11449,8 +12953,14 @@ void CompilerMSL::entry_point_args_builtin(string &ep_args) // Handle HLSL-style 0-based vertex/instance index. builtin_declaration = true; - ep_args += builtin_type_decl(bi_type, var_id) + " " + to_expression(var_id); - ep_args += " [[" + builtin_qualifier(bi_type); + + // Handle different MSL gl_TessCoord types. (float2, float3) + if (bi_type == BuiltInTessCoord && get_entry_point().flags.get(ExecutionModeQuads)) + ep_args += "float2 " + to_expression(var_id) + "In"; + else + ep_args += builtin_type_decl(bi_type, var_id) + " " + to_expression(var_id); + + ep_args += string(" [[") + builtin_qualifier(bi_type); if (bi_type == BuiltInSampleMask && get_entry_point().flags.get(ExecutionModePostDepthCoverage)) { if (!msl_options.supports_msl_version(2)) @@ -11514,7 +13024,7 @@ void CompilerMSL::entry_point_args_builtin(string &ep_args) " [[buffer(", msl_options.shader_output_buffer_index, ")]]"); } - if (get_execution_model() == ExecutionModelTessellationControl) + if (is_tesc_shader()) { if (!ep_args.empty()) ep_args += ", "; @@ -11556,7 +13066,7 @@ void CompilerMSL::entry_point_args_builtin(string &ep_args) // a buffer to hold the per-patch data, a buffer to hold the per-patch // tessellation levels, and a block of workgroup memory to hold the // input control point data. - if (get_execution_model() == ExecutionModelTessellationControl) + if (is_tesc_shader()) { if (patch_stage_out_var_id) { @@ -11590,20 +13100,22 @@ void CompilerMSL::entry_point_args_builtin(string &ep_args) if (outer_factor_initializer_id && (c = maybe_get(outer_factor_initializer_id))) { auto &entry_func = get(ir.default_entry_point); - entry_func.fixup_hooks_in.push_back([=]() { - uint32_t components = get_execution_mode_bitset().get(ExecutionModeTriangles) ? 3 : 4; - for (uint32_t i = 0; i < components; i++) - { - statement(builtin_to_glsl(BuiltInTessLevelOuter, StorageClassOutput), "[", i, "] = ", - "half(", to_expression(c->subconstants[i]), ");"); - } - }); + entry_func.fixup_hooks_in.push_back( + [=]() + { + uint32_t components = is_tessellating_triangles() ? 3 : 4; + for (uint32_t i = 0; i < components; i++) + { + statement(builtin_to_glsl(BuiltInTessLevelOuter, StorageClassOutput), "[", i, + "] = ", "half(", to_expression(c->subconstants[i]), ");"); + } + }); } if (inner_factor_initializer_id && (c = maybe_get(inner_factor_initializer_id))) { auto &entry_func = get(ir.default_entry_point); - if (get_execution_mode_bitset().get(ExecutionModeTriangles)) + if (is_tessellating_triangles()) { entry_func.fixup_hooks_in.push_back([=]() { statement(builtin_to_glsl(BuiltInTessLevelInner, StorageClassOutput), " = ", "half(", @@ -11639,6 +13151,36 @@ void CompilerMSL::entry_point_args_builtin(string &ep_args) } } } + // Tessellation evaluation shaders get three additional parameters: + // a buffer for the per-patch data, a buffer for the per-patch + // tessellation levels, and a buffer for the control point data. + if (is_tese_shader() && msl_options.raw_buffer_tese_input) + { + if (patch_stage_in_var_id) + { + if (!ep_args.empty()) + ep_args += ", "; + ep_args += + join("const device ", type_to_glsl(get_patch_stage_in_struct_type()), "* ", patch_input_buffer_var_name, + " [[buffer(", convert_to_string(msl_options.shader_patch_input_buffer_index), ")]]"); + } + + if (tess_level_inner_var_id || tess_level_outer_var_id) + { + if (!ep_args.empty()) + ep_args += ", "; + ep_args += join("const device ", get_tess_factor_struct_name(), "* ", tess_factor_buffer_var_name, + " [[buffer(", convert_to_string(msl_options.shader_tess_factor_buffer_index), ")]]"); + } + + if (stage_in_var_id) + { + if (!ep_args.empty()) + ep_args += ", "; + ep_args += join("const device ", type_to_glsl(get_stage_in_struct_type()), "* ", input_buffer_var_name, + " [[buffer(", convert_to_string(msl_options.shader_input_buffer_index), ")]]"); + } + } } string CompilerMSL::entry_point_args_argument_buffer(bool append_comma) @@ -11679,7 +13221,7 @@ string CompilerMSL::entry_point_args_argument_buffer(bool append_comma) claimed_bindings.set(buffer_binding); - ep_args += get_argument_address_space(var) + " " + type_to_glsl(type) + "& " + to_restrict(id) + to_name(id); + ep_args += get_argument_address_space(var) + " " + type_to_glsl(type) + "& " + to_restrict(id, true) + to_name(id); ep_args += " [[buffer(" + convert_to_string(buffer_binding) + ")]]"; next_metal_resource_index_buffer = max(next_metal_resource_index_buffer, buffer_binding + 1); @@ -11724,6 +13266,7 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) struct Resource { SPIRVariable *var; + SPIRVariable *descriptor_alias; string name; SPIRType::BaseType basetype; uint32_t index; @@ -11733,6 +13276,7 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) SmallVector resources; + entry_point_bindings.clear(); ir.for_each_typed_id([&](uint32_t var_id, SPIRVariable &var) { if ((var.storage == StorageClassUniform || var.storage == StorageClassUniformConstant || var.storage == StorageClassPushConstant || var.storage == StorageClassStorageBuffer) && @@ -11747,6 +13291,33 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) return; } + // Handle descriptor aliasing. We can handle aliasing of buffers by casting pointers, + // but not for typed resources. + SPIRVariable *descriptor_alias = nullptr; + if (var.storage == StorageClassUniform || var.storage == StorageClassStorageBuffer) + { + for (auto &resource : resources) + { + if (get_decoration(resource.var->self, DecorationDescriptorSet) == + get_decoration(var_id, DecorationDescriptorSet) && + get_decoration(resource.var->self, DecorationBinding) == + get_decoration(var_id, DecorationBinding) && + resource.basetype == SPIRType::Struct && type.basetype == SPIRType::Struct && + (resource.var->storage == StorageClassUniform || + resource.var->storage == StorageClassStorageBuffer)) + { + descriptor_alias = resource.var; + // Self-reference marks that we should declare the resource, + // and it's being used as an alias (so we can emit void* instead). + resource.descriptor_alias = resource.var; + // Need to promote interlocked usage so that the primary declaration is correct. + if (interlocked_resources.count(var_id)) + interlocked_resources.insert(resource.var->self); + break; + } + } + } + const MSLConstexprSampler *constexpr_sampler = nullptr; if (type.basetype == SPIRType::SampledImage || type.basetype == SPIRType::Sampler) { @@ -11760,7 +13331,7 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) // Emulate texture2D atomic operations uint32_t secondary_index = 0; - if (atomic_image_vars.count(var.self)) + if (atomic_image_vars_emulated.count(var.self)) { secondary_index = get_metal_resource_index(var, SPIRType::AtomicCounter, 0); } @@ -11773,13 +13344,14 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) if (constexpr_sampler && constexpr_sampler->ycbcr_conversion_enable) plane_count = constexpr_sampler->planes; + entry_point_bindings.push_back(&var); for (uint32_t i = 0; i < plane_count; i++) - resources.push_back({ &var, to_name(var_id), SPIRType::Image, + resources.push_back({ &var, descriptor_alias, to_name(var_id), SPIRType::Image, get_metal_resource_index(var, SPIRType::Image, i), i, secondary_index }); if (type.image.dim != DimBuffer && !constexpr_sampler) { - resources.push_back({ &var, to_sampler_expression(var_id), SPIRType::Sampler, + resources.push_back({ &var, descriptor_alias, to_sampler_expression(var_id), SPIRType::Sampler, get_metal_resource_index(var, SPIRType::Sampler), 0, 0 }); } } @@ -11787,15 +13359,22 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) { // constexpr samplers are not declared as resources. add_resource_name(var_id); - resources.push_back({ &var, to_name(var_id), type.basetype, - get_metal_resource_index(var, type.basetype), 0, secondary_index }); + + // Don't allocate resource indices for aliases. + uint32_t resource_index = ~0u; + if (!descriptor_alias) + resource_index = get_metal_resource_index(var, type.basetype); + + entry_point_bindings.push_back(&var); + resources.push_back({ &var, descriptor_alias, to_name(var_id), type.basetype, + resource_index, 0, secondary_index }); } } }); - sort(resources.begin(), resources.end(), [](const Resource &lhs, const Resource &rhs) { - return tie(lhs.basetype, lhs.index) < tie(rhs.basetype, rhs.index); - }); + stable_sort(resources.begin(), resources.end(), + [](const Resource &lhs, const Resource &rhs) + { return tie(lhs.basetype, lhs.index) < tie(rhs.basetype, rhs.index); }); for (auto &r : resources) { @@ -11811,41 +13390,86 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) auto &m = ir.meta[type.self]; if (m.members.size() == 0) break; - if (!type.array.empty()) + + if (r.descriptor_alias) { - if (type.array.size() > 1) - SPIRV_CROSS_THROW("Arrays of arrays of buffers are not supported."); + if (r.var == r.descriptor_alias) + { + auto primary_name = join("spvBufferAliasSet", + get_decoration(var_id, DecorationDescriptorSet), + "Binding", + get_decoration(var_id, DecorationBinding)); - // Metal doesn't directly support this, so we must expand the - // array. We'll declare a local array to hold these elements - // later. - uint32_t array_size = to_array_size_literal(type); + // Declare the primary alias as void* + if (!ep_args.empty()) + ep_args += ", "; + ep_args += get_argument_address_space(var) + " void* " + primary_name; + ep_args += " [[buffer(" + convert_to_string(r.index) + ")"; + if (interlocked_resources.count(var_id)) + ep_args += ", raster_order_group(0)"; + ep_args += "]]"; + } - if (array_size == 0) - SPIRV_CROSS_THROW("Unsized arrays of buffers are not supported in MSL."); + buffer_aliases_discrete.push_back(r.var->self); + } + else if (!type.array.empty()) + { + if (type.array.size() > 1) + SPIRV_CROSS_THROW("Arrays of arrays of buffers are not supported."); - // Allow Metal to use the array template to make arrays a value type is_using_builtin_array = true; - buffer_arrays.push_back(var_id); - for (uint32_t i = 0; i < array_size; ++i) + if (is_var_runtime_size_array(var)) { + add_spv_func_and_recompile(SPVFuncImplVariableDescriptorArray); if (!ep_args.empty()) ep_args += ", "; - ep_args += get_argument_address_space(var) + " " + type_to_glsl(type) + "* " + to_restrict(var_id) + - r.name + "_" + convert_to_string(i); - ep_args += " [[buffer(" + convert_to_string(r.index + i) + ")"; + const bool ssbo = has_decoration(type.self, DecorationBufferBlock); + if ((var.storage == spv::StorageClassStorageBuffer || ssbo) && + msl_options.runtime_array_rich_descriptor) + { + add_spv_func_and_recompile(SPVFuncImplVariableSizedDescriptor); + ep_args += "const device spvBufferDescriptor<" + get_argument_address_space(var) + " " + + type_to_glsl(type) + "*>* "; + } + else + { + ep_args += "const device spvDescriptor<" + get_argument_address_space(var) + " " + + type_to_glsl(type) + "*>* "; + } + ep_args += to_restrict(var_id, true) + r.name + "_"; + ep_args += " [[buffer(" + convert_to_string(r.index) + ")"; if (interlocked_resources.count(var_id)) ep_args += ", raster_order_group(0)"; ep_args += "]]"; } + else + { + uint32_t array_size = get_resource_array_size(type, var_id); + for (uint32_t i = 0; i < array_size; ++i) + { + if (!ep_args.empty()) + ep_args += ", "; + ep_args += get_argument_address_space(var) + " " + type_to_glsl(type) + "* " + + to_restrict(var_id, true) + r.name + "_" + convert_to_string(i); + ep_args += " [[buffer(" + convert_to_string(r.index + i) + ")"; + if (interlocked_resources.count(var_id)) + ep_args += ", raster_order_group(0)"; + ep_args += "]]"; + } + } is_using_builtin_array = false; } else { if (!ep_args.empty()) ep_args += ", "; - ep_args += - get_argument_address_space(var) + " " + type_to_glsl(type) + "& " + to_restrict(var_id) + r.name; + ep_args += get_argument_address_space(var) + " "; + + if (recursive_inputs.count(type.self)) + ep_args += string("void* ") + to_restrict(var_id, true) + r.name + "_vp"; + else + ep_args += type_to_glsl(type) + "& " + to_restrict(var_id, true) + r.name; + ep_args += " [[buffer(" + convert_to_string(r.index) + ")"; if (interlocked_resources.count(var_id)) ep_args += ", raster_order_group(0)"; @@ -11857,7 +13481,10 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) if (!ep_args.empty()) ep_args += ", "; ep_args += sampler_type(type, var_id) + " " + r.name; - ep_args += " [[sampler(" + convert_to_string(r.index) + ")]]"; + if (is_var_runtime_size_array(var)) + ep_args += "_ [[buffer(" + convert_to_string(r.index) + ")]]"; + else + ep_args += " [[sampler(" + convert_to_string(r.index) + ")]]"; break; case SPIRType::Image: { @@ -11871,7 +13498,12 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) ep_args += image_type_glsl(type, var_id) + " " + r.name; if (r.plane > 0) ep_args += join(plane_name_suffix, r.plane); - ep_args += " [[texture(" + convert_to_string(r.index) + ")"; + + if (is_var_runtime_size_array(var)) + ep_args += "_ [[buffer(" + convert_to_string(r.index) + ")"; + else + ep_args += " [[texture(" + convert_to_string(r.index) + ")"; + if (interlocked_resources.count(var_id)) ep_args += ", raster_order_group(0)"; ep_args += "]]"; @@ -11885,7 +13517,7 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) } // Emulate texture2D atomic operations - if (atomic_image_vars.count(var.self)) + if (atomic_image_vars_emulated.count(var.self)) { ep_args += ", device atomic_" + type_to_glsl(get(basetype.image.type), 0); ep_args += "* " + r.name + "_atomic"; @@ -11897,9 +13529,26 @@ void CompilerMSL::entry_point_args_discrete_descriptors(string &ep_args) break; } case SPIRType::AccelerationStructure: - ep_args += ", " + type_to_glsl(type, var_id) + " " + r.name; - ep_args += " [[buffer(" + convert_to_string(r.index) + ")]]"; + { + if (is_var_runtime_size_array(var)) + { + add_spv_func_and_recompile(SPVFuncImplVariableDescriptor); + const auto &parent_type = get(type.parent_type); + if (!ep_args.empty()) + ep_args += ", "; + ep_args += "const device spvDescriptor<" + type_to_glsl(parent_type) + ">* " + + to_restrict(var_id, true) + r.name + "_"; + ep_args += " [[buffer(" + convert_to_string(r.index) + ")]]"; + } + else + { + if (!ep_args.empty()) + ep_args += ", "; + ep_args += type_to_glsl(type, var_id) + " " + r.name; + ep_args += " [[buffer(" + convert_to_string(r.index) + ")]]"; + } break; + } default: if (!ep_args.empty()) ep_args += ", "; @@ -11982,29 +13631,44 @@ void CompilerMSL::fix_up_shader_inputs_outputs() else if ((var.storage == StorageClassStorageBuffer || (var.storage == StorageClassUniform && ssbo)) && !is_hidden_variable(var)) { - if (buffers_requiring_array_length.count(var.self)) + if (buffer_requires_array_length(var.self)) { - entry_func.fixup_hooks_in.push_back([this, &type, &var, var_id]() { - bool is_array_type = !type.array.empty(); - - uint32_t desc_set = get_decoration(var_id, DecorationDescriptorSet); - if (descriptor_set_is_argument_buffer(desc_set)) - { - statement("constant uint", is_array_type ? "* " : "& ", to_buffer_size_expression(var_id), - is_array_type ? " = &" : " = ", to_name(argument_buffer_ids[desc_set]), - ".spvBufferSizeConstants", "[", - convert_to_string(get_metal_resource_index(var, SPIRType::Image)), "];"); - } - else - { - // If we have an array of images, we need to be able to index into it, so take a pointer instead. - statement("constant uint", is_array_type ? "* " : "& ", to_buffer_size_expression(var_id), - is_array_type ? " = &" : " = ", to_name(buffer_size_buffer_id), "[", - convert_to_string(get_metal_resource_index(var, type.basetype)), "];"); - } - }); + entry_func.fixup_hooks_in.push_back( + [this, &type, &var, var_id]() + { + bool is_array_type = !type.array.empty() && !is_var_runtime_size_array(var); + + uint32_t desc_set = get_decoration(var_id, DecorationDescriptorSet); + if (descriptor_set_is_argument_buffer(desc_set)) + { + statement("constant uint", is_array_type ? "* " : "& ", to_buffer_size_expression(var_id), + is_array_type ? " = &" : " = ", to_name(argument_buffer_ids[desc_set]), + ".spvBufferSizeConstants", "[", + convert_to_string(get_metal_resource_index(var, SPIRType::Image)), "];"); + } + else + { + // If we have an array of images, we need to be able to index into it, so take a pointer instead. + statement("constant uint", is_array_type ? "* " : "& ", to_buffer_size_expression(var_id), + is_array_type ? " = &" : " = ", to_name(buffer_size_buffer_id), "[", + convert_to_string(get_metal_resource_index(var, type.basetype)), "];"); + } + }); } } + + if (msl_options.replace_recursive_inputs && type_contains_recursion(type) && + (var.storage == StorageClassUniform || var.storage == StorageClassUniformConstant || + var.storage == StorageClassPushConstant || var.storage == StorageClassStorageBuffer)) + { + recursive_inputs.insert(type.self); + entry_func.fixup_hooks_in.push_back([this, &type, &var, var_id]() { + auto addr_space = get_argument_address_space(var); + auto var_name = to_name(var_id); + statement(addr_space, " auto& ", to_restrict(var_id, true), var_name, + " = *(", addr_space, " ", type_to_glsl(type), "*)", var_name, "_vp;"); + }); + } }); // Builtin variables @@ -12036,19 +13700,9 @@ void CompilerMSL::fix_up_shader_inputs_outputs() }); } break; - case BuiltInHelperInvocation: - if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3)) - SPIRV_CROSS_THROW("simd_is_helper_thread() requires version 2.3 on iOS."); - else if (msl_options.is_macos() && !msl_options.supports_msl_version(2, 1)) - SPIRV_CROSS_THROW("simd_is_helper_thread() requires version 2.1 on macOS."); - - entry_func.fixup_hooks_in.push_back([=]() { - statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = simd_is_helper_thread();"); - }); - break; case BuiltInInvocationId: // This is direct-mapped without multi-patch workgroups. - if (get_execution_model() != ExecutionModelTessellationControl || !msl_options.multi_patch_workgroup) + if (!is_tesc_shader() || !msl_options.multi_patch_workgroup) break; entry_func.fixup_hooks_in.push_back([=]() { @@ -12060,7 +13714,7 @@ void CompilerMSL::fix_up_shader_inputs_outputs() case BuiltInPrimitiveId: // This is natively supported by fragment and tessellation evaluation shaders. // In tessellation control shaders, this is direct-mapped without multi-patch workgroups. - if (get_execution_model() != ExecutionModelTessellationControl || !msl_options.multi_patch_workgroup) + if (!is_tesc_shader() || !msl_options.multi_patch_workgroup) break; entry_func.fixup_hooks_in.push_back([=]() { @@ -12070,20 +13724,47 @@ void CompilerMSL::fix_up_shader_inputs_outputs() }); break; case BuiltInPatchVertices: - if (get_execution_model() == ExecutionModelTessellationEvaluation) - entry_func.fixup_hooks_in.push_back([=]() { - statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = ", - to_expression(patch_stage_in_var_id), ".gl_in.size();"); - }); + if (is_tese_shader()) + { + if (msl_options.raw_buffer_tese_input) + { + entry_func.fixup_hooks_in.push_back( + [=]() { + statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = ", + get_entry_point().output_vertices, ";"); + }); + } + else + { + entry_func.fixup_hooks_in.push_back( + [=]() + { + statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = ", + to_expression(patch_stage_in_var_id), ".gl_in.size();"); + }); + } + } else + { entry_func.fixup_hooks_in.push_back([=]() { statement(builtin_type_decl(bi_type), " ", to_expression(var_id), " = spvIndirectParams[0];"); }); + } break; case BuiltInTessCoord: + if (get_entry_point().flags.get(ExecutionModeQuads)) + { + // The entry point will only have a float2 TessCoord variable. + // Pad to float3. + entry_func.fixup_hooks_in.push_back([=]() { + auto name = builtin_to_glsl(BuiltInTessCoord, StorageClassInput); + statement("float3 " + name + " = float3(" + name + "In.x, " + name + "In.y, 0.0);"); + }); + } + // Emit a fixup to account for the shifted domain. Don't do this for triangles; // MoltenVK will just reverse the winding order instead. - if (msl_options.tess_domain_origin_lower_left && !get_entry_point().flags.get(ExecutionModeTriangles)) + if (msl_options.tess_domain_origin_lower_left && !is_tessellating_triangles()) { string tc = to_expression(var_id); entry_func.fixup_hooks_in.push_back([=]() { statement(tc, ".y = 1.0 - ", tc, ".y;"); }); @@ -12577,8 +14258,6 @@ uint32_t CompilerMSL::get_metal_resource_index(SPIRVariable &var, SPIRType::Base for (uint32_t i = 0; i < uint32_t(type.array.size()); i++) binding_stride *= to_array_size_literal(type, i); - assert(binding_stride != 0); - // If a binding has not been specified, revert to incrementing resource indices. uint32_t resource_index; @@ -12590,6 +14269,11 @@ uint32_t CompilerMSL::get_metal_resource_index(SPIRVariable &var, SPIRType::Base } else { + if (is_var_runtime_size_array(var)) + { + basetype = SPIRType::Struct; + binding_stride = 1; + } // Allocate from plain bindings which are allocated per resource type. switch (basetype) { @@ -12636,13 +14320,45 @@ bool CompilerMSL::type_is_pointer_to_pointer(const SPIRType &type) const return type.pointer_depth > parent_type.pointer_depth && type_is_pointer(parent_type); } +const char *CompilerMSL::descriptor_address_space(uint32_t id, StorageClass storage, const char *plain_address_space) const +{ + if (msl_options.argument_buffers) + { + bool storage_class_is_descriptor = storage == StorageClassUniform || + storage == StorageClassStorageBuffer || + storage == StorageClassUniformConstant; + + uint32_t desc_set = get_decoration(id, DecorationDescriptorSet); + if (storage_class_is_descriptor && descriptor_set_is_argument_buffer(desc_set)) + { + // An awkward case where we need to emit *more* address space declarations (yay!). + // An example is where we pass down an array of buffer pointers to leaf functions. + // It's a constant array containing pointers to constants. + // The pointer array is always constant however. E.g. + // device SSBO * constant (&array)[N]. + // const device SSBO * constant (&array)[N]. + // constant SSBO * constant (&array)[N]. + // However, this only matters for argument buffers, since for MSL 1.0 style codegen, + // we emit the buffer array on stack instead, and that seems to work just fine apparently. + + // If the argument was marked as being in device address space, any pointer to member would + // be const device, not constant. + if (argument_buffer_device_storage_mask & (1u << desc_set)) + return "const device"; + else + return "constant"; + } + } + + return plain_address_space; +} + string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) { auto &var = get(arg.id); auto &type = get_variable_data_type(var); auto &var_type = get(arg.type); StorageClass type_storage = var_type.storage; - bool is_pointer = var_type.pointer; // If we need to modify the name of the variable, make sure we use the original variable. // Our alias is just a shadow variable. @@ -12650,19 +14366,19 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) if (arg.alias_global_variable && var.basevariable) name_id = var.basevariable; - bool constref = !arg.alias_global_variable && is_pointer && arg.write_count == 0; + bool constref = !arg.alias_global_variable && is_pointer(var_type) && arg.write_count == 0; // Framebuffer fetch is plain value, const looks out of place, but it is not wrong. if (type_is_msl_framebuffer_fetch(type)) constref = false; + else if (type_storage == StorageClassUniformConstant) + constref = true; bool type_is_image = type.basetype == SPIRType::Image || type.basetype == SPIRType::SampledImage || type.basetype == SPIRType::Sampler; + bool type_is_tlas = type.basetype == SPIRType::AccelerationStructure; - // Arrays of images/samplers in MSL are always const. - if (!type.array.empty() && type_is_image) - constref = true; - - const char *cv_qualifier = constref ? "const " : ""; + // For opaque types we handle const later due to descriptor address spaces. + const char *cv_qualifier = (constref && !type_is_image) ? "const " : ""; string decl; // If this is a combined image-sampler for a 2D image with floating-point type, @@ -12679,9 +14395,6 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) bool builtin = has_decoration(var.self, DecorationBuiltIn); auto builtin_type = BuiltIn(get_decoration(arg.id, DecorationBuiltIn)); - if (address_space == "threadgroup") - is_using_builtin_array = true; - if (var.basevariable && (var.basevariable == stage_in_ptr_var_id || var.basevariable == stage_out_ptr_var_id)) decl = join(cv_qualifier, type_to_glsl(type, arg.id)); else if (builtin) @@ -12710,6 +14423,18 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) else decl = join(cv_qualifier, type_to_glsl(type, arg.id)); } + else if (is_var_runtime_size_array(var)) + { + const auto *parent_type = &get(type.parent_type); + auto type_name = type_to_glsl(*parent_type, arg.id); + if (type.basetype == SPIRType::AccelerationStructure) + decl = join("spvDescriptorArray<", type_name, ">"); + else if (type_is_image) + decl = join("spvDescriptorArray<", cv_qualifier, type_name, ">"); + else + decl = join("spvDescriptorArray<", address_space, " ", type_name, "*>"); + address_space = "const"; + } else if ((type_storage == StorageClassUniform || type_storage == StorageClassStorageBuffer) && is_array(type)) { is_using_builtin_array = true; @@ -12731,12 +14456,12 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) decl += join(" ", cv_qualifier); } else + { decl = join(cv_qualifier, type_to_glsl(type, arg.id)); + } } - bool opaque_handle = type_storage == StorageClassUniformConstant; - - if (!builtin && !opaque_handle && !is_pointer && + if (!builtin && !is_pointer(var_type) && (type_storage == StorageClassFunction || type_storage == StorageClassGeneric)) { // If the argument is a pure value and not an opaque type, we will pass by value. @@ -12751,7 +14476,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) // non-constant arrays, but we can create thread const from constant. decl = string("thread const ") + decl; decl += " (&"; - const char *restrict_kw = to_restrict(name_id); + const char *restrict_kw = to_restrict(name_id, true); if (*restrict_kw) { decl += " "; @@ -12771,37 +14496,19 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) } else if (is_array(type) && !type_is_image) { - // Arrays of images and samplers are special cased. + // Arrays of opaque types are special cased. if (!address_space.empty()) decl = join(address_space, " ", decl); - if (msl_options.argument_buffers) + const char *argument_buffer_space = descriptor_address_space(name_id, type_storage, nullptr); + if (argument_buffer_space) { - uint32_t desc_set = get_decoration(name_id, DecorationDescriptorSet); - if ((type_storage == StorageClassUniform || type_storage == StorageClassStorageBuffer) && - descriptor_set_is_argument_buffer(desc_set)) - { - // An awkward case where we need to emit *more* address space declarations (yay!). - // An example is where we pass down an array of buffer pointers to leaf functions. - // It's a constant array containing pointers to constants. - // The pointer array is always constant however. E.g. - // device SSBO * constant (&array)[N]. - // const device SSBO * constant (&array)[N]. - // constant SSBO * constant (&array)[N]. - // However, this only matters for argument buffers, since for MSL 1.0 style codegen, - // we emit the buffer array on stack instead, and that seems to work just fine apparently. - - // If the argument was marked as being in device address space, any pointer to member would - // be const device, not constant. - if (argument_buffer_device_storage_mask & (1u << desc_set)) - decl += " const device"; - else - decl += " constant"; - } + decl += " "; + decl += argument_buffer_space; } // Special case, need to override the array size here if we're using tess level as an argument. - if (get_execution_model() == ExecutionModelTessellationControl && builtin && + if (is_tesc_shader() && builtin && (builtin_type == BuiltInTessLevelInner || builtin_type == BuiltInTessLevelOuter)) { uint32_t array_size = get_physical_tess_level_array_size(builtin_type); @@ -12818,6 +14525,10 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) decl += join("[", array_size, "]"); } } + else if (is_var_runtime_size_array(var)) + { + decl += " " + to_expression(name_id); + } else { auto array_size_decl = type_to_array_glsl(type); @@ -12826,7 +14537,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) else decl += " (&"; - const char *restrict_kw = to_restrict(name_id); + const char *restrict_kw = to_restrict(name_id, true); if (*restrict_kw) { decl += " "; @@ -12841,7 +14552,8 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) } } } - else if (!opaque_handle && (!pull_model_inputs.count(var.basevariable) || type.basetype == SPIRType::Struct)) + else if (!type_is_image && !type_is_tlas && + (!pull_model_inputs.count(var.basevariable) || type.basetype == SPIRType::Struct)) { // If this is going to be a reference to a variable pointer, the address space // for the reference has to go before the '&', but after the '*'. @@ -12858,9 +14570,34 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) } decl += "&"; decl += " "; - decl += to_restrict(name_id); + decl += to_restrict(name_id, true); decl += to_expression(name_id); } + else if (type_is_image || type_is_tlas) + { + if (is_var_runtime_size_array(var)) + { + decl = address_space + " " + decl + " " + to_expression(name_id); + } + else if (type.array.empty()) + { + // For non-arrayed types we can just pass opaque descriptors by value. + // This fixes problems if descriptors are passed by value from argument buffers and plain descriptors + // in same shader. + // There is no address space we can actually use, but value will work. + // This will break if applications attempt to pass down descriptor arrays as arguments, but + // fortunately that is extremely unlikely ... + decl += " "; + decl += to_expression(name_id); + } + else + { + const char *img_address_space = descriptor_address_space(name_id, type_storage, "thread const"); + decl = join(img_address_space, " ", decl); + decl += "& "; + decl += to_expression(name_id); + } + } else { if (!address_space.empty()) @@ -12871,7 +14608,7 @@ string CompilerMSL::argument_decl(const SPIRFunction::Parameter &arg) // Emulate texture2D atomic operations auto *backing_var = maybe_get_backing_variable(name_id); - if (backing_var && atomic_image_vars.count(backing_var->self)) + if (backing_var && atomic_image_vars_emulated.count(backing_var->self)) { decl += ", device atomic_" + type_to_glsl(get(var_type.image.type), 0); decl += "* " + to_expression(name_id) + "_atomic"; @@ -12895,8 +14632,8 @@ string CompilerMSL::to_name(uint32_t id, bool allow_alias) const return Compiler::to_name(id, allow_alias); } -// Returns a name that combines the name of the struct with the name of the member, except for Builtins -string CompilerMSL::to_qualified_member_name(const SPIRType &type, uint32_t index) +// Appends the name of the member to the variable qualifier string, except for Builtins. +string CompilerMSL::append_member_name(const string &qualifier, const SPIRType &type, uint32_t index) { // Don't qualify Builtin names because they are unique and are treated as such when building expressions BuiltIn builtin = BuiltInMax; @@ -12907,7 +14644,7 @@ string CompilerMSL::to_qualified_member_name(const SPIRType &type, uint32_t inde string mbr_name = to_member_name(type, index); size_t startPos = mbr_name.find_first_not_of("_"); mbr_name = (startPos != string::npos) ? mbr_name.substr(startPos) : ""; - return join(to_name(type.self), "_", mbr_name); + return join(qualifier, "_", mbr_name); } // Ensures that the specified name is permanently usable by prepending a prefix @@ -12924,6 +14661,8 @@ const std::unordered_set &CompilerMSL::get_reserved_keyword_set() "vertex", "fragment", "compute", + "constant", + "device", "bias", "level", "gradient2d", @@ -13050,6 +14789,8 @@ const std::unordered_set &CompilerMSL::get_reserved_keyword_set() "M_SQRT2", "M_SQRT1_2", "quad_broadcast", + "thread", + "threadgroup", }; return keywords; @@ -13063,6 +14804,7 @@ const std::unordered_set &CompilerMSL::get_illegal_func_names() "assert", "fmin3", "fmax3", + "divide", "VARIABLE_TRACEPOINT", "STATIC_DATA_TRACEPOINT", "STATIC_DATA_TRACEPOINT_V", @@ -13251,9 +14993,9 @@ void CompilerMSL::sync_entry_point_aliases_and_names() entry.second.name = ir.meta[entry.first].decoration.alias; } -string CompilerMSL::to_member_reference(uint32_t base, const SPIRType &type, uint32_t index, bool ptr_chain) +string CompilerMSL::to_member_reference(uint32_t base, const SPIRType &type, uint32_t index, bool ptr_chain_is_resolved) { - auto *var = maybe_get(base); + auto *var = maybe_get_backing_variable(base); // If this is a buffer array, we have to dereference the buffer pointers. // Otherwise, if this is a pointer expression, dereference it. @@ -13263,14 +15005,15 @@ string CompilerMSL::to_member_reference(uint32_t base, const SPIRType &type, uin { // Only allow -> dereference for block types. This is so we get expressions like // buffer[i]->first_member.second_member, rather than buffer[i]->first->second. - bool is_block = has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock); + const bool is_block = + has_decoration(type.self, DecorationBlock) || has_decoration(type.self, DecorationBufferBlock); bool is_buffer_variable = is_block && (var->storage == StorageClassUniform || var->storage == StorageClassStorageBuffer); - declared_as_pointer = is_buffer_variable && is_array(get(var->basetype)); + declared_as_pointer = is_buffer_variable && is_array(get_pointee_type(var->basetype)); } - if (declared_as_pointer || (!ptr_chain && should_dereference(base))) + if (declared_as_pointer || (!ptr_chain_is_resolved && should_dereference(base))) return join("->", to_member_name(type, index)); else return join(".", to_member_name(type, index)); @@ -13292,19 +15035,19 @@ string CompilerMSL::to_qualifiers_glsl(uint32_t id) // The optional id parameter indicates the object whose type we are trying // to find the description for. It is optional. Most type descriptions do not // depend on a specific object's use of that type. -string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id) +string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id, bool member) { string type_name; // Pointer? - if (type.pointer) + if (is_pointer(type) || type_is_array_of_pointers(type)) { assert(type.pointer_depth > 0); const char *restrict_kw; auto type_address_space = get_type_address_space(type, id); - auto type_decl = type_to_glsl(get(type.parent_type), id); + const auto *p_parent_type = &get(type.parent_type); // Work around C pointer qualifier rules. If glsl_type is a pointer type as well // we'll need to emit the address space to the right. @@ -13312,9 +15055,26 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id) // Prefer emitting thread T *foo over T thread* foo since it's more readable, // but we'll have to emit thread T * thread * T constant bar; for example. if (type_is_pointer_to_pointer(type)) - type_name = join(type_decl, " ", type_address_space, " "); + type_name = join(type_to_glsl(*p_parent_type, id), " ", type_address_space, " "); else - type_name = join(type_address_space, " ", type_decl); + { + // Since this is not a pointer-to-pointer, ensure we've dug down to the base type. + // Some situations chain pointers even though they are not formally pointers-of-pointers. + while (type_is_pointer(*p_parent_type)) + p_parent_type = &get(p_parent_type->parent_type); + + // If we're emitting BDA, just use the templated type. + // Emitting builtin arrays need a lot of cooperation with other code to ensure + // the C-style nesting works right. + // FIXME: This is somewhat of a hack. + bool old_is_using_builtin_array = is_using_builtin_array; + if (is_physical_pointer(type)) + is_using_builtin_array = false; + + type_name = join(type_address_space, " ", type_to_glsl(*p_parent_type, id)); + + is_using_builtin_array = old_is_using_builtin_array; + } switch (type.basetype) { @@ -13326,7 +15086,7 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id) default: // Anything else can be a raw pointer. type_name += "*"; - restrict_kw = to_restrict(id); + restrict_kw = to_restrict(id, false); if (*restrict_kw) { type_name += " "; @@ -13375,9 +15135,7 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id) // Need to special-case threadgroup booleans. They are supposed to be logical // storage, but MSL compilers will sometimes crash if you use threadgroup bool. // Workaround this by using 16-bit types instead and fixup on load-store to this data. - // FIXME: We have no sane way of working around this problem if a struct member is boolean - // and that struct is used as a threadgroup variable, but ... sigh. - if ((var && var->storage == StorageClassWorkgroup) || type.storage == StorageClassWorkgroup) + if ((var && var->storage == StorageClassWorkgroup) || type.storage == StorageClassWorkgroup || member) type_name = "short"; else type_name = "bool"; @@ -13424,14 +15182,14 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id) break; case SPIRType::AccelerationStructure: if (msl_options.supports_msl_version(2, 4)) - type_name = "acceleration_structure"; + type_name = "raytracing::acceleration_structure"; else if (msl_options.supports_msl_version(2, 3)) - type_name = "instance_acceleration_structure"; + type_name = "raytracing::instance_acceleration_structure"; else SPIRV_CROSS_THROW("Acceleration Structure Type is supported in MSL 2.3 and above."); break; case SPIRType::RayQuery: - return "intersection_query"; + return "raytracing::intersection_query"; default: return "unknown_type"; @@ -13439,7 +15197,24 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id) // Matrix? if (type.columns > 1) + { + auto *var = maybe_get_backing_variable(id); + if (var && var->basevariable) + var = &get(var->basevariable); + + // Need to special-case threadgroup matrices. Due to an oversight, Metal's + // matrix struct prior to Metal 3 lacks constructors in the threadgroup AS, + // preventing us from default-constructing or initializing matrices in threadgroup storage. + // Work around this by using our own type as storage. + if (((var && var->storage == StorageClassWorkgroup) || type.storage == StorageClassWorkgroup) && + !msl_options.supports_msl_version(3, 0)) + { + add_spv_func_and_recompile(SPVFuncImplStorageMatrix); + type_name = "spvStorage_" + type_name; + } + type_name += to_string(type.columns) + "x"; + } // Vector or Matrix? if (type.vecsize > 1) @@ -13469,6 +15244,11 @@ string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id) } } +string CompilerMSL::type_to_glsl(const SPIRType &type, uint32_t id) +{ + return type_to_glsl(type, id, false); +} + string CompilerMSL::type_to_array_glsl(const SPIRType &type) { // Allow Metal to use the array template to make arrays a value type @@ -13477,17 +15257,14 @@ string CompilerMSL::type_to_array_glsl(const SPIRType &type) case SPIRType::AtomicCounter: case SPIRType::ControlPointArray: case SPIRType::RayQuery: - { return CompilerGLSL::type_to_array_glsl(type); - } + default: - { - if (using_builtin_array()) + if (type_is_array_of_pointers(type) || using_builtin_array()) return CompilerGLSL::type_to_array_glsl(type); else return ""; } - } } string CompilerMSL::constant_op_expression(const SPIRConstantOp &cop) @@ -13509,23 +15286,25 @@ bool CompilerMSL::variable_decl_is_remapped_storage(const SPIRVariable &variable if (storage == StorageClassWorkgroup) { - auto model = get_execution_model(); - // Specially masked IO block variable. // Normally, we will never access IO blocks directly here. // The only scenario which that should occur is with a masked IO block. - if (model == ExecutionModelTessellationControl && variable.storage == StorageClassOutput && + if (is_tesc_shader() && variable.storage == StorageClassOutput && has_decoration(get(variable.basetype).self, DecorationBlock)) { return true; } - return variable.storage == StorageClassOutput && - model == ExecutionModelTessellationControl && - is_stage_output_variable_masked(variable); + return variable.storage == StorageClassOutput && is_tesc_shader() && is_stage_output_variable_masked(variable); } else if (storage == StorageClassStorageBuffer) { + // These builtins are passed directly; we don't want to use remapping + // for them. + auto builtin = (BuiltIn)get_decoration(variable.self, DecorationBuiltIn); + if (is_tese_shader() && is_builtin_variable(variable) && (builtin == BuiltInTessCoord || builtin == BuiltInPrimitiveId)) + return false; + // We won't be able to catch writes to control point outputs here since variable // refers to a function local pointer. // This is fine, as there cannot be concurrent writers to that memory anyways, @@ -13541,19 +15320,6 @@ bool CompilerMSL::variable_decl_is_remapped_storage(const SPIRVariable &variable } } -std::string CompilerMSL::variable_decl(const SPIRVariable &variable) -{ - bool old_is_using_builtin_array = is_using_builtin_array; - - // Threadgroup arrays can't have a wrapper type. - if (variable_decl_is_remapped_storage(variable, StorageClassWorkgroup)) - is_using_builtin_array = true; - - std::string expr = CompilerGLSL::variable_decl(variable); - is_using_builtin_array = old_is_using_builtin_array; - return expr; -} - // GCC workaround of lambdas calling protected funcs std::string CompilerMSL::variable_decl(const SPIRType &type, const std::string &name, uint32_t id) { @@ -13579,12 +15345,16 @@ std::string CompilerMSL::sampler_type(const SPIRType &type, uint32_t id) // Arrays of samplers in MSL must be declared with a special array syntax ala C++11 std::array. // If we have a runtime array, it could be a variable-count descriptor set binding. - uint32_t array_size = to_array_size_literal(type); - if (array_size == 0) - array_size = get_resource_array_size(id); - + uint32_t array_size = get_resource_array_size(type, id); if (array_size == 0) - SPIRV_CROSS_THROW("Unsized array of samplers is not supported in MSL."); + { + add_spv_func_and_recompile(SPVFuncImplVariableDescriptor); + add_spv_func_and_recompile(SPVFuncImplVariableDescriptorArray); + auto &parent = get(get_pointee_type(type).parent_type); + if (processing_entry_point) + return join("const device spvDescriptor<", sampler_type(parent, id), ">*"); + return join("const spvDescriptorArray<", sampler_type(parent, id), ">"); + } auto &parent = get(get_pointee_type(type).parent_type); return join("array<", sampler_type(parent, id), ", ", array_size, ">"); @@ -13625,12 +15395,14 @@ string CompilerMSL::image_type_glsl(const SPIRType &type, uint32_t id) // Arrays of images in MSL must be declared with a special array syntax ala C++11 std::array. // If we have a runtime array, it could be a variable-count descriptor set binding. - uint32_t array_size = to_array_size_literal(type); - if (array_size == 0) - array_size = get_resource_array_size(id); - + uint32_t array_size = get_resource_array_size(type, id); if (array_size == 0) - SPIRV_CROSS_THROW("Unsized array of images is not supported in MSL."); + { + add_spv_func_and_recompile(SPVFuncImplVariableDescriptor); + add_spv_func_and_recompile(SPVFuncImplVariableDescriptorArray); + auto &parent = get(get_pointee_type(type).parent_type); + return join("const device spvDescriptor<", image_type_glsl(parent, id), ">*"); + } auto &parent = get(get_pointee_type(type).parent_type); return join("array<", image_type_glsl(parent, id), ", ", array_size, ">"); @@ -13846,6 +15618,10 @@ void CompilerMSL::emit_subgroup_op(const Instruction &i) case OpGroupNonUniformBallotFindLSB: case OpGroupNonUniformBallotFindMSB: case OpGroupNonUniformBallotBitCount: + case OpSubgroupBallotKHR: + case OpSubgroupAllKHR: + case OpSubgroupAnyKHR: + case OpSubgroupAllEqualKHR: if (!msl_options.supports_msl_version(2, 2)) SPIRV_CROSS_THROW("Ballot ops on iOS requires Metal 2.2 and up."); break; @@ -13856,6 +15632,7 @@ void CompilerMSL::emit_subgroup_op(const Instruction &i) case OpGroupNonUniformShuffleDown: case OpGroupNonUniformQuadSwap: case OpGroupNonUniformQuadBroadcast: + case OpSubgroupReadInvocationKHR: break; } } @@ -13871,68 +15648,88 @@ void CompilerMSL::emit_subgroup_op(const Instruction &i) case OpGroupNonUniformShuffleXor: case OpGroupNonUniformShuffleUp: case OpGroupNonUniformShuffleDown: + case OpSubgroupReadInvocationKHR: break; } } - uint32_t result_type = ops[0]; - uint32_t id = ops[1]; + uint32_t op_idx = 0; + uint32_t result_type = ops[op_idx++]; + uint32_t id = ops[op_idx++]; - auto scope = static_cast(evaluate_constant_u32(ops[2])); + Scope scope; + switch (op) + { + case OpSubgroupBallotKHR: + case OpSubgroupFirstInvocationKHR: + case OpSubgroupReadInvocationKHR: + case OpSubgroupAllKHR: + case OpSubgroupAnyKHR: + case OpSubgroupAllEqualKHR: + // These earlier instructions don't have the scope operand. + scope = ScopeSubgroup; + break; + default: + scope = static_cast(evaluate_constant_u32(ops[op_idx++])); + break; + } if (scope != ScopeSubgroup) SPIRV_CROSS_THROW("Only subgroup scope is supported."); switch (op) { case OpGroupNonUniformElect: - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) + if (msl_options.use_quadgroup_operation()) emit_op(result_type, id, "quad_is_first()", false); else emit_op(result_type, id, "simd_is_first()", false); break; case OpGroupNonUniformBroadcast: - emit_binary_func_op(result_type, id, ops[3], ops[4], "spvSubgroupBroadcast"); + case OpSubgroupReadInvocationKHR: + emit_binary_func_op(result_type, id, ops[op_idx], ops[op_idx + 1], "spvSubgroupBroadcast"); break; case OpGroupNonUniformBroadcastFirst: - emit_unary_func_op(result_type, id, ops[3], "spvSubgroupBroadcastFirst"); + case OpSubgroupFirstInvocationKHR: + emit_unary_func_op(result_type, id, ops[op_idx], "spvSubgroupBroadcastFirst"); break; case OpGroupNonUniformBallot: - emit_unary_func_op(result_type, id, ops[3], "spvSubgroupBallot"); + case OpSubgroupBallotKHR: + emit_unary_func_op(result_type, id, ops[op_idx], "spvSubgroupBallot"); break; case OpGroupNonUniformInverseBallot: - emit_binary_func_op(result_type, id, ops[3], builtin_subgroup_invocation_id_id, "spvSubgroupBallotBitExtract"); + emit_binary_func_op(result_type, id, ops[op_idx], builtin_subgroup_invocation_id_id, "spvSubgroupBallotBitExtract"); break; case OpGroupNonUniformBallotBitExtract: - emit_binary_func_op(result_type, id, ops[3], ops[4], "spvSubgroupBallotBitExtract"); + emit_binary_func_op(result_type, id, ops[op_idx], ops[op_idx + 1], "spvSubgroupBallotBitExtract"); break; case OpGroupNonUniformBallotFindLSB: - emit_binary_func_op(result_type, id, ops[3], builtin_subgroup_size_id, "spvSubgroupBallotFindLSB"); + emit_binary_func_op(result_type, id, ops[op_idx], builtin_subgroup_size_id, "spvSubgroupBallotFindLSB"); break; case OpGroupNonUniformBallotFindMSB: - emit_binary_func_op(result_type, id, ops[3], builtin_subgroup_size_id, "spvSubgroupBallotFindMSB"); + emit_binary_func_op(result_type, id, ops[op_idx], builtin_subgroup_size_id, "spvSubgroupBallotFindMSB"); break; case OpGroupNonUniformBallotBitCount: { - auto operation = static_cast(ops[3]); + auto operation = static_cast(ops[op_idx++]); switch (operation) { case GroupOperationReduce: - emit_binary_func_op(result_type, id, ops[4], builtin_subgroup_size_id, "spvSubgroupBallotBitCount"); + emit_binary_func_op(result_type, id, ops[op_idx], builtin_subgroup_size_id, "spvSubgroupBallotBitCount"); break; case GroupOperationInclusiveScan: - emit_binary_func_op(result_type, id, ops[4], builtin_subgroup_invocation_id_id, + emit_binary_func_op(result_type, id, ops[op_idx], builtin_subgroup_invocation_id_id, "spvSubgroupBallotInclusiveBitCount"); break; case GroupOperationExclusiveScan: - emit_binary_func_op(result_type, id, ops[4], builtin_subgroup_invocation_id_id, + emit_binary_func_op(result_type, id, ops[op_idx], builtin_subgroup_invocation_id_id, "spvSubgroupBallotExclusiveBitCount"); break; default: @@ -13942,57 +15739,60 @@ void CompilerMSL::emit_subgroup_op(const Instruction &i) } case OpGroupNonUniformShuffle: - emit_binary_func_op(result_type, id, ops[3], ops[4], "spvSubgroupShuffle"); + emit_binary_func_op(result_type, id, ops[op_idx], ops[op_idx + 1], "spvSubgroupShuffle"); break; case OpGroupNonUniformShuffleXor: - emit_binary_func_op(result_type, id, ops[3], ops[4], "spvSubgroupShuffleXor"); + emit_binary_func_op(result_type, id, ops[op_idx], ops[op_idx + 1], "spvSubgroupShuffleXor"); break; case OpGroupNonUniformShuffleUp: - emit_binary_func_op(result_type, id, ops[3], ops[4], "spvSubgroupShuffleUp"); + emit_binary_func_op(result_type, id, ops[op_idx], ops[op_idx + 1], "spvSubgroupShuffleUp"); break; case OpGroupNonUniformShuffleDown: - emit_binary_func_op(result_type, id, ops[3], ops[4], "spvSubgroupShuffleDown"); + emit_binary_func_op(result_type, id, ops[op_idx], ops[op_idx + 1], "spvSubgroupShuffleDown"); break; case OpGroupNonUniformAll: - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) - emit_unary_func_op(result_type, id, ops[3], "quad_all"); + case OpSubgroupAllKHR: + if (msl_options.use_quadgroup_operation()) + emit_unary_func_op(result_type, id, ops[op_idx], "quad_all"); else - emit_unary_func_op(result_type, id, ops[3], "simd_all"); + emit_unary_func_op(result_type, id, ops[op_idx], "simd_all"); break; case OpGroupNonUniformAny: - if (msl_options.is_ios() && !msl_options.ios_use_simdgroup_functions) - emit_unary_func_op(result_type, id, ops[3], "quad_any"); + case OpSubgroupAnyKHR: + if (msl_options.use_quadgroup_operation()) + emit_unary_func_op(result_type, id, ops[op_idx], "quad_any"); else - emit_unary_func_op(result_type, id, ops[3], "simd_any"); + emit_unary_func_op(result_type, id, ops[op_idx], "simd_any"); break; case OpGroupNonUniformAllEqual: - emit_unary_func_op(result_type, id, ops[3], "spvSubgroupAllEqual"); + case OpSubgroupAllEqualKHR: + emit_unary_func_op(result_type, id, ops[op_idx], "spvSubgroupAllEqual"); break; // clang-format off #define MSL_GROUP_OP(op, msl_op) \ case OpGroupNonUniform##op: \ { \ - auto operation = static_cast(ops[3]); \ + auto operation = static_cast(ops[op_idx++]); \ if (operation == GroupOperationReduce) \ - emit_unary_func_op(result_type, id, ops[4], "simd_" #msl_op); \ + emit_unary_func_op(result_type, id, ops[op_idx], "simd_" #msl_op); \ else if (operation == GroupOperationInclusiveScan) \ - emit_unary_func_op(result_type, id, ops[4], "simd_prefix_inclusive_" #msl_op); \ + emit_unary_func_op(result_type, id, ops[op_idx], "simd_prefix_inclusive_" #msl_op); \ else if (operation == GroupOperationExclusiveScan) \ - emit_unary_func_op(result_type, id, ops[4], "simd_prefix_exclusive_" #msl_op); \ + emit_unary_func_op(result_type, id, ops[op_idx], "simd_prefix_exclusive_" #msl_op); \ else if (operation == GroupOperationClusteredReduce) \ { \ /* Only cluster sizes of 4 are supported. */ \ - uint32_t cluster_size = evaluate_constant_u32(ops[5]); \ + uint32_t cluster_size = evaluate_constant_u32(ops[op_idx + 1]); \ if (cluster_size != 4) \ SPIRV_CROSS_THROW("Metal only supports quad ClusteredReduce."); \ - emit_unary_func_op(result_type, id, ops[4], "quad_" #msl_op); \ + emit_unary_func_op(result_type, id, ops[op_idx], "quad_" #msl_op); \ } \ else \ SPIRV_CROSS_THROW("Invalid group operation."); \ @@ -14008,9 +15808,9 @@ case OpGroupNonUniform##op: \ #define MSL_GROUP_OP(op, msl_op) \ case OpGroupNonUniform##op: \ { \ - auto operation = static_cast(ops[3]); \ + auto operation = static_cast(ops[op_idx++]); \ if (operation == GroupOperationReduce) \ - emit_unary_func_op(result_type, id, ops[4], "simd_" #msl_op); \ + emit_unary_func_op(result_type, id, ops[op_idx], "simd_" #msl_op); \ else if (operation == GroupOperationInclusiveScan) \ SPIRV_CROSS_THROW("Metal doesn't support InclusiveScan for OpGroupNonUniform" #op "."); \ else if (operation == GroupOperationExclusiveScan) \ @@ -14018,10 +15818,10 @@ case OpGroupNonUniform##op: \ else if (operation == GroupOperationClusteredReduce) \ { \ /* Only cluster sizes of 4 are supported. */ \ - uint32_t cluster_size = evaluate_constant_u32(ops[5]); \ + uint32_t cluster_size = evaluate_constant_u32(ops[op_idx + 1]); \ if (cluster_size != 4) \ SPIRV_CROSS_THROW("Metal only supports quad ClusteredReduce."); \ - emit_unary_func_op(result_type, id, ops[4], "quad_" #msl_op); \ + emit_unary_func_op(result_type, id, ops[op_idx], "quad_" #msl_op); \ } \ else \ SPIRV_CROSS_THROW("Invalid group operation."); \ @@ -14031,9 +15831,9 @@ case OpGroupNonUniform##op: \ #define MSL_GROUP_OP_CAST(op, msl_op, type) \ case OpGroupNonUniform##op: \ { \ - auto operation = static_cast(ops[3]); \ + auto operation = static_cast(ops[op_idx++]); \ if (operation == GroupOperationReduce) \ - emit_unary_func_op_cast(result_type, id, ops[4], "simd_" #msl_op, type, type); \ + emit_unary_func_op_cast(result_type, id, ops[op_idx], "simd_" #msl_op, type, type); \ else if (operation == GroupOperationInclusiveScan) \ SPIRV_CROSS_THROW("Metal doesn't support InclusiveScan for OpGroupNonUniform" #op "."); \ else if (operation == GroupOperationExclusiveScan) \ @@ -14041,10 +15841,10 @@ case OpGroupNonUniform##op: \ else if (operation == GroupOperationClusteredReduce) \ { \ /* Only cluster sizes of 4 are supported. */ \ - uint32_t cluster_size = evaluate_constant_u32(ops[5]); \ + uint32_t cluster_size = evaluate_constant_u32(ops[op_idx + 1]); \ if (cluster_size != 4) \ SPIRV_CROSS_THROW("Metal only supports quad ClusteredReduce."); \ - emit_unary_func_op_cast(result_type, id, ops[4], "quad_" #msl_op, type, type); \ + emit_unary_func_op_cast(result_type, id, ops[op_idx], "quad_" #msl_op, type, type); \ } \ else \ SPIRV_CROSS_THROW("Invalid group operation."); \ @@ -14068,11 +15868,11 @@ case OpGroupNonUniform##op: \ #undef MSL_GROUP_OP_CAST case OpGroupNonUniformQuadSwap: - emit_binary_func_op(result_type, id, ops[3], ops[4], "spvQuadSwap"); + emit_binary_func_op(result_type, id, ops[op_idx], ops[op_idx + 1], "spvQuadSwap"); break; case OpGroupNonUniformQuadBroadcast: - emit_binary_func_op(result_type, id, ops[3], ops[4], "spvQuadBroadcast"); + emit_binary_func_op(result_type, id, ops[op_idx], ops[op_idx + 1], "spvQuadBroadcast"); break; default: @@ -14099,17 +15899,14 @@ string CompilerMSL::bitcast_glsl_op(const SPIRType &out_type, const SPIRType &in // size (eg. short shift right becomes int), which means chaining integer ops // together may introduce size variations that SPIR-V doesn't know about. if (same_size_cast && !integral_cast) - { return "as_type<" + type_to_glsl(out_type) + ">"; - } else - { return type_to_glsl(out_type); - } } bool CompilerMSL::emit_complex_bitcast(uint32_t, uint32_t, uint32_t) { + // This is handled from the outside where we deal with PtrToU/UToPtr and friends. return false; } @@ -14248,7 +16045,7 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) case BuiltInClipDistance: case BuiltInCullDistance: case BuiltInLayer: - if (get_execution_model() == ExecutionModelTessellationControl) + if (is_tesc_shader()) break; if (storage != StorageClassInput && current_function && (current_function->self == ir.default_entry_point) && !is_stage_output_builtin_masked(builtin)) @@ -14273,15 +16070,15 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) return stage_out_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage); break; - case BuiltInBaryCoordNV: - case BuiltInBaryCoordNoPerspNV: + case BuiltInBaryCoordKHR: + case BuiltInBaryCoordNoPerspKHR: if (storage == StorageClassInput && current_function && (current_function->self == ir.default_entry_point)) return stage_in_var_name + "." + CompilerGLSL::builtin_to_glsl(builtin, storage); break; case BuiltInTessLevelOuter: - if (get_execution_model() == ExecutionModelTessellationControl && - storage != StorageClassInput && current_function && (current_function->self == ir.default_entry_point)) + if (is_tesc_shader() && storage != StorageClassInput && current_function && + (current_function->self == ir.default_entry_point)) { return join(tess_factor_buffer_var_name, "[", to_expression(builtin_primitive_id_id), "].edgeTessellationFactor"); @@ -14289,14 +16086,24 @@ string CompilerMSL::builtin_to_glsl(BuiltIn builtin, StorageClass storage) break; case BuiltInTessLevelInner: - if (get_execution_model() == ExecutionModelTessellationControl && - storage != StorageClassInput && current_function && (current_function->self == ir.default_entry_point)) + if (is_tesc_shader() && storage != StorageClassInput && current_function && + (current_function->self == ir.default_entry_point)) { return join(tess_factor_buffer_var_name, "[", to_expression(builtin_primitive_id_id), "].insideTessellationFactor"); } break; + case BuiltInHelperInvocation: + if (needs_manual_helper_invocation_updates()) + break; + if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3)) + SPIRV_CROSS_THROW("simd_is_helper_thread() requires version 2.3 on iOS."); + else if (msl_options.is_macos() && !msl_options.supports_msl_version(2, 1)) + SPIRV_CROSS_THROW("simd_is_helper_thread() requires version 2.1 on macOS."); + // In SPIR-V 1.6 with Volatile HelperInvocation, we cannot emit a fixup early. + return "simd_is_helper_thread()"; + default: break; } @@ -14463,7 +16270,7 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin) SPIRV_CROSS_THROW("NumSubgroups is handled specially with emulation."); if (!msl_options.supports_msl_version(2)) SPIRV_CROSS_THROW("Subgroup builtins require Metal 2.0."); - return msl_options.is_ios() ? "quadgroups_per_threadgroup" : "simdgroups_per_threadgroup"; + return msl_options.use_quadgroup_operation() ? "quadgroups_per_threadgroup" : "simdgroups_per_threadgroup"; case BuiltInSubgroupId: if (msl_options.emulate_subgroups) @@ -14471,7 +16278,7 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin) SPIRV_CROSS_THROW("SubgroupId is handled specially with emulation."); if (!msl_options.supports_msl_version(2)) SPIRV_CROSS_THROW("Subgroup builtins require Metal 2.0."); - return msl_options.is_ios() ? "quadgroup_index_in_threadgroup" : "simdgroup_index_in_threadgroup"; + return msl_options.use_quadgroup_operation() ? "quadgroup_index_in_threadgroup" : "simdgroup_index_in_threadgroup"; case BuiltInSubgroupLocalInvocationId: if (msl_options.emulate_subgroups) @@ -14490,7 +16297,7 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin) // We are generating a Metal kernel function. if (!msl_options.supports_msl_version(2)) SPIRV_CROSS_THROW("Subgroup builtins in kernel functions require Metal 2.0."); - return msl_options.is_ios() ? "thread_index_in_quadgroup" : "thread_index_in_simdgroup"; + return msl_options.use_quadgroup_operation() ? "thread_index_in_quadgroup" : "thread_index_in_simdgroup"; } else SPIRV_CROSS_THROW("Subgroup builtins are not available in this type of function."); @@ -14503,16 +16310,14 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin) // Shouldn't be reached. SPIRV_CROSS_THROW("Subgroup ballot masks are handled specially in MSL."); - case BuiltInBaryCoordNV: - // TODO: AMD barycentrics as well? Seem to have different swizzle and 2 components rather than 3. + case BuiltInBaryCoordKHR: if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3)) SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.3 and above on iOS."); else if (!msl_options.supports_msl_version(2, 2)) SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.2 and above on macOS."); return "barycentric_coord, center_perspective"; - case BuiltInBaryCoordNoPerspNV: - // TODO: AMD barycentrics as well? Seem to have different swizzle and 2 components rather than 3. + case BuiltInBaryCoordNoPerspKHR: if (msl_options.is_ios() && !msl_options.supports_msl_version(2, 3)) SPIRV_CROSS_THROW("Barycentrics are only supported in MSL 2.3 and above on iOS."); else if (!msl_options.supports_msl_version(2, 2)) @@ -14527,7 +16332,6 @@ string CompilerMSL::builtin_qualifier(BuiltIn builtin) // Returns an MSL string type declaration for a SPIR-V builtin string CompilerMSL::builtin_type_decl(BuiltIn builtin, uint32_t id) { - const SPIREntryPoint &execution = get_entry_point(); switch (builtin) { // Vertex function in @@ -14571,17 +16375,17 @@ string CompilerMSL::builtin_type_decl(BuiltIn builtin, uint32_t id) // Tess. control function out case BuiltInTessLevelInner: - if (execution.model == ExecutionModelTessellationEvaluation) - return !execution.flags.get(ExecutionModeTriangles) ? "float2" : "float"; + if (is_tese_shader()) + return (msl_options.raw_buffer_tese_input || is_tessellating_triangles()) ? "float" : "float2"; return "half"; case BuiltInTessLevelOuter: - if (execution.model == ExecutionModelTessellationEvaluation) - return !execution.flags.get(ExecutionModeTriangles) ? "float4" : "float"; + if (is_tese_shader()) + return (msl_options.raw_buffer_tese_input || is_tessellating_triangles()) ? "float" : "float4"; return "half"; // Tess. evaluation function in case BuiltInTessCoord: - return execution.flags.get(ExecutionModeTriangles) ? "float3" : "float2"; + return "float3"; // Fragment function in case BuiltInFrontFacing: @@ -14602,8 +16406,8 @@ string CompilerMSL::builtin_type_decl(BuiltIn builtin, uint32_t id) case BuiltInHelperInvocation: return "bool"; - case BuiltInBaryCoordNV: - case BuiltInBaryCoordNoPerspNV: + case BuiltInBaryCoordKHR: + case BuiltInBaryCoordNoPerspKHR: // Use the type as declared, can be 1, 2 or 3 components. return type_to_glsl(get_variable_data_type(get(id))); @@ -14651,8 +16455,8 @@ string CompilerMSL::built_in_func_arg(BuiltIn builtin, bool prefix_comma) // Handle HLSL-style 0-based vertex/instance index. builtin_declaration = true; bi_arg += builtin_type_decl(builtin); - bi_arg += " " + builtin_to_glsl(builtin, StorageClassInput); - bi_arg += " [[" + builtin_qualifier(builtin) + "]]"; + bi_arg += string(" ") + builtin_to_glsl(builtin, StorageClassInput); + bi_arg += string(" [[") + builtin_qualifier(builtin) + string("]]"); builtin_declaration = false; return bi_arg; @@ -14700,7 +16504,7 @@ uint32_t CompilerMSL::get_declared_type_array_stride_msl(const SPIRType &type, b for (uint32_t dim = 0; dim < dimensions; dim++) { uint32_t array_size = to_array_size_literal(type, dim); - value_size *= max(array_size, 1u); + value_size *= max(array_size, 1u); } return value_size; @@ -14777,6 +16581,25 @@ uint32_t CompilerMSL::get_declared_struct_size_msl(const SPIRType &struct_type, // Returns the byte size of a struct member. uint32_t CompilerMSL::get_declared_type_size_msl(const SPIRType &type, bool is_packed, bool row_major) const { + // Pointers take 8 bytes each + if (type.pointer && type.storage == StorageClassPhysicalStorageBuffer) + { + uint32_t type_size = 8 * (type.vecsize == 3 ? 4 : type.vecsize); + + // Work our way through potentially layered arrays, + // stopping when we hit a pointer that is not also an array. + int32_t dim_idx = (int32_t)type.array.size() - 1; + auto *p_type = &type; + while (!type_is_pointer(*p_type) && dim_idx >= 0) + { + type_size *= to_array_size_literal(*p_type, dim_idx); + p_type = &get(p_type->parent_type); + dim_idx--; + } + + return type_size; + } + switch (type.basetype) { case SPIRType::Unknown: @@ -14792,7 +16615,7 @@ uint32_t CompilerMSL::get_declared_type_size_msl(const SPIRType &type, bool is_p if (!type.array.empty()) { uint32_t array_size = to_array_size_literal(type); - return get_declared_type_array_stride_msl(type, is_packed, row_major) * max(array_size, 1u); + return get_declared_type_array_stride_msl(type, is_packed, row_major) * max(array_size, 1u); } if (type.basetype == SPIRType::Struct) @@ -14836,6 +16659,10 @@ uint32_t CompilerMSL::get_declared_input_size_msl(const SPIRType &type, uint32_t // Returns the byte alignment of a type. uint32_t CompilerMSL::get_declared_type_alignment_msl(const SPIRType &type, bool is_packed, bool row_major) const { + // Pointers aligns on multiples of 8 bytes + if (type.pointer && type.storage == StorageClassPhysicalStorageBuffer) + return 8 * (type.vecsize == 3 ? 4 : type.vecsize); + switch (type.basetype) { case SPIRType::Unknown: @@ -14983,17 +16810,23 @@ bool CompilerMSL::OpCodePreprocessor::handle(Op opcode, const uint32_t *args, ui suppress_missing_prototypes = true; break; + case OpDemoteToHelperInvocationEXT: + uses_discard = true; + break; + // Emulate texture2D atomic operations case OpImageTexelPointer: { - auto *var = compiler.maybe_get_backing_variable(args[2]); - image_pointers[args[1]] = var ? var->self : ID(0); + if (!compiler.msl_options.supports_msl_version(3, 1)) + { + auto *var = compiler.maybe_get_backing_variable(args[2]); + image_pointers_emulated[args[1]] = var ? var->self : ID(0); + } break; } case OpImageWrite: - if (!compiler.msl_options.supports_msl_version(2, 2)) - uses_resource_write = true; + uses_image_write = true; break; case OpStore: @@ -15007,6 +16840,7 @@ bool CompilerMSL::OpCodePreprocessor::handle(Op opcode, const uint32_t *args, ui case OpAtomicIIncrement: case OpAtomicIDecrement: case OpAtomicIAdd: + case OpAtomicFAddEXT: case OpAtomicISub: case OpAtomicSMin: case OpAtomicUMin: @@ -15017,34 +16851,38 @@ bool CompilerMSL::OpCodePreprocessor::handle(Op opcode, const uint32_t *args, ui case OpAtomicXor: { uses_atomics = true; - auto it = image_pointers.find(args[2]); - if (it != image_pointers.end()) + auto it = image_pointers_emulated.find(args[2]); + if (it != image_pointers_emulated.end()) { - compiler.atomic_image_vars.insert(it->second); + uses_image_write = true; + compiler.atomic_image_vars_emulated.insert(it->second); } - check_resource_write(args[2]); + else + check_resource_write(args[2]); break; } case OpAtomicStore: { uses_atomics = true; - auto it = image_pointers.find(args[0]); - if (it != image_pointers.end()) + auto it = image_pointers_emulated.find(args[0]); + if (it != image_pointers_emulated.end()) { - compiler.atomic_image_vars.insert(it->second); + compiler.atomic_image_vars_emulated.insert(it->second); + uses_image_write = true; } - check_resource_write(args[0]); + else + check_resource_write(args[0]); break; } case OpAtomicLoad: { uses_atomics = true; - auto it = image_pointers.find(args[2]); - if (it != image_pointers.end()) + auto it = image_pointers_emulated.find(args[2]); + if (it != image_pointers_emulated.end()) { - compiler.atomic_image_vars.insert(it->second); + compiler.atomic_image_vars_emulated.insert(it->second); } break; } @@ -15068,8 +16906,11 @@ bool CompilerMSL::OpCodePreprocessor::handle(Op opcode, const uint32_t *args, ui case OpArrayLength: { auto *var = compiler.maybe_get_backing_variable(args[2]); - if (var) - compiler.buffers_requiring_array_length.insert(var->self); + if (var != nullptr) + { + if (!compiler.is_var_runtime_size_array(*var)) + compiler.buffers_requiring_array_length.insert(var->self); + } break; } @@ -15137,6 +16978,11 @@ bool CompilerMSL::OpCodePreprocessor::handle(Op opcode, const uint32_t *args, ui break; } + case OpIsHelperInvocationEXT: + if (compiler.needs_manual_helper_invocation_updates()) + needs_helper_invocation = true; + break; + default: break; } @@ -15154,9 +17000,8 @@ void CompilerMSL::OpCodePreprocessor::check_resource_write(uint32_t var_id) { auto *p_var = compiler.maybe_get_backing_variable(var_id); StorageClass sc = p_var ? p_var->storage : StorageClassMax; - if (!compiler.msl_options.supports_msl_version(2, 1) && - (sc == StorageClassUniform || sc == StorageClassStorageBuffer)) - uses_resource_write = true; + if (sc == StorageClassUniform || sc == StorageClassStorageBuffer) + uses_buffer_write = true; } // Returns an enumeration of a SPIR-V function that needs to be output for certain Op codes. @@ -15204,6 +17049,7 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o case OpAtomicIIncrement: case OpAtomicIDecrement: case OpAtomicIAdd: + case OpAtomicFAddEXT: case OpAtomicISub: case OpAtomicSMin: case OpAtomicUMin: @@ -15215,8 +17061,8 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o case OpAtomicLoad: case OpAtomicStore: { - auto it = image_pointers.find(args[opcode == OpAtomicStore ? 0 : 2]); - if (it != image_pointers.end()) + auto it = image_pointers_emulated.find(args[opcode == OpAtomicStore ? 0 : 2]); + if (it != image_pointers_emulated.end()) { uint32_t tid = compiler.get(it->second).basetype; if (tid && compiler.get(tid).image.dim == Dim2D) @@ -15301,12 +17147,15 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o } case OpGroupNonUniformBroadcast: + case OpSubgroupReadInvocationKHR: return SPVFuncImplSubgroupBroadcast; case OpGroupNonUniformBroadcastFirst: + case OpSubgroupFirstInvocationKHR: return SPVFuncImplSubgroupBroadcastFirst; case OpGroupNonUniformBallot: + case OpSubgroupBallotKHR: return SPVFuncImplSubgroupBallot; case OpGroupNonUniformInverseBallot: @@ -15323,6 +17172,7 @@ CompilerMSL::SPVFuncImpl CompilerMSL::OpCodePreprocessor::get_spv_func_impl(Op o return SPVFuncImplSubgroupBallotBitCount; case OpGroupNonUniformAllEqual: + case OpSubgroupAllEqualKHR: return SPVFuncImplSubgroupAllEqual; case OpGroupNonUniformShuffle: @@ -15448,17 +17298,65 @@ void CompilerMSL::remap_constexpr_sampler_by_binding(uint32_t desc_set, uint32_t void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type) { + bool is_packed = has_extended_decoration(source_id, SPIRVCrossDecorationPhysicalTypePacked); + auto *source_expr = maybe_get(source_id); auto *var = maybe_get_backing_variable(source_id); + const SPIRType *var_type = nullptr, *phys_type = nullptr; + + if (uint32_t phys_id = get_extended_decoration(source_id, SPIRVCrossDecorationPhysicalTypeID)) + phys_type = &get(phys_id); + else + phys_type = &expr_type; + if (var) + { source_id = var->self; + var_type = &get_variable_data_type(*var); + } + + bool rewrite_boolean_load = + expr_type.basetype == SPIRType::Boolean && + (var && (var->storage == StorageClassWorkgroup || var_type->basetype == SPIRType::Struct)); // Type fixups for workgroup variables if they are booleans. - if (var && var->storage == StorageClassWorkgroup && expr_type.basetype == SPIRType::Boolean) - expr = join(type_to_glsl(expr_type), "(", expr, ")"); + if (rewrite_boolean_load) + { + if (is_array(expr_type)) + expr = to_rerolled_array_expression(expr_type, expr, expr_type); + else + expr = join(type_to_glsl(expr_type), "(", expr, ")"); + } - // Only interested in standalone builtin variables. + // Type fixups for workgroup variables if they are matrices. + // Don't do fixup for packed types; those are handled specially. + // FIXME: Maybe use a type like spvStorageMatrix for packed matrices? + if (!msl_options.supports_msl_version(3, 0) && var && + (var->storage == StorageClassWorkgroup || + (var_type->basetype == SPIRType::Struct && + has_extended_decoration(var_type->self, SPIRVCrossDecorationWorkgroupStruct) && !is_packed)) && + expr_type.columns > 1) + { + SPIRType matrix_type = *phys_type; + if (source_expr && source_expr->need_transpose) + swap(matrix_type.vecsize, matrix_type.columns); + matrix_type.array.clear(); + matrix_type.array_size_literal.clear(); + expr = join(type_to_glsl(matrix_type), "(", expr, ")"); + } + + // Only interested in standalone builtin variables in the switch below. if (!has_decoration(source_id, DecorationBuiltIn)) + { + // If the backing variable does not match our expected sign, we can fix it up here. + // See ensure_correct_input_type(). + if (var && var->storage == StorageClassInput) + { + auto &base_type = get(var->basetype); + if (base_type.basetype != SPIRType::Struct && expr_type.basetype != base_type.basetype) + expr = join(type_to_glsl(expr_type), "(", expr, ")"); + } return; + } auto builtin = static_cast(get_decoration(source_id, DecorationBuiltIn)); auto expected_type = expr_type.basetype; @@ -15482,13 +17380,14 @@ void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr, case BuiltInInstanceIndex: case BuiltInBaseInstance: case BuiltInBaseVertex: + case BuiltInSampleMask: expected_type = SPIRType::UInt; expected_width = 32; break; case BuiltInTessLevelInner: case BuiltInTessLevelOuter: - if (get_execution_model() == ExecutionModelTessellationControl) + if (is_tesc_shader()) { expected_type = SPIRType::Half; expected_width = 16; @@ -15499,9 +17398,17 @@ void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr, break; } - if (expected_type != expr_type.basetype) + if (is_array(expr_type) && builtin == BuiltInSampleMask) + { + // Needs special handling. + auto wrap_expr = join(type_to_glsl(expr_type), "({ "); + wrap_expr += join(type_to_glsl(get(expr_type.parent_type)), "(", expr, ")"); + wrap_expr += " })"; + expr = std::move(wrap_expr); + } + else if (expected_type != expr_type.basetype) { - if (!expr_type.array.empty() && (builtin == BuiltInTessLevelInner || builtin == BuiltInTessLevelOuter)) + if (is_array(expr_type) && (builtin == BuiltInTessLevelInner || builtin == BuiltInTessLevelOuter)) { // Triggers when loading TessLevel directly as an array. // Need explicit padding + cast. @@ -15518,7 +17425,7 @@ void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr, wrap_expr += ", "; } - if (get_execution_mode_bitset().get(ExecutionModeTriangles)) + if (is_tessellating_triangles()) wrap_expr += ", 0.0"; wrap_expr += " })"; @@ -15533,27 +17440,58 @@ void CompilerMSL::cast_from_variable_load(uint32_t source_id, std::string &expr, expr = bitcast_expression(expr_type, expected_type, expr); } } - - if (builtin == BuiltInTessCoord && get_entry_point().flags.get(ExecutionModeQuads) && expr_type.vecsize == 3) - { - // In SPIR-V, this is always a vec3, even for quads. In Metal, though, it's a float2 for quads. - // The code is expecting a float3, so we need to widen this. - expr = join("float3(", expr, ", 0)"); - } } void CompilerMSL::cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) { + bool is_packed = has_extended_decoration(target_id, SPIRVCrossDecorationPhysicalTypePacked); + auto *target_expr = maybe_get(target_id); auto *var = maybe_get_backing_variable(target_id); + const SPIRType *var_type = nullptr, *phys_type = nullptr; + + if (uint32_t phys_id = get_extended_decoration(target_id, SPIRVCrossDecorationPhysicalTypeID)) + phys_type = &get(phys_id); + else + phys_type = &expr_type; + if (var) + { target_id = var->self; + var_type = &get_variable_data_type(*var); + } - // Type fixups for workgroup variables if they are booleans. - if (var && var->storage == StorageClassWorkgroup && expr_type.basetype == SPIRType::Boolean) + bool rewrite_boolean_store = + expr_type.basetype == SPIRType::Boolean && + (var && (var->storage == StorageClassWorkgroup || var_type->basetype == SPIRType::Struct)); + + // Type fixups for workgroup variables or struct members if they are booleans. + if (rewrite_boolean_store) + { + if (is_array(expr_type)) + { + expr = to_rerolled_array_expression(*var_type, expr, expr_type); + } + else + { + auto short_type = expr_type; + short_type.basetype = SPIRType::Short; + expr = join(type_to_glsl(short_type), "(", expr, ")"); + } + } + + // Type fixups for workgroup variables if they are matrices. + // Don't do fixup for packed types; those are handled specially. + // FIXME: Maybe use a type like spvStorageMatrix for packed matrices? + if (!msl_options.supports_msl_version(3, 0) && var && + (var->storage == StorageClassWorkgroup || + (var_type->basetype == SPIRType::Struct && + has_extended_decoration(var_type->self, SPIRVCrossDecorationWorkgroupStruct) && !is_packed)) && + expr_type.columns > 1) { - auto short_type = expr_type; - short_type.basetype = SPIRType::Short; - expr = join(type_to_glsl(short_type), "(", expr, ")"); + SPIRType matrix_type = *phys_type; + if (target_expr && target_expr->need_transpose) + swap(matrix_type.vecsize, matrix_type.columns); + expr = join("spvStorage_", type_to_glsl(matrix_type), "(", expr, ")"); } // Only interested in standalone builtin variables. @@ -15640,13 +17578,14 @@ bool CompilerMSL::descriptor_set_is_argument_buffer(uint32_t desc_set) const bool CompilerMSL::is_supported_argument_buffer_type(const SPIRType &type) const { - // Very specifically, image load-store in argument buffers are disallowed on MSL on iOS. - // But we won't know when the argument buffer is encoded whether this image will have - // a NonWritable decoration. So just use discrete arguments for all storage images - // on iOS. - bool is_storage_image = type.basetype == SPIRType::Image && type.image.sampled == 2; - bool is_supported_type = !msl_options.is_ios() || !is_storage_image; - return !type_is_msl_framebuffer_fetch(type) && is_supported_type; + // iOS Tier 1 argument buffers do not support writable images. + // When the argument buffer is encoded, we don't know whether this image will have a + // NonWritable decoration, so just use discrete arguments for all storage images on iOS. + bool is_supported_type = !(type.basetype == SPIRType::Image && + type.image.sampled == 2 && + msl_options.is_ios() && + msl_options.argument_buffers_tier <= Options::ArgumentBuffersTier::Tier1); + return is_supported_type && !type_is_msl_framebuffer_fetch(type); } void CompilerMSL::analyze_argument_buffers() @@ -15665,6 +17604,7 @@ void CompilerMSL::analyze_argument_buffers() struct Resource { SPIRVariable *var; + SPIRVariable *descriptor_alias; string name; SPIRType::BaseType basetype; uint32_t index; @@ -15704,6 +17644,32 @@ void CompilerMSL::analyze_argument_buffers() } } + // Handle descriptor aliasing as well as we can. + // We can handle aliasing of buffers by casting pointers, but not for typed resources. + // Inline UBOs cannot be handled since it's not a pointer, but inline data. + SPIRVariable *descriptor_alias = nullptr; + if (var.storage == StorageClassUniform || var.storage == StorageClassStorageBuffer) + { + for (auto &resource : resources_in_set[desc_set]) + { + if (get_decoration(resource.var->self, DecorationBinding) == + get_decoration(var_id, DecorationBinding) && + resource.basetype == SPIRType::Struct && type.basetype == SPIRType::Struct && + (resource.var->storage == StorageClassUniform || + resource.var->storage == StorageClassStorageBuffer)) + { + descriptor_alias = resource.var; + // Self-reference marks that we should declare the resource, + // and it's being used as an alias (so we can emit void* instead). + resource.descriptor_alias = resource.var; + // Need to promote interlocked usage so that the primary declaration is correct. + if (interlocked_resources.count(var_id)) + interlocked_resources.insert(resource.var->self); + break; + } + } + } + uint32_t binding = get_decoration(var_id, DecorationBinding); if (type.basetype == SPIRType::SampledImage) { @@ -15717,14 +17683,14 @@ void CompilerMSL::analyze_argument_buffers() { uint32_t image_resource_index = get_metal_resource_index(var, SPIRType::Image, i); resources_in_set[desc_set].push_back( - { &var, to_name(var_id), SPIRType::Image, image_resource_index, i }); + { &var, descriptor_alias, to_name(var_id), SPIRType::Image, image_resource_index, i }); } if (type.image.dim != DimBuffer && !constexpr_sampler) { uint32_t sampler_resource_index = get_metal_resource_index(var, SPIRType::Sampler); resources_in_set[desc_set].push_back( - { &var, to_sampler_expression(var_id), SPIRType::Sampler, sampler_resource_index, 0 }); + { &var, descriptor_alias, to_sampler_expression(var_id), SPIRType::Sampler, sampler_resource_index, 0 }); } } else if (inline_uniform_blocks.count(SetBindingPair{ desc_set, binding })) @@ -15736,22 +17702,27 @@ void CompilerMSL::analyze_argument_buffers() // constexpr samplers are not declared as resources. // Inline uniform blocks are always emitted at the end. add_resource_name(var_id); + + uint32_t resource_index = ~0u; + if (!descriptor_alias) + resource_index = get_metal_resource_index(var, type.basetype); + resources_in_set[desc_set].push_back( - { &var, to_name(var_id), type.basetype, get_metal_resource_index(var, type.basetype), 0 }); + { &var, descriptor_alias, to_name(var_id), type.basetype, resource_index, 0 }); // Emulate texture2D atomic operations - if (atomic_image_vars.count(var.self)) + if (atomic_image_vars_emulated.count(var.self)) { uint32_t buffer_resource_index = get_metal_resource_index(var, SPIRType::AtomicCounter, 0); resources_in_set[desc_set].push_back( - { &var, to_name(var_id) + "_atomic", SPIRType::Struct, buffer_resource_index, 0 }); + { &var, descriptor_alias, to_name(var_id) + "_atomic", SPIRType::Struct, buffer_resource_index, 0 }); } } // Check if this descriptor set needs a swizzle buffer. if (needs_swizzle_buffer_def && is_sampled_image_type(type)) set_needs_swizzle_buffer[desc_set] = true; - else if (buffers_requiring_array_length.count(var_id) != 0) + else if (buffer_requires_array_length(var_id)) { set_needs_buffer_sizes[desc_set] = true; needs_buffer_sizes = true; @@ -15775,6 +17746,7 @@ void CompilerMSL::analyze_argument_buffers() // Create a buffer to hold extra data, including the swizzle constants. SPIRType uint_type_pointer = get_uint_type(); + uint_type_pointer.op = OpTypePointer; uint_type_pointer.pointer = true; uint_type_pointer.pointer_depth++; uint_type_pointer.parent_type = get_uint_type_id(); @@ -15791,7 +17763,7 @@ void CompilerMSL::analyze_argument_buffers() set_decoration(var_id, DecorationDescriptorSet, desc_set); set_decoration(var_id, DecorationBinding, kSwizzleBufferBinding); resources_in_set[desc_set].push_back( - { &var, to_name(var_id), SPIRType::UInt, get_metal_resource_index(var, SPIRType::UInt), 0 }); + { &var, nullptr, to_name(var_id), SPIRType::UInt, get_metal_resource_index(var, SPIRType::UInt), 0 }); } if (set_needs_buffer_sizes[desc_set]) @@ -15802,7 +17774,7 @@ void CompilerMSL::analyze_argument_buffers() set_decoration(var_id, DecorationDescriptorSet, desc_set); set_decoration(var_id, DecorationBinding, kBufferSizeBufferBinding); resources_in_set[desc_set].push_back( - { &var, to_name(var_id), SPIRType::UInt, get_metal_resource_index(var, SPIRType::UInt), 0 }); + { &var, nullptr, to_name(var_id), SPIRType::UInt, get_metal_resource_index(var, SPIRType::UInt), 0 }); } } } @@ -15814,7 +17786,7 @@ void CompilerMSL::analyze_argument_buffers() uint32_t desc_set = get_decoration(var_id, DecorationDescriptorSet); add_resource_name(var_id); resources_in_set[desc_set].push_back( - { &var, to_name(var_id), SPIRType::Struct, get_metal_resource_index(var, SPIRType::Struct), 0 }); + { &var, nullptr, to_name(var_id), SPIRType::Struct, get_metal_resource_index(var, SPIRType::Struct), 0 }); } for (uint32_t desc_set = 0; desc_set < kMaxArgumentBuffers; desc_set++) @@ -15830,7 +17802,7 @@ void CompilerMSL::analyze_argument_buffers() uint32_t ptr_type_id = next_id + 2; argument_buffer_ids[desc_set] = next_id; - auto &buffer_type = set(type_id); + auto &buffer_type = set(type_id, OpTypeStruct); buffer_type.basetype = SPIRType::Struct; @@ -15847,8 +17819,9 @@ void CompilerMSL::analyze_argument_buffers() set_name(type_id, join("spvDescriptorSetBuffer", desc_set)); - auto &ptr_type = set(ptr_type_id); + auto &ptr_type = set(ptr_type_id, OpTypePointer); ptr_type = buffer_type; + ptr_type.op = spv::OpTypePointer; ptr_type.pointer = true; ptr_type.pointer_depth++; ptr_type.parent_type = type_id; @@ -15858,7 +17831,7 @@ void CompilerMSL::analyze_argument_buffers() set_name(buffer_variable_id, join("spvDescriptorSet", desc_set)); // Ids must be emitted in ID order. - sort(begin(resources), end(resources), [&](const Resource &lhs, const Resource &rhs) -> bool { + stable_sort(begin(resources), end(resources), [&](const Resource &lhs, const Resource &rhs) -> bool { return tie(lhs.index, lhs.basetype) < tie(rhs.index, rhs.basetype); }); @@ -15873,51 +17846,51 @@ void CompilerMSL::analyze_argument_buffers() // member_index and next_arg_buff_index are incremented when padding members are added. if (msl_options.pad_argument_buffer_resources) { - while (resource.index > next_arg_buff_index) + auto &rez_bind = get_argument_buffer_resource(desc_set, next_arg_buff_index); + if (!resource.descriptor_alias) { - auto &rez_bind = get_argument_buffer_resource(desc_set, next_arg_buff_index); - switch (rez_bind.basetype) + while (resource.index > next_arg_buff_index) { - case SPIRType::Void: - case SPIRType::Boolean: - case SPIRType::SByte: - case SPIRType::UByte: - case SPIRType::Short: - case SPIRType::UShort: - case SPIRType::Int: - case SPIRType::UInt: - case SPIRType::Int64: - case SPIRType::UInt64: - case SPIRType::AtomicCounter: - case SPIRType::Half: - case SPIRType::Float: - case SPIRType::Double: - add_argument_buffer_padding_buffer_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - break; - case SPIRType::Image: - add_argument_buffer_padding_image_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - break; - case SPIRType::Sampler: - add_argument_buffer_padding_sampler_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - break; - case SPIRType::SampledImage: - if (next_arg_buff_index == rez_bind.msl_sampler) - add_argument_buffer_padding_sampler_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - else + switch (rez_bind.basetype) + { + case SPIRType::Void: + case SPIRType::Boolean: + case SPIRType::SByte: + case SPIRType::UByte: + case SPIRType::Short: + case SPIRType::UShort: + case SPIRType::Int: + case SPIRType::UInt: + case SPIRType::Int64: + case SPIRType::UInt64: + case SPIRType::AtomicCounter: + case SPIRType::Half: + case SPIRType::Float: + case SPIRType::Double: + add_argument_buffer_padding_buffer_type(buffer_type, member_index, next_arg_buff_index, rez_bind); + break; + case SPIRType::Image: add_argument_buffer_padding_image_type(buffer_type, member_index, next_arg_buff_index, rez_bind); - break; - default: - break; + break; + case SPIRType::Sampler: + add_argument_buffer_padding_sampler_type(buffer_type, member_index, next_arg_buff_index, rez_bind); + break; + case SPIRType::SampledImage: + if (next_arg_buff_index == rez_bind.msl_sampler) + add_argument_buffer_padding_sampler_type(buffer_type, member_index, next_arg_buff_index, rez_bind); + else + add_argument_buffer_padding_image_type(buffer_type, member_index, next_arg_buff_index, rez_bind); + break; + default: + break; + } } } // Adjust the number of slots consumed by current member itself. - // If actual member is an array, allow runtime array resolution as well. - uint32_t elem_cnt = type.array.empty() ? 1 : to_array_size_literal(type); - if (elem_cnt == 0) - elem_cnt = get_resource_array_size(var.self); - - next_arg_buff_index += elem_cnt; + // Use the count value from the app, instead of the shader, in case the + // shader is only accesing part, or even one element, of the array. + next_arg_buff_index += rez_bind.count; } string mbr_name = ensure_valid_name(resource.name, "m"); @@ -15931,14 +17904,14 @@ void CompilerMSL::analyze_argument_buffers() bool type_is_array = !type.array.empty(); uint32_t sampler_type_id = ir.increase_bound_by(type_is_array ? 2 : 1); - auto &new_sampler_type = set(sampler_type_id); + auto &new_sampler_type = set(sampler_type_id, OpTypeSampler); new_sampler_type.basetype = SPIRType::Sampler; new_sampler_type.storage = StorageClassUniformConstant; if (type_is_array) { uint32_t sampler_type_array_id = sampler_type_id + 1; - auto &sampler_type_array = set(sampler_type_array_id); + auto &sampler_type_array = set(sampler_type_array_id, OpTypeArray); sampler_type_array = new_sampler_type; sampler_type_array.array = type.array; sampler_type_array.array_size_literal = type.array_size_literal; @@ -15963,17 +17936,23 @@ void CompilerMSL::analyze_argument_buffers() } else if (buffers_requiring_dynamic_offset.count(pair)) { + if (resource.descriptor_alias) + SPIRV_CROSS_THROW("Descriptor aliasing is currently not supported with dynamic offsets."); + // Don't set the qualified name here; we'll define a variable holding the corrected buffer address later. buffer_type.member_types.push_back(var.basetype); buffers_requiring_dynamic_offset[pair].second = var.self; } else if (inline_uniform_blocks.count(pair)) { + if (resource.descriptor_alias) + SPIRV_CROSS_THROW("Descriptor aliasing is currently not supported with inline UBOs."); + // Put the buffer block itself into the argument buffer. buffer_type.member_types.push_back(get_variable_data_type_id(var)); set_qualified_name(var.self, join(to_name(buffer_variable_id), ".", mbr_name)); } - else if (atomic_image_vars.count(var.self)) + else if (atomic_image_vars_emulated.count(var.self)) { // Emulate texture2D atomic operations. // Don't set the qualified name: it's already set for this variable, @@ -15983,12 +17962,13 @@ void CompilerMSL::analyze_argument_buffers() uint32_t atomic_type_id = offset; uint32_t type_ptr_id = offset + 1; - SPIRType atomic_type; + SPIRType atomic_type { OpTypeInt }; atomic_type.basetype = SPIRType::AtomicCounter; atomic_type.width = 32; atomic_type.vecsize = 1; set(atomic_type_id, atomic_type); + atomic_type.op = OpTypePointer; atomic_type.pointer = true; atomic_type.pointer_depth++; atomic_type.parent_type = atomic_type_id; @@ -16000,9 +17980,12 @@ void CompilerMSL::analyze_argument_buffers() } else { - // Resources will be declared as pointers not references, so automatically dereference as appropriate. - buffer_type.member_types.push_back(var.basetype); - if (type.array.empty()) + if (!resource.descriptor_alias || resource.descriptor_alias == resource.var) + buffer_type.member_types.push_back(var.basetype); + + if (resource.descriptor_alias && resource.descriptor_alias != resource.var) + buffer_aliases_argument.push_back({ var.self, resource.descriptor_alias->self }); + else if (type.array.empty()) set_qualified_name(var.self, join("(*", to_name(buffer_variable_id), ".", mbr_name, ")")); else set_qualified_name(var.self, join(to_name(buffer_variable_id), ".", mbr_name)); @@ -16046,13 +18029,14 @@ void CompilerMSL::add_argument_buffer_padding_buffer_type(SPIRType &struct_type, if (!argument_buffer_padding_buffer_type_id) { uint32_t buff_type_id = ir.increase_bound_by(2); - auto &buff_type = set(buff_type_id); + auto &buff_type = set(buff_type_id, OpNop); buff_type.basetype = rez_bind.basetype; buff_type.storage = StorageClassUniformConstant; uint32_t ptr_type_id = buff_type_id + 1; - auto &ptr_type = set(ptr_type_id); + auto &ptr_type = set(ptr_type_id, OpTypePointer); ptr_type = buff_type; + ptr_type.op = spv::OpTypePointer; ptr_type.pointer = true; ptr_type.pointer_depth++; ptr_type.parent_type = buff_type_id; @@ -16060,8 +18044,7 @@ void CompilerMSL::add_argument_buffer_padding_buffer_type(SPIRType &struct_type, argument_buffer_padding_buffer_type_id = ptr_type_id; } - for (uint32_t rez_idx = 0; rez_idx < rez_bind.count; rez_idx++) - add_argument_buffer_padding_type(argument_buffer_padding_buffer_type_id, struct_type, mbr_idx, arg_buff_index, 1); + add_argument_buffer_padding_type(argument_buffer_padding_buffer_type_id, struct_type, mbr_idx, arg_buff_index, rez_bind.count); } // Adds an argument buffer padding argument image type as a member of the struct type at the member index. @@ -16071,12 +18054,12 @@ void CompilerMSL::add_argument_buffer_padding_image_type(SPIRType &struct_type, if (!argument_buffer_padding_image_type_id) { uint32_t base_type_id = ir.increase_bound_by(2); - auto &base_type = set(base_type_id); + auto &base_type = set(base_type_id, OpTypeFloat); base_type.basetype = SPIRType::Float; base_type.width = 32; uint32_t img_type_id = base_type_id + 1; - auto &img_type = set(img_type_id); + auto &img_type = set(img_type_id, OpTypeImage); img_type.basetype = SPIRType::Image; img_type.storage = StorageClassUniformConstant; @@ -16102,7 +18085,7 @@ void CompilerMSL::add_argument_buffer_padding_sampler_type(SPIRType &struct_type if (!argument_buffer_padding_sampler_type_id) { uint32_t samp_type_id = ir.increase_bound_by(1); - auto &samp_type = set(samp_type_id); + auto &samp_type = set(samp_type_id, OpTypeSampler); samp_type.basetype = SPIRType::Sampler; samp_type.storage = StorageClassUniformConstant; @@ -16121,8 +18104,8 @@ void CompilerMSL::add_argument_buffer_padding_type(uint32_t mbr_type_id, SPIRTyp if (count > 1) { uint32_t ary_type_id = ir.increase_bound_by(1); - auto &ary_type = set(ary_type_id); - ary_type = get(type_id); + auto &ary_type = set(ary_type_id, get(type_id)); + ary_type.op = OpTypeArray; ary_type.array.push_back(count); ary_type.array_size_literal.push_back(true); ary_type.parent_type = type_id; @@ -16146,7 +18129,7 @@ void CompilerMSL::activate_argument_buffer_resources() uint32_t desc_set = get_decoration(self, DecorationDescriptorSet); if (descriptor_set_is_argument_buffer(desc_set)) - active_interface_variables.insert(self); + add_active_interface_variable(self); }); } @@ -16172,6 +18155,20 @@ void CompilerMSL::emit_block_hints(const SPIRBlock &) string CompilerMSL::additional_fixed_sample_mask_str() const { char print_buffer[32]; +#ifdef _MSC_VER + // snprintf does not exist or is buggy on older MSVC versions, some of + // them being used by MinGW. Use sprintf instead and disable + // corresponding warning. +#pragma warning(push) +#pragma warning(disable : 4996) +#endif +#if _WIN32 sprintf(print_buffer, "0x%x", msl_options.additional_fixed_sample_mask); +#else + snprintf(print_buffer, sizeof(print_buffer), "0x%x", msl_options.additional_fixed_sample_mask); +#endif +#ifdef _MSC_VER +#pragma warning(pop) +#endif return print_buffer; } diff --git a/src/libraries/spirv_cross/spirv_msl.hpp b/src/libraries/spirv_cross/spirv_msl.hpp index f01cceaf7..45109d88f 100644 --- a/src/libraries/spirv_cross/spirv_msl.hpp +++ b/src/libraries/spirv_cross/spirv_msl.hpp @@ -34,36 +34,53 @@ namespace SPIRV_CROSS_NAMESPACE { -// Indicates the format of a shader input. Currently limited to specifying +// Indicates the format of a shader interface variable. Currently limited to specifying // if the input is an 8-bit unsigned integer, 16-bit unsigned integer, or // some other format. -enum MSLShaderInputFormat +enum MSLShaderVariableFormat { - MSL_SHADER_INPUT_FORMAT_OTHER = 0, - MSL_SHADER_INPUT_FORMAT_UINT8 = 1, - MSL_SHADER_INPUT_FORMAT_UINT16 = 2, - MSL_SHADER_INPUT_FORMAT_ANY16 = 3, - MSL_SHADER_INPUT_FORMAT_ANY32 = 4, + MSL_SHADER_VARIABLE_FORMAT_OTHER = 0, + MSL_SHADER_VARIABLE_FORMAT_UINT8 = 1, + MSL_SHADER_VARIABLE_FORMAT_UINT16 = 2, + MSL_SHADER_VARIABLE_FORMAT_ANY16 = 3, + MSL_SHADER_VARIABLE_FORMAT_ANY32 = 4, // Deprecated aliases. - MSL_VERTEX_FORMAT_OTHER = MSL_SHADER_INPUT_FORMAT_OTHER, - MSL_VERTEX_FORMAT_UINT8 = MSL_SHADER_INPUT_FORMAT_UINT8, - MSL_VERTEX_FORMAT_UINT16 = MSL_SHADER_INPUT_FORMAT_UINT16, + MSL_VERTEX_FORMAT_OTHER = MSL_SHADER_VARIABLE_FORMAT_OTHER, + MSL_VERTEX_FORMAT_UINT8 = MSL_SHADER_VARIABLE_FORMAT_UINT8, + MSL_VERTEX_FORMAT_UINT16 = MSL_SHADER_VARIABLE_FORMAT_UINT16, + MSL_SHADER_INPUT_FORMAT_OTHER = MSL_SHADER_VARIABLE_FORMAT_OTHER, + MSL_SHADER_INPUT_FORMAT_UINT8 = MSL_SHADER_VARIABLE_FORMAT_UINT8, + MSL_SHADER_INPUT_FORMAT_UINT16 = MSL_SHADER_VARIABLE_FORMAT_UINT16, + MSL_SHADER_INPUT_FORMAT_ANY16 = MSL_SHADER_VARIABLE_FORMAT_ANY16, + MSL_SHADER_INPUT_FORMAT_ANY32 = MSL_SHADER_VARIABLE_FORMAT_ANY32, + + MSL_SHADER_VARIABLE_FORMAT_INT_MAX = 0x7fffffff +}; + +// Indicates the rate at which a variable changes value, one of: per-vertex, +// per-primitive, or per-patch. +enum MSLShaderVariableRate +{ + MSL_SHADER_VARIABLE_RATE_PER_VERTEX = 0, + MSL_SHADER_VARIABLE_RATE_PER_PRIMITIVE = 1, + MSL_SHADER_VARIABLE_RATE_PER_PATCH = 2, - MSL_SHADER_INPUT_FORMAT_INT_MAX = 0x7fffffff + MSL_SHADER_VARIABLE_RATE_INT_MAX = 0x7fffffff, }; -// Defines MSL characteristics of an input variable at a particular location. +// Defines MSL characteristics of a shader interface variable at a particular location. // After compilation, it is possible to query whether or not this location was used. // If vecsize is nonzero, it must be greater than or equal to the vecsize declared in the shader, // or behavior is undefined. -struct MSLShaderInput +struct MSLShaderInterfaceVariable { uint32_t location = 0; uint32_t component = 0; - MSLShaderInputFormat format = MSL_SHADER_INPUT_FORMAT_OTHER; + MSLShaderVariableFormat format = MSL_SHADER_VARIABLE_FORMAT_OTHER; spv::BuiltIn builtin = spv::BuiltInMax; uint32_t vecsize = 0; + MSLShaderVariableRate rate = MSL_SHADER_VARIABLE_RATE_PER_VERTEX; }; // Matches the binding index of a MSL resource for a binding within a descriptor set. @@ -301,6 +318,7 @@ class CompilerMSL : public CompilerGLSL uint32_t dynamic_offsets_buffer_index = 23; uint32_t shader_input_buffer_index = 22; uint32_t shader_index_buffer_index = 21; + uint32_t shader_patch_input_buffer_index = 20; uint32_t shader_input_wg_index = 0; uint32_t device_index = 0; uint32_t enable_frag_output_mask = 0xffffffff; @@ -321,10 +339,28 @@ class CompilerMSL : public CompilerGLSL bool dispatch_base = false; bool texture_1D_as_2D = false; - // Enable use of MSL 2.0 indirect argument buffers. + // Enable use of Metal argument buffers. // MSL 2.0 must also be enabled. bool argument_buffers = false; + // Defines Metal argument buffer tier levels. + // Uses same values as Metal MTLArgumentBuffersTier enumeration. + enum class ArgumentBuffersTier + { + Tier1 = 0, + Tier2 = 1, + }; + + // When using Metal argument buffers, indicates the Metal argument buffer tier level supported by the Metal platform. + // Ignored when Options::argument_buffers is disabled. + // - Tier1 supports writable images on macOS, but not on iOS. + // - Tier2 supports writable images on macOS and iOS, and higher resource count limits. + // Tier capabilities based on recommendations from Apple engineering. + ArgumentBuffersTier argument_buffers_tier = ArgumentBuffersTier::Tier1; + + // Enables specifick argument buffer format with extra information to track SSBO-length + bool runtime_array_rich_descriptor = false; + // Ensures vertex and instance indices start at zero. This reflects the behavior of HLSL with SV_VertexID and SV_InstanceID. bool enable_base_index_zero = false; @@ -382,6 +418,11 @@ class CompilerMSL : public CompilerGLSL // builtins are processed, but should result in more efficient usage of the GPU. bool multi_patch_workgroup = false; + // Use storage buffers instead of vertex-style attributes for tessellation evaluation + // input. This may require conversion of inputs in the generated post-tessellation + // vertex shader, but allows the use of nested arrays. + bool raw_buffer_tese_input = false; + // If set, a vertex shader will be compiled as part of a tessellation pipeline. // It will be translated as a compute kernel, so it can use the global invocation ID // to index the output buffer. @@ -393,7 +434,7 @@ class CompilerMSL : public CompilerGLSL // and will be addressed using the current ViewIndex. bool arrayed_subpass_input = false; - // Whether to use SIMD-group or quadgroup functions to implement group nnon-uniform + // Whether to use SIMD-group or quadgroup functions to implement group non-uniform // operations. Some GPUs on iOS do not support the SIMD-group functions, only the // quadgroup functions. bool ios_use_simdgroup_functions = false; @@ -435,6 +476,49 @@ class CompilerMSL : public CompilerGLSL // the extra threads away. bool force_sample_rate_shading = false; + // If set, gl_HelperInvocation will be set manually whenever a fragment is discarded. + // Some Metal devices have a bug where simd_is_helper_thread() does not return true + // after a fragment has been discarded. This is a workaround that is only expected to be needed + // until the bug is fixed in Metal; it is provided as an option to allow disabling it when that occurs. + bool manual_helper_invocation_updates = true; + + // If set, extra checks will be emitted in fragment shaders to prevent writes + // from discarded fragments. Some Metal devices have a bug where writes to storage resources + // from discarded fragment threads continue to occur, despite the fragment being + // discarded. This is a workaround that is only expected to be needed until the + // bug is fixed in Metal; it is provided as an option so it can be enabled + // only when the bug is present. + bool check_discarded_frag_stores = false; + + // If set, Lod operands to OpImageSample*DrefExplicitLod for 1D and 2D array images + // will be implemented using a gradient instead of passing the level operand directly. + // Some Metal devices have a bug where the level() argument to depth2d_array::sample_compare() + // in a fragment shader is biased by some unknown amount, possibly dependent on the + // partial derivatives of the texture coordinates. This is a workaround that is only + // expected to be needed until the bug is fixed in Metal; it is provided as an option + // so it can be enabled only when the bug is present. + bool sample_dref_lod_array_as_grad = false; + + // MSL doesn't guarantee coherence between writes and subsequent reads of read_write textures. + // This inserts fences before each read of a read_write texture to ensure coherency. + // If you're sure you never rely on this, you can set this to false for a possible performance improvement. + // Note: Only Apple's GPU compiler takes advantage of the lack of coherency, so make sure to test on Apple GPUs if you disable this. + bool readwrite_texture_fences = true; + + // Metal 3.1 introduced a Metal regression bug which causes infinite recursion during + // Metal's analysis of an entry point input structure that is itself recursive. Enabling + // this option will replace the recursive input declaration with a alternate variable of + // type void*, and then cast to the correct type at the top of the entry point function. + // The bug has been reported to Apple, and will hopefully be fixed in future releases. + bool replace_recursive_inputs = false; + + // If set, manual fixups of gradient vectors for cube texture lookups will be performed. + // All released Apple Silicon GPUs to date behave incorrectly when sampling a cube texture + // with explicit gradients. They will ignore one of the three partial derivatives based + // on the selected major axis, and expect the remaining derivatives to be partially + // transformed. + bool agx_manual_cube_grad_fixup = false; + bool is_ios() const { return platform == iOS; @@ -445,6 +529,11 @@ class CompilerMSL : public CompilerGLSL return platform == macOS; } + bool use_quadgroup_operation() const + { + return is_ios() && !ios_use_simdgroup_functions; + } + void set_msl_version(uint32_t major, uint32_t minor = 0, uint32_t patch = 0) { msl_version = make_msl_version(major, minor, patch); @@ -494,6 +583,11 @@ class CompilerMSL : public CompilerGLSL return !buffers_requiring_array_length.empty(); } + bool buffer_requires_array_length(VariableID id) const + { + return buffers_requiring_array_length.count(id) != 0; + } + // Provide feedback to calling API to allow it to pass a buffer // containing the view mask for the current multiview subpass. bool needs_view_mask_buffer() const @@ -534,10 +628,15 @@ class CompilerMSL : public CompilerGLSL explicit CompilerMSL(const ParsedIR &ir); explicit CompilerMSL(ParsedIR &&ir); - // input is a shader input description used to fix up shader input variables. + // input is a shader interface variable description used to fix up shader input variables. // If shader inputs are provided, is_msl_shader_input_used() will return true after - // calling ::compile() if the location was used by the MSL code. - void add_msl_shader_input(const MSLShaderInput &input); + // calling ::compile() if the location were used by the MSL code. + void add_msl_shader_input(const MSLShaderInterfaceVariable &input); + + // output is a shader interface variable description used to fix up shader output variables. + // If shader outputs are provided, is_msl_shader_output_used() will return true after + // calling ::compile() if the location were used by the MSL code. + void add_msl_shader_output(const MSLShaderInterfaceVariable &output); // resource is a resource binding to indicate the MSL buffer, // texture or sampler index to use for a particular SPIR-V description set @@ -572,6 +671,9 @@ class CompilerMSL : public CompilerGLSL // Query after compilation is done. This allows you to check if an input location was used by the shader. bool is_msl_shader_input_used(uint32_t location); + // Query after compilation is done. This allows you to check if an output location were used by the shader. + bool is_msl_shader_output_used(uint32_t location); + // If not using add_msl_shader_input, it's possible // that certain builtin attributes need to be automatically assigned locations. // This is typical for tessellation builtin inputs such as tess levels, gl_Position, etc. @@ -579,6 +681,13 @@ class CompilerMSL : public CompilerGLSL // add_msl_shader_input or the builtin is not used, otherwise returns N in [[attribute(N)]]. uint32_t get_automatic_builtin_input_location(spv::BuiltIn builtin) const; + // If not using add_msl_shader_output, it's possible + // that certain builtin attributes need to be automatically assigned locations. + // This is typical for tessellation builtin outputs such as tess levels, gl_Position, etc. + // This returns k_unknown_location if the location were explicitly assigned with + // add_msl_shader_output or the builtin were not used, otherwise returns N in [[attribute(N)]]. + uint32_t get_automatic_builtin_output_location(spv::BuiltIn builtin) const; + // NOTE: Only resources which are remapped using add_msl_resource_binding will be reported here. // Constexpr samplers are always assumed to be emitted. // No specific MSLResourceBinding remapping is required for constexpr samplers as long as they are remapped @@ -633,7 +742,7 @@ class CompilerMSL : public CompilerGLSL protected: // An enum of SPIR-V functions that are implemented in additional // source code that is added to the shader if necessary. - enum SPVFuncImpl + enum SPVFuncImpl : uint8_t { SPVFuncImplNone, SPVFuncImplMod, @@ -654,12 +763,14 @@ class CompilerMSL : public CompilerGLSL SPVFuncImplArrayOfArrayCopy6Dim = SPVFuncImplArrayCopyMultidimBase + 6, SPVFuncImplTexelBufferCoords, SPVFuncImplImage2DAtomicCoords, // Emulate texture2D atomic operations + SPVFuncImplGradientCube, SPVFuncImplFMul, SPVFuncImplFAdd, SPVFuncImplFSub, SPVFuncImplQuantizeToF16, SPVFuncImplCubemapTo2DArrayFace, SPVFuncImplUnsafeArray, // Allow Metal to use the array template to make arrays a value type + SPVFuncImplStorageMatrix, // Allow threadgroup construction of matrices SPVFuncImplInverse4x4, SPVFuncImplInverse3x3, SPVFuncImplInverse2x2, @@ -708,11 +819,18 @@ class CompilerMSL : public CompilerGLSL SPVFuncImplConvertYCbCrBT601, SPVFuncImplConvertYCbCrBT2020, SPVFuncImplDynamicImageSampler, + SPVFuncImplRayQueryIntersectionParams, + SPVFuncImplVariableDescriptor, + SPVFuncImplVariableSizedDescriptor, + SPVFuncImplVariableDescriptorArray, + SPVFuncImplPaddedStd140 }; // If the underlying resource has been used for comparison then duplicate loads of that resource must be too // Use Metal's native frame-buffer fetch API for subpass inputs. void emit_texture_op(const Instruction &i, bool sparse) override; + void emit_binary_ptr_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op); + std::string to_ptr_expression(uint32_t id, bool register_expression_read = true); void emit_binary_unord_op(uint32_t result_type, uint32_t result_id, uint32_t op0, uint32_t op1, const char *op); void emit_instruction(const Instruction &instr) override; void emit_glsl_op(uint32_t result_type, uint32_t result_id, uint32_t op, const uint32_t *args, @@ -731,6 +849,7 @@ class CompilerMSL : public CompilerGLSL void emit_struct_member(const SPIRType &type, uint32_t member_type_id, uint32_t index, const std::string &qualifier = "", uint32_t base_offset = 0) override; void emit_struct_padding_target(const SPIRType &type) override; + std::string type_to_glsl(const SPIRType &type, uint32_t id, bool member); std::string type_to_glsl(const SPIRType &type, uint32_t id = 0) override; void emit_block_hints(const SPIRBlock &block) override; @@ -738,9 +857,6 @@ class CompilerMSL : public CompilerGLSL std::string type_to_array_glsl(const SPIRType &type) override; std::string constant_op_expression(const SPIRConstantOp &cop) override; - // Threadgroup arrays can't have a wrapper type - std::string variable_decl(const SPIRVariable &variable) override; - bool variable_decl_is_remapped_storage(const SPIRVariable &variable, spv::StorageClass storage) const override; // GCC workaround of lambdas calling protected functions (for older GCC versions) @@ -765,10 +881,9 @@ class CompilerMSL : public CompilerGLSL std::string bitcast_glsl_op(const SPIRType &result_type, const SPIRType &argument_type) override; bool emit_complex_bitcast(uint32_t result_id, uint32_t id, uint32_t op0) override; bool skip_argument(uint32_t id) const override; - std::string to_member_reference(uint32_t base, const SPIRType &type, uint32_t index, bool ptr_chain) override; + std::string to_member_reference(uint32_t base, const SPIRType &type, uint32_t index, bool ptr_chain_is_resolved) override; std::string to_qualifiers_glsl(uint32_t id) override; void replace_illegal_names() override; - void declare_undefined_values() override; void declare_constant_arrays(); void replace_illegal_entry_point_names(); @@ -784,13 +899,17 @@ class CompilerMSL : public CompilerGLSL bool is_non_native_row_major_matrix(uint32_t id) override; bool member_is_non_native_row_major_matrix(const SPIRType &type, uint32_t index) override; std::string convert_row_major_matrix(std::string exp_str, const SPIRType &exp_type, uint32_t physical_type_id, - bool is_packed) override; + bool is_packed, bool relaxed) override; + + bool is_tesc_shader() const; + bool is_tese_shader() const; void preprocess_op_codes(); void localize_global_variables(); void extract_global_variables_from_functions(); void mark_packable_structs(); void mark_as_packable(SPIRType &type); + void mark_as_workgroup_struct(SPIRType &type); std::unordered_map> function_global_vars; void extract_global_variables_from_function(uint32_t func_id, std::set &added_arg_ids, @@ -826,13 +945,22 @@ class CompilerMSL : public CompilerGLSL bool add_component_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref, SPIRVariable &var, const SPIRType &type, InterfaceBlockMeta &meta); - void add_plain_member_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref, - SPIRType &ib_type, SPIRVariable &var, uint32_t index, - InterfaceBlockMeta &meta); - void add_composite_member_variable_to_interface_block(spv::StorageClass storage, const std::string &ib_var_ref, - SPIRType &ib_type, SPIRVariable &var, uint32_t index, - InterfaceBlockMeta &meta); + void add_plain_member_variable_to_interface_block(spv::StorageClass storage, + const std::string &ib_var_ref, SPIRType &ib_type, + SPIRVariable &var, SPIRType &var_type, + uint32_t mbr_idx, InterfaceBlockMeta &meta, + const std::string &mbr_name_qual, + const std::string &var_chain_qual, + uint32_t &location, uint32_t &var_mbr_idx); + void add_composite_member_variable_to_interface_block(spv::StorageClass storage, + const std::string &ib_var_ref, SPIRType &ib_type, + SPIRVariable &var, SPIRType &var_type, + uint32_t mbr_idx, InterfaceBlockMeta &meta, + const std::string &mbr_name_qual, + const std::string &var_chain_qual, + uint32_t &location, uint32_t &var_mbr_idx); void add_tess_level_input_to_interface_block(const std::string &ib_var_ref, SPIRType &ib_type, SPIRVariable &var); + void add_tess_level_input(const std::string &base_ref, const std::string &mbr_name, SPIRVariable &var); void fix_up_interface_member_indices(spv::StorageClass storage, uint32_t ib_type_id); @@ -848,7 +976,8 @@ class CompilerMSL : public CompilerGLSL void emit_specialization_constants_and_structs(); void emit_interface_block(uint32_t ib_var_id); bool maybe_emit_array_assignment(uint32_t id_lhs, uint32_t id_rhs); - uint32_t get_resource_array_size(uint32_t id) const; + bool is_var_runtime_size_array(const SPIRVariable &var) const; + uint32_t get_resource_array_size(const SPIRType &type, uint32_t id) const; void fix_up_shader_inputs_outputs(); @@ -858,7 +987,7 @@ class CompilerMSL : public CompilerGLSL std::string entry_point_arg_stage_in(); void entry_point_args_builtin(std::string &args); void entry_point_args_discrete_descriptors(std::string &args); - std::string to_qualified_member_name(const SPIRType &type, uint32_t index); + std::string append_member_name(const std::string &qualifier, const SPIRType &type, uint32_t index); std::string ensure_valid_name(std::string name, std::string pfx); std::string to_sampler_expression(uint32_t id); std::string to_swizzle_expression(uint32_t id); @@ -872,11 +1001,14 @@ class CompilerMSL : public CompilerGLSL std::string member_attribute_qualifier(const SPIRType &type, uint32_t index); std::string member_location_attribute_qualifier(const SPIRType &type, uint32_t index); std::string argument_decl(const SPIRFunction::Parameter &arg); + const char *descriptor_address_space(uint32_t id, spv::StorageClass storage, const char *plain_address_space) const; std::string round_fp_tex_coords(std::string tex_coords, bool coord_is_fp); uint32_t get_metal_resource_index(SPIRVariable &var, SPIRType::BaseType basetype, uint32_t plane = 0); uint32_t get_member_location(uint32_t type_id, uint32_t index, uint32_t *comp = nullptr) const; uint32_t get_or_allocate_builtin_input_member_location(spv::BuiltIn builtin, uint32_t type_id, uint32_t index, uint32_t *comp = nullptr); + uint32_t get_or_allocate_builtin_output_member_location(spv::BuiltIn builtin, + uint32_t type_id, uint32_t index, uint32_t *comp = nullptr); uint32_t get_physical_tess_level_array_size(spv::BuiltIn builtin) const; @@ -912,7 +1044,7 @@ class CompilerMSL : public CompilerGLSL bool validate_member_packing_rules_msl(const SPIRType &type, uint32_t index) const; std::string get_argument_address_space(const SPIRVariable &argument); std::string get_type_address_space(const SPIRType &type, uint32_t id, bool argument = false); - const char *to_restrict(uint32_t id, bool space = true); + const char *to_restrict(uint32_t id, bool space); SPIRType &get_stage_in_struct_type(); SPIRType &get_stage_out_struct_type(); SPIRType &get_patch_stage_in_struct_type(); @@ -920,14 +1052,14 @@ class CompilerMSL : public CompilerGLSL std::string get_tess_factor_struct_name(); SPIRType &get_uint_type(); uint32_t get_uint_type_id(); - void emit_atomic_func_op(uint32_t result_type, uint32_t result_id, const char *op, uint32_t mem_order_1, - uint32_t mem_order_2, bool has_mem_order_2, uint32_t op0, uint32_t op1 = 0, + void emit_atomic_func_op(uint32_t result_type, uint32_t result_id, const char *op, spv::Op opcode, + uint32_t mem_order_1, uint32_t mem_order_2, bool has_mem_order_2, uint32_t op0, uint32_t op1 = 0, bool op1_is_pointer = false, bool op1_is_literal = false, uint32_t op2 = 0); const char *get_memory_order(uint32_t spv_mem_sem); void add_pragma_line(const std::string &line); void add_typedef_line(const std::string &line); void emit_barrier(uint32_t id_exe_scope, uint32_t id_mem_scope, uint32_t id_mem_sem); - void emit_array_copy(const std::string &lhs, uint32_t lhs_id, uint32_t rhs_id, + bool emit_array_copy(const char *expr, uint32_t lhs_id, uint32_t rhs_id, spv::StorageClass lhs_storage, spv::StorageClass rhs_storage) override; void build_implicit_builtins(); uint32_t build_constant_uint_array_pointer(); @@ -937,6 +1069,7 @@ class CompilerMSL : public CompilerGLSL uint32_t builtin_frag_coord_id = 0; uint32_t builtin_sample_id_id = 0; uint32_t builtin_sample_mask_id = 0; + uint32_t builtin_helper_invocation_id = 0; uint32_t builtin_vertex_idx_id = 0; uint32_t builtin_base_vertex_id = 0; uint32_t builtin_instance_idx_id = 0; @@ -961,6 +1094,7 @@ class CompilerMSL : public CompilerGLSL uint32_t argument_buffer_padding_sampler_type_id = 0; bool does_shader_write_sample_mask = false; + bool frag_shader_needs_discard_checks = false; void cast_to_variable_store(uint32_t target_id, std::string &expr, const SPIRType &expr_type) override; void cast_from_variable_load(uint32_t source_id, std::string &expr, const SPIRType &expr_type) override; @@ -969,9 +1103,11 @@ class CompilerMSL : public CompilerGLSL void analyze_sampled_image_usage(); bool access_chain_needs_stage_io_builtin_translation(uint32_t base) override; - void prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, spv::StorageClass storage, + bool prepare_access_chain_for_scalar_access(std::string &expr, const SPIRType &type, spv::StorageClass storage, bool &is_packed) override; void fix_up_interpolant_access_chain(const uint32_t *ops, uint32_t length); + void check_physical_type_cast(std::string &expr, const SPIRType *type, uint32_t physical_type) override; + bool emit_tessellation_access_chain(const uint32_t *ops, uint32_t length); bool emit_tessellation_io_load(uint32_t result_type, uint32_t id, uint32_t ptr); bool is_out_of_bounds_tessellation_level(uint32_t id_lhs); @@ -985,12 +1121,17 @@ class CompilerMSL : public CompilerGLSL Options msl_options; std::set spv_function_implementations; // Must be ordered to ensure declarations are in a specific order. - std::map inputs_by_location; - std::unordered_map inputs_by_builtin; + std::map inputs_by_location; + std::unordered_map inputs_by_builtin; + std::map outputs_by_location; + std::unordered_map outputs_by_builtin; std::unordered_set location_inputs_in_use; std::unordered_set location_inputs_in_use_fallback; + std::unordered_set location_outputs_in_use; + std::unordered_set location_outputs_in_use_fallback; std::unordered_map fragment_output_components; std::unordered_map builtin_to_automatic_input_location; + std::unordered_map builtin_to_automatic_output_location; std::set pragma_lines; std::set typedef_lines; SmallVector vars_needing_early_declaration; @@ -1010,6 +1151,8 @@ class CompilerMSL : public CompilerGLSL VariableID patch_stage_out_var_id = 0; VariableID stage_in_ptr_var_id = 0; VariableID stage_out_ptr_var_id = 0; + VariableID tess_level_inner_var_id = 0; + VariableID tess_level_outer_var_id = 0; VariableID stage_out_masked_builtin_type_id = 0; // Handle HLSL-style 0-based vertex/instance index. @@ -1036,6 +1179,7 @@ class CompilerMSL : public CompilerGLSL bool needs_subgroup_invocation_id = false; bool needs_subgroup_size = false; bool needs_sample_id = false; + bool needs_helper_invocation = false; std::string qual_pos_var_name; std::string stage_in_var_name = "in"; std::string stage_out_var_name = "out"; @@ -1048,6 +1192,7 @@ class CompilerMSL : public CompilerGLSL std::string input_wg_var_name = "gl_in"; std::string input_buffer_var_name = "spvIn"; std::string output_buffer_var_name = "spvOut"; + std::string patch_input_buffer_var_name = "spvPatchIn"; std::string patch_output_buffer_var_name = "spvPatchOut"; std::string tess_factor_buffer_var_name = "spvTessLevel"; std::string index_buffer_var_name = "spvIndices"; @@ -1059,9 +1204,13 @@ class CompilerMSL : public CompilerGLSL const MSLConstexprSampler *find_constexpr_sampler(uint32_t id) const; std::unordered_set buffers_requiring_array_length; - SmallVector buffer_arrays; - std::unordered_set atomic_image_vars; // Emulate texture2D atomic operations + SmallVector> buffer_aliases_argument; + SmallVector buffer_aliases_discrete; + std::unordered_set atomic_image_vars_emulated; // Emulate texture2D atomic operations std::unordered_set pull_model_inputs; + std::unordered_set recursive_inputs; + + SmallVector entry_point_bindings; // Must be ordered since array is in a specific order. std::map> buffers_requiring_dynamic_offset; @@ -1100,6 +1249,16 @@ class CompilerMSL : public CompilerGLSL bool variable_storage_requires_stage_io(spv::StorageClass storage) const; + bool needs_manual_helper_invocation_updates() const + { + return msl_options.manual_helper_invocation_updates && msl_options.supports_msl_version(2, 3); + } + bool needs_frag_discard_checks() const + { + return get_execution_model() == spv::ExecutionModelFragment && msl_options.supports_msl_version(2, 3) && + msl_options.check_discarded_frag_stores && frag_shader_needs_discard_checks; + } + bool has_additional_fixed_sample_mask() const { return msl_options.additional_fixed_sample_mask != 0xffffffff; } std::string additional_fixed_sample_mask_str() const; @@ -1117,13 +1276,16 @@ class CompilerMSL : public CompilerGLSL CompilerMSL &compiler; std::unordered_map result_types; - std::unordered_map image_pointers; // Emulate texture2D atomic operations + std::unordered_map image_pointers_emulated; // Emulate texture2D atomic operations bool suppress_missing_prototypes = false; bool uses_atomics = false; - bool uses_resource_write = false; + bool uses_image_write = false; + bool uses_buffer_write = false; + bool uses_discard = false; bool needs_subgroup_invocation_id = false; bool needs_subgroup_size = false; bool needs_sample_id = false; + bool needs_helper_invocation = false; }; // OpcodeHandler that scans for uses of sampled images diff --git a/src/libraries/spirv_cross/spirv_parser.cpp b/src/libraries/spirv_cross/spirv_parser.cpp index 4faf3ca08..6108dbb65 100644 --- a/src/libraries/spirv_cross/spirv_parser.cpp +++ b/src/libraries/spirv_cross/spirv_parser.cpp @@ -31,7 +31,7 @@ namespace SPIRV_CROSS_NAMESPACE { Parser::Parser(vector spirv) { - ir.spirv = move(spirv); + ir.spirv = std::move(spirv); } Parser::Parser(const uint32_t *spirv_data, size_t word_count) @@ -68,6 +68,7 @@ static bool is_valid_spirv_version(uint32_t version) case 0x10300: // SPIR-V 1.3 case 0x10400: // SPIR-V 1.4 case 0x10500: // SPIR-V 1.5 + case 0x10600: // SPIR-V 1.6 return true; default: @@ -182,6 +183,15 @@ void Parser::parse(const Instruction &instruction) auto op = static_cast(instruction.op); uint32_t length = instruction.length; + // HACK for glslang that might emit OpEmitMeshTasksEXT followed by return / branch. + // Instead of failing hard, just ignore it. + if (ignore_trailing_block_opcodes) + { + ignore_trailing_block_opcodes = false; + if (op == OpReturn || op == OpBranch || op == OpUnreachable) + return; + } + switch (op) { case OpSourceContinued: @@ -258,29 +268,37 @@ void Parser::parse(const Instruction &instruction) case OpExtension: { auto ext = extract_string(ir.spirv, instruction.offset); - ir.declared_extensions.push_back(move(ext)); + ir.declared_extensions.push_back(std::move(ext)); break; } case OpExtInstImport: { uint32_t id = ops[0]; + + SPIRExtension::Extension spirv_ext = SPIRExtension::Unsupported; + auto ext = extract_string(ir.spirv, instruction.offset + 1); if (ext == "GLSL.std.450") - set(id, SPIRExtension::GLSL); + spirv_ext = SPIRExtension::GLSL; else if (ext == "DebugInfo") - set(id, SPIRExtension::SPV_debug_info); + spirv_ext = SPIRExtension::SPV_debug_info; else if (ext == "SPV_AMD_shader_ballot") - set(id, SPIRExtension::SPV_AMD_shader_ballot); + spirv_ext = SPIRExtension::SPV_AMD_shader_ballot; else if (ext == "SPV_AMD_shader_explicit_vertex_parameter") - set(id, SPIRExtension::SPV_AMD_shader_explicit_vertex_parameter); + spirv_ext = SPIRExtension::SPV_AMD_shader_explicit_vertex_parameter; else if (ext == "SPV_AMD_shader_trinary_minmax") - set(id, SPIRExtension::SPV_AMD_shader_trinary_minmax); + spirv_ext = SPIRExtension::SPV_AMD_shader_trinary_minmax; else if (ext == "SPV_AMD_gcn_shader") - set(id, SPIRExtension::SPV_AMD_gcn_shader); - else - set(id, SPIRExtension::Unsupported); - + spirv_ext = SPIRExtension::SPV_AMD_gcn_shader; + else if (ext == "NonSemantic.DebugPrintf") + spirv_ext = SPIRExtension::NonSemanticDebugPrintf; + else if (ext == "NonSemantic.Shader.DebugInfo.100") + spirv_ext = SPIRExtension::NonSemanticShaderDebugInfo; + else if (ext.find("NonSemantic.") == 0) + spirv_ext = SPIRExtension::NonSemanticGeneric; + + set(id, spirv_ext); // Other SPIR-V extensions which have ExtInstrs are currently not supported. break; @@ -290,7 +308,15 @@ void Parser::parse(const Instruction &instruction) { // The SPIR-V debug information extended instructions might come at global scope. if (current_block) + { current_block->ops.push_back(instruction); + if (length >= 2) + { + const auto *type = maybe_get(ops[0]); + if (type) + ir.load_type_width.insert({ ops[1], type->width }); + } + } break; } @@ -338,12 +364,32 @@ void Parser::parse(const Instruction &instruction) execution.output_vertices = ops[2]; break; + case ExecutionModeOutputPrimitivesEXT: + execution.output_primitives = ops[2]; + break; + default: break; } break; } + case OpExecutionModeId: + { + auto &execution = ir.entry_points[ops[0]]; + auto mode = static_cast(ops[1]); + execution.flags.set(mode); + + if (mode == ExecutionModeLocalSizeId) + { + execution.workgroup_size.id_x = ops[2]; + execution.workgroup_size.id_y = ops[3]; + execution.workgroup_size.id_z = ops[4]; + } + + break; + } + case OpName: { uint32_t id = ops[0]; @@ -471,7 +517,7 @@ void Parser::parse(const Instruction &instruction) case OpTypeVoid: { uint32_t id = ops[0]; - auto &type = set(id); + auto &type = set(id, op); type.basetype = SPIRType::Void; break; } @@ -479,7 +525,7 @@ void Parser::parse(const Instruction &instruction) case OpTypeBool: { uint32_t id = ops[0]; - auto &type = set(id); + auto &type = set(id, op); type.basetype = SPIRType::Boolean; type.width = 1; break; @@ -489,7 +535,7 @@ void Parser::parse(const Instruction &instruction) { uint32_t id = ops[0]; uint32_t width = ops[1]; - auto &type = set(id); + auto &type = set(id, op); if (width == 64) type.basetype = SPIRType::Double; else if (width == 32) @@ -507,7 +553,7 @@ void Parser::parse(const Instruction &instruction) uint32_t id = ops[0]; uint32_t width = ops[1]; bool signedness = ops[2] != 0; - auto &type = set(id); + auto &type = set(id, op); type.basetype = signedness ? to_signed_basetype(width) : to_unsigned_basetype(width); type.width = width; break; @@ -522,9 +568,9 @@ void Parser::parse(const Instruction &instruction) uint32_t vecsize = ops[2]; auto &base = get(ops[1]); - auto &vecbase = set(id); + auto &vecbase = set(id, base); - vecbase = base; + vecbase.op = op; vecbase.vecsize = vecsize; vecbase.self = id; vecbase.parent_type = ops[1]; @@ -537,9 +583,9 @@ void Parser::parse(const Instruction &instruction) uint32_t colcount = ops[2]; auto &base = get(ops[1]); - auto &matrixbase = set(id); + auto &matrixbase = set(id, base); - matrixbase = base; + matrixbase.op = op; matrixbase.columns = colcount; matrixbase.self = id; matrixbase.parent_type = ops[1]; @@ -549,12 +595,11 @@ void Parser::parse(const Instruction &instruction) case OpTypeArray: { uint32_t id = ops[0]; - auto &arraybase = set(id); - uint32_t tid = ops[1]; auto &base = get(tid); + auto &arraybase = set(id, base); - arraybase = base; + arraybase.op = op; arraybase.parent_type = tid; uint32_t cid = ops[2]; @@ -569,7 +614,9 @@ void Parser::parse(const Instruction &instruction) arraybase.array_size_literal.push_back(literal); arraybase.array.push_back(literal ? c->scalar() : cid); - // Do NOT set arraybase.self! + + // .self resolves down to non-array/non-pointer type. + arraybase.self = base.self; break; } @@ -578,25 +625,27 @@ void Parser::parse(const Instruction &instruction) uint32_t id = ops[0]; auto &base = get(ops[1]); - auto &arraybase = set(id); + auto &arraybase = set(id, base); // We're copying type information into Array types, so we'll need a fixup for any physical pointer // references. if (base.forward_pointer) forward_pointer_fixups.push_back({ id, ops[1] }); - arraybase = base; + arraybase.op = op; arraybase.array.push_back(0); arraybase.array_size_literal.push_back(true); arraybase.parent_type = ops[1]; - // Do NOT set arraybase.self! + + // .self resolves down to non-array/non-pointer type. + arraybase.self = base.self; break; } case OpTypeImage: { uint32_t id = ops[0]; - auto &type = set(id); + auto &type = set(id, op); type.basetype = SPIRType::Image; type.image.type = ops[1]; type.image.dim = static_cast(ops[2]); @@ -613,7 +662,7 @@ void Parser::parse(const Instruction &instruction) { uint32_t id = ops[0]; uint32_t imagetype = ops[1]; - auto &type = set(id); + auto &type = set(id, op); type = get(imagetype); type.basetype = SPIRType::SampledImage; type.self = id; @@ -623,7 +672,7 @@ void Parser::parse(const Instruction &instruction) case OpTypeSampler: { uint32_t id = ops[0]; - auto &type = set(id); + auto &type = set(id, op); type.basetype = SPIRType::Sampler; break; } @@ -636,10 +685,13 @@ void Parser::parse(const Instruction &instruction) // We won't be able to compile it, but we shouldn't crash when parsing. // We should be able to reflect. auto *base = maybe_get(ops[2]); - auto &ptrbase = set(id); + auto &ptrbase = set(id, op); if (base) + { ptrbase = *base; + ptrbase.op = op; + } ptrbase.pointer = true; ptrbase.pointer_depth++; @@ -660,7 +712,7 @@ void Parser::parse(const Instruction &instruction) case OpTypeForwardPointer: { uint32_t id = ops[0]; - auto &ptrbase = set(id); + auto &ptrbase = set(id, op); ptrbase.pointer = true; ptrbase.pointer_depth++; ptrbase.storage = static_cast(ops[1]); @@ -675,7 +727,7 @@ void Parser::parse(const Instruction &instruction) case OpTypeStruct: { uint32_t id = ops[0]; - auto &type = set(id); + auto &type = set(id, op); type.basetype = SPIRType::Struct; for (uint32_t i = 1; i < length; i++) type.member_types.push_back(ops[i]); @@ -724,7 +776,7 @@ void Parser::parse(const Instruction &instruction) case OpTypeAccelerationStructureKHR: { uint32_t id = ops[0]; - auto &type = set(id); + auto &type = set(id, op); type.basetype = SPIRType::AccelerationStructure; break; } @@ -732,7 +784,7 @@ void Parser::parse(const Instruction &instruction) case OpTypeRayQueryKHR: { uint32_t id = ops[0]; - auto &type = set(id); + auto &type = set(id, op); type.basetype = SPIRType::RayQuery; break; } @@ -979,10 +1031,9 @@ void Parser::parse(const Instruction &instruction) { uint32_t ids = ir.increase_bound_by(2); - SPIRType type; + auto &type = set(ids, OpTypeInt); type.basetype = SPIRType::Int; type.width = 32; - set(ids, type); auto &c = set(ids + 1, ids); current_block->condition = c.self; @@ -993,7 +1044,16 @@ void Parser::parse(const Instruction &instruction) } else { - ir.block_meta[current_block->next_block] &= ~ParsedIR::BLOCK_META_SELECTION_MERGE_BIT; + // Collapse loops if we have to. + bool collapsed_loop = current_block->true_block == current_block->merge_block && + current_block->merge == SPIRBlock::MergeLoop; + + if (collapsed_loop) + { + ir.block_meta[current_block->merge_block] &= ~ParsedIR::BLOCK_META_LOOP_MERGE_BIT; + ir.block_meta[current_block->continue_block] &= ~ParsedIR::BLOCK_META_CONTINUE_BIT; + } + current_block->next_block = current_block->true_block; current_block->condition = 0; current_block->true_block = 0; @@ -1042,6 +1102,7 @@ void Parser::parse(const Instruction &instruction) } case OpKill: + case OpTerminateInvocation: { if (!current_block) SPIRV_CROSS_THROW("Trying to end a non-existing block."); @@ -1066,6 +1127,18 @@ void Parser::parse(const Instruction &instruction) current_block = nullptr; break; + case OpEmitMeshTasksEXT: + if (!current_block) + SPIRV_CROSS_THROW("Trying to end a non-existing block."); + current_block->terminator = SPIRBlock::EmitMeshTasks; + for (uint32_t i = 0; i < 3; i++) + current_block->mesh.groups[i] = ops[i]; + current_block->mesh.payload = length >= 4 ? ops[3] : 0; + current_block = nullptr; + // Currently glslang is bugged and does not treat EmitMeshTasksEXT as a terminator. + ignore_trailing_block_opcodes = true; + break; + case OpReturn: { if (!current_block) @@ -1194,10 +1267,9 @@ void Parser::parse(const Instruction &instruction) { const auto *type = maybe_get(ops[0]); if (type) - { ir.load_type_width.insert({ ops[1], type->width }); - } } + if (!current_block) SPIRV_CROSS_THROW("Currently no block to insert opcode."); diff --git a/src/libraries/spirv_cross/spirv_parser.hpp b/src/libraries/spirv_cross/spirv_parser.hpp index d72fc71d8..dabc0e224 100644 --- a/src/libraries/spirv_cross/spirv_parser.hpp +++ b/src/libraries/spirv_cross/spirv_parser.hpp @@ -46,6 +46,8 @@ class Parser ParsedIR ir; SPIRFunction *current_function = nullptr; SPIRBlock *current_block = nullptr; + // For workarounds. + bool ignore_trailing_block_opcodes = false; void parse(const Instruction &instr); const uint32_t *stream(const Instruction &instr) const; diff --git a/src/libraries/spirv_cross/spirv_reflect.cpp b/src/libraries/spirv_cross/spirv_reflect.cpp index ee2fe930d..b02773722 100644 --- a/src/libraries/spirv_cross/spirv_reflect.cpp +++ b/src/libraries/spirv_cross/spirv_reflect.cpp @@ -291,8 +291,8 @@ static bool naturally_emit_type(const SPIRType &type) bool CompilerReflection::type_is_reference(const SPIRType &type) const { // Physical pointers and arrays of physical pointers need to refer to the pointee's type. - return type_is_top_level_physical_pointer(type) || - (!type.array.empty() && type_is_top_level_physical_pointer(get(type.parent_type))); + return is_physical_pointer(type) || + (type_is_array_of_pointers(type) && type.storage == StorageClassPhysicalStorageBuffer); } void CompilerReflection::emit_types() @@ -341,7 +341,7 @@ void CompilerReflection::emit_type(uint32_t type_id, bool &emitted_open_tag) json_stream->emit_json_key_object("_" + std::to_string(type_id)); json_stream->emit_json_key_value("name", name); - if (type_is_top_level_physical_pointer(type)) + if (is_physical_pointer(type)) { json_stream->emit_json_key_value("type", "_" + std::to_string(type.parent_type)); json_stream->emit_json_key_value("physical_pointer", true); @@ -404,7 +404,7 @@ void CompilerReflection::emit_type_member(const SPIRType &type, uint32_t index) void CompilerReflection::emit_type_array(const SPIRType &type) { - if (!type_is_top_level_physical_pointer(type) && !type.array.empty()) + if (!is_physical_pointer(type) && !type.array.empty()) { json_stream->emit_json_key_array("array"); // Note that we emit the zeros here as a means of identifying @@ -444,7 +444,7 @@ void CompilerReflection::emit_type_member_qualifiers(const SPIRType &type, uint3 if (dec.decoration_flags.get(DecorationRowMajor)) json_stream->emit_json_key_value("row_major", true); - if (type_is_top_level_physical_pointer(membertype)) + if (is_physical_pointer(membertype)) json_stream->emit_json_key_value("physical_pointer", true); } } @@ -587,18 +587,18 @@ void CompilerReflection::emit_resources(const char *tag, const SmallVectoremit_json_key_value("writeonly", true); - if (buffer_flags.get(DecorationNonWritable)) - json_stream->emit_json_key_value("readonly", true); - if (buffer_flags.get(DecorationRestrict)) - json_stream->emit_json_key_value("restrict", true); - if (buffer_flags.get(DecorationCoherent)) - json_stream->emit_json_key_value("coherent", true); - } + Bitset qualifier_mask = ssbo_block ? get_buffer_block_flags(res.id) : mask; + + if (qualifier_mask.get(DecorationNonReadable)) + json_stream->emit_json_key_value("writeonly", true); + if (qualifier_mask.get(DecorationNonWritable)) + json_stream->emit_json_key_value("readonly", true); + if (qualifier_mask.get(DecorationRestrict)) + json_stream->emit_json_key_value("restrict", true); + if (qualifier_mask.get(DecorationCoherent)) + json_stream->emit_json_key_value("coherent", true); + if (qualifier_mask.get(DecorationVolatile)) + json_stream->emit_json_key_value("volatile", true); } emit_type_array(type); From 8e361aefbfd8d18c6705e2a08a272efe332eb405 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sun, 7 Jan 2024 21:22:13 -0400 Subject: [PATCH 16/29] SPIRV-Cross: remove C API files The spirv header for those is outdated and can cause warnings because its contents don't match the other spirv header files in SPIRV-Cross and glslang --- .../xcode/liblove.xcodeproj/project.pbxproj | 14 - src/libraries/spirv_cross/spirv.h | 2568 --------------- src/libraries/spirv_cross/spirv_cross_c.cpp | 2875 ----------------- src/libraries/spirv_cross/spirv_cross_c.h | 1097 ------- 4 files changed, 6554 deletions(-) delete mode 100644 src/libraries/spirv_cross/spirv.h delete mode 100644 src/libraries/spirv_cross/spirv_cross_c.cpp delete mode 100644 src/libraries/spirv_cross/spirv_cross_c.h diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index 7a206b70e..c67adf2fd 100644 --- a/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/platform/xcode/liblove.xcodeproj/project.pbxproj @@ -679,8 +679,6 @@ FA18CF2B23DCF67900263725 /* spirv_cross_util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA18CF0423DCF67800263725 /* spirv_cross_util.cpp */; }; FA18CF2C23DCF67900263725 /* spirv_cross.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA18CF0523DCF67800263725 /* spirv_cross.cpp */; }; FA18CF2D23DCF67900263725 /* spirv_cross.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA18CF0523DCF67800263725 /* spirv_cross.cpp */; }; - FA18CF2E23DCF67900263725 /* spirv_cross_c.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA18CF0623DCF67800263725 /* spirv_cross_c.cpp */; }; - FA18CF2F23DCF67900263725 /* spirv_cross_c.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA18CF0623DCF67800263725 /* spirv_cross_c.cpp */; }; FA18CF3023DCF67900263725 /* spirv_hlsl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA18CF0723DCF67800263725 /* spirv_hlsl.cpp */; }; FA18CF3123DCF67900263725 /* spirv_hlsl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA18CF0723DCF67800263725 /* spirv_hlsl.cpp */; }; FA18CF3223DCF67900263725 /* spirv_cfg.hpp in Headers */ = {isa = PBXBuildFile; fileRef = FA18CF0823DCF67800263725 /* spirv_cfg.hpp */; }; @@ -688,8 +686,6 @@ FA18CF3423DCF67900263725 /* spirv_cpp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA18CF0923DCF67800263725 /* spirv_cpp.cpp */; }; FA18CF3523DCF67900263725 /* spirv_cross_parsed_ir.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA18CF0A23DCF67800263725 /* spirv_cross_parsed_ir.cpp */; }; FA18CF3623DCF67900263725 /* spirv_cross_parsed_ir.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA18CF0A23DCF67800263725 /* spirv_cross_parsed_ir.cpp */; }; - FA18CF3723DCF67900263725 /* spirv.h in Headers */ = {isa = PBXBuildFile; fileRef = FA18CF0B23DCF67800263725 /* spirv.h */; }; - FA18CF3823DCF67900263725 /* spirv_cross_c.h in Headers */ = {isa = PBXBuildFile; fileRef = FA18CF0C23DCF67800263725 /* spirv_cross_c.h */; }; FA18CF3923DCF67900263725 /* spirv_msl.hpp in Headers */ = {isa = PBXBuildFile; fileRef = FA18CF0D23DCF67800263725 /* spirv_msl.hpp */; }; FA18CF3A23DCF67900263725 /* spirv_reflect.hpp in Headers */ = {isa = PBXBuildFile; fileRef = FA18CF0E23DCF67800263725 /* spirv_reflect.hpp */; }; FA18CF3B23DCF67900263725 /* spirv_cross_util.hpp in Headers */ = {isa = PBXBuildFile; fileRef = FA18CF0F23DCF67800263725 /* spirv_cross_util.hpp */; }; @@ -1839,13 +1835,10 @@ FA18CF0323DCF67800263725 /* spirv_msl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spirv_msl.cpp; sourceTree = ""; }; FA18CF0423DCF67800263725 /* spirv_cross_util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spirv_cross_util.cpp; sourceTree = ""; }; FA18CF0523DCF67800263725 /* spirv_cross.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spirv_cross.cpp; sourceTree = ""; }; - FA18CF0623DCF67800263725 /* spirv_cross_c.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spirv_cross_c.cpp; sourceTree = ""; }; FA18CF0723DCF67800263725 /* spirv_hlsl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spirv_hlsl.cpp; sourceTree = ""; }; FA18CF0823DCF67800263725 /* spirv_cfg.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = spirv_cfg.hpp; sourceTree = ""; }; FA18CF0923DCF67800263725 /* spirv_cpp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spirv_cpp.cpp; sourceTree = ""; }; FA18CF0A23DCF67800263725 /* spirv_cross_parsed_ir.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = spirv_cross_parsed_ir.cpp; sourceTree = ""; }; - FA18CF0B23DCF67800263725 /* spirv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spirv.h; sourceTree = ""; }; - FA18CF0C23DCF67800263725 /* spirv_cross_c.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = spirv_cross_c.h; sourceTree = ""; }; FA18CF0D23DCF67800263725 /* spirv_msl.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = spirv_msl.hpp; sourceTree = ""; }; FA18CF0E23DCF67800263725 /* spirv_reflect.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = spirv_reflect.hpp; sourceTree = ""; }; FA18CF0F23DCF67800263725 /* spirv_cross_util.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = spirv_cross_util.hpp; sourceTree = ""; }; @@ -3458,8 +3451,6 @@ FA18CF1423DCF67800263725 /* spirv_common.hpp */, FA18CF0923DCF67800263725 /* spirv_cpp.cpp */, FA18CF0023DCF67800263725 /* spirv_cpp.hpp */, - FA18CF0623DCF67800263725 /* spirv_cross_c.cpp */, - FA18CF0C23DCF67800263725 /* spirv_cross_c.h */, FA18CF1223DCF67800263725 /* spirv_cross_containers.hpp */, FA18CEF423DCF67800263725 /* spirv_cross_error_handling.hpp */, FA18CF0A23DCF67800263725 /* spirv_cross_parsed_ir.cpp */, @@ -3478,7 +3469,6 @@ FA18CEF223DCF67800263725 /* spirv_parser.hpp */, FA18CF0223DCF67800263725 /* spirv_reflect.cpp */, FA18CF0E23DCF67800263725 /* spirv_reflect.hpp */, - FA18CF0B23DCF67800263725 /* spirv.h */, FA18CEFE23DCF67800263725 /* spirv.hpp */, ); path = spirv_cross; @@ -4155,7 +4145,6 @@ FAF140AB1E20934C00F898D2 /* SymbolTable.h in Headers */, FA18CF1E23DCF67900263725 /* external_interface.h in Headers */, FA0B7ED71A95902D000E1D17 /* Timer.h in Headers */, - FA18CF3723DCF67900263725 /* spirv.h in Headers */, FA0B7AC31A958EA3000E1D17 /* list.h in Headers */, FA0B7B2D1A958EA3000E1D17 /* core.h in Headers */, FA1E88841DF363DB00E808AA /* Filter.h in Headers */, @@ -4399,7 +4388,6 @@ FA18CF2023DCF67900263725 /* spirv_hlsl.hpp in Headers */, FA0B7D271A95902C000E1D17 /* wrap_Font.h in Headers */, FA0B7DAA1A95902C000E1D17 /* PVRHandler.h in Headers */, - FA18CF3823DCF67900263725 /* spirv_cross_c.h in Headers */, FA27B3B51B498151008A9DCE /* wrap_Video.h in Headers */, FABDA9BC2552448300B5C523 /* b2_fixture.h in Headers */, FA0B7D7B1A95902C000E1D17 /* Quad.h in Headers */, @@ -5015,7 +5003,6 @@ FACA02F81F5E39760084B28F /* CompressedData.cpp in Sources */, FA0B7ADA1A958EA3000E1D17 /* glad.cpp in Sources */, FAF140541E20934C00F898D2 /* CodeGen.cpp in Sources */, - FA18CF2F23DCF67900263725 /* spirv_cross_c.cpp in Sources */, FA0B7E1F1A95902C000E1D17 /* Physics.cpp in Sources */, FA6A2B7B1F60B8250074C308 /* wrap_ByteData.cpp in Sources */, FA0B7E821A95902C000E1D17 /* Shape.cpp in Sources */, @@ -5302,7 +5289,6 @@ FA0B7E301A95902C000E1D17 /* Shape.cpp in Sources */, FA93C4541F315B960087CCD4 /* FormatHandler.cpp in Sources */, FA0B7E481A95902C000E1D17 /* wrap_DistanceJoint.cpp in Sources */, - FA18CF2E23DCF67900263725 /* spirv_cross_c.cpp in Sources */, FABDA9A72552448300B5C523 /* b2_motor_joint.cpp in Sources */, FA0B792F1A958E3B000E1D17 /* Module.cpp in Sources */, FA0B7E2A1A95902C000E1D17 /* RevoluteJoint.cpp in Sources */, diff --git a/src/libraries/spirv_cross/spirv.h b/src/libraries/spirv_cross/spirv.h deleted file mode 100644 index 5b6e8aaf4..000000000 --- a/src/libraries/spirv_cross/spirv.h +++ /dev/null @@ -1,2568 +0,0 @@ -/* -** Copyright (c) 2014-2020 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. -*/ - -/* -** This header is automatically generated by the same tool that creates -** the Binary Section of the SPIR-V specification. -*/ - -/* -** Enumeration tokens for SPIR-V, in various styles: -** C, C++, C++11, JSON, Lua, Python, C#, D, Beef -** -** - C will have tokens with a "Spv" prefix, e.g.: SpvSourceLanguageGLSL -** - C++ will have tokens in the "spv" name space, e.g.: spv::SourceLanguageGLSL -** - C++11 will use enum classes in the spv namespace, e.g.: spv::SourceLanguage::GLSL -** - Lua will use tables, e.g.: spv.SourceLanguage.GLSL -** - Python will use dictionaries, e.g.: spv['SourceLanguage']['GLSL'] -** - C# will use enum classes in the Specification class located in the "Spv" namespace, -** e.g.: Spv.Specification.SourceLanguage.GLSL -** - D will have tokens under the "spv" module, e.g: spv.SourceLanguage.GLSL -** - Beef will use enum classes in the Specification class located in the "Spv" namespace, -** e.g.: Spv.Specification.SourceLanguage.GLSL -** -** Some tokens act like mask values, which can be OR'd together, -** while others are mutually exclusive. The mask-like ones have -** "Mask" in their name, and a parallel enum that has the shift -** amount (1 << x) for each corresponding enumerant. -*/ - -#ifndef spirv_H -#define spirv_H - -typedef unsigned int SpvId; - -#define SPV_VERSION 0x10600 -#define SPV_REVISION 1 - -static const unsigned int SpvMagicNumber = 0x07230203; -static const unsigned int SpvVersion = 0x00010600; -static const unsigned int SpvRevision = 1; -static const unsigned int SpvOpCodeMask = 0xffff; -static const unsigned int SpvWordCountShift = 16; - -typedef enum SpvSourceLanguage_ { - SpvSourceLanguageUnknown = 0, - SpvSourceLanguageESSL = 1, - SpvSourceLanguageGLSL = 2, - SpvSourceLanguageOpenCL_C = 3, - SpvSourceLanguageOpenCL_CPP = 4, - SpvSourceLanguageHLSL = 5, - SpvSourceLanguageCPP_for_OpenCL = 6, - SpvSourceLanguageSYCL = 7, - SpvSourceLanguageMax = 0x7fffffff, -} SpvSourceLanguage; - -typedef enum SpvExecutionModel_ { - SpvExecutionModelVertex = 0, - SpvExecutionModelTessellationControl = 1, - SpvExecutionModelTessellationEvaluation = 2, - SpvExecutionModelGeometry = 3, - SpvExecutionModelFragment = 4, - SpvExecutionModelGLCompute = 5, - SpvExecutionModelKernel = 6, - SpvExecutionModelTaskNV = 5267, - SpvExecutionModelMeshNV = 5268, - SpvExecutionModelRayGenerationKHR = 5313, - SpvExecutionModelRayGenerationNV = 5313, - SpvExecutionModelIntersectionKHR = 5314, - SpvExecutionModelIntersectionNV = 5314, - SpvExecutionModelAnyHitKHR = 5315, - SpvExecutionModelAnyHitNV = 5315, - SpvExecutionModelClosestHitKHR = 5316, - SpvExecutionModelClosestHitNV = 5316, - SpvExecutionModelMissKHR = 5317, - SpvExecutionModelMissNV = 5317, - SpvExecutionModelCallableKHR = 5318, - SpvExecutionModelCallableNV = 5318, - SpvExecutionModelTaskEXT = 5364, - SpvExecutionModelMeshEXT = 5365, - SpvExecutionModelMax = 0x7fffffff, -} SpvExecutionModel; - -typedef enum SpvAddressingModel_ { - SpvAddressingModelLogical = 0, - SpvAddressingModelPhysical32 = 1, - SpvAddressingModelPhysical64 = 2, - SpvAddressingModelPhysicalStorageBuffer64 = 5348, - SpvAddressingModelPhysicalStorageBuffer64EXT = 5348, - SpvAddressingModelMax = 0x7fffffff, -} SpvAddressingModel; - -typedef enum SpvMemoryModel_ { - SpvMemoryModelSimple = 0, - SpvMemoryModelGLSL450 = 1, - SpvMemoryModelOpenCL = 2, - SpvMemoryModelVulkan = 3, - SpvMemoryModelVulkanKHR = 3, - SpvMemoryModelMax = 0x7fffffff, -} SpvMemoryModel; - -typedef enum SpvExecutionMode_ { - SpvExecutionModeInvocations = 0, - SpvExecutionModeSpacingEqual = 1, - SpvExecutionModeSpacingFractionalEven = 2, - SpvExecutionModeSpacingFractionalOdd = 3, - SpvExecutionModeVertexOrderCw = 4, - SpvExecutionModeVertexOrderCcw = 5, - SpvExecutionModePixelCenterInteger = 6, - SpvExecutionModeOriginUpperLeft = 7, - SpvExecutionModeOriginLowerLeft = 8, - SpvExecutionModeEarlyFragmentTests = 9, - SpvExecutionModePointMode = 10, - SpvExecutionModeXfb = 11, - SpvExecutionModeDepthReplacing = 12, - SpvExecutionModeDepthGreater = 14, - SpvExecutionModeDepthLess = 15, - SpvExecutionModeDepthUnchanged = 16, - SpvExecutionModeLocalSize = 17, - SpvExecutionModeLocalSizeHint = 18, - SpvExecutionModeInputPoints = 19, - SpvExecutionModeInputLines = 20, - SpvExecutionModeInputLinesAdjacency = 21, - SpvExecutionModeTriangles = 22, - SpvExecutionModeInputTrianglesAdjacency = 23, - SpvExecutionModeQuads = 24, - SpvExecutionModeIsolines = 25, - SpvExecutionModeOutputVertices = 26, - SpvExecutionModeOutputPoints = 27, - SpvExecutionModeOutputLineStrip = 28, - SpvExecutionModeOutputTriangleStrip = 29, - SpvExecutionModeVecTypeHint = 30, - SpvExecutionModeContractionOff = 31, - SpvExecutionModeInitializer = 33, - SpvExecutionModeFinalizer = 34, - SpvExecutionModeSubgroupSize = 35, - SpvExecutionModeSubgroupsPerWorkgroup = 36, - SpvExecutionModeSubgroupsPerWorkgroupId = 37, - SpvExecutionModeLocalSizeId = 38, - SpvExecutionModeLocalSizeHintId = 39, - SpvExecutionModeSubgroupUniformControlFlowKHR = 4421, - SpvExecutionModePostDepthCoverage = 4446, - SpvExecutionModeDenormPreserve = 4459, - SpvExecutionModeDenormFlushToZero = 4460, - SpvExecutionModeSignedZeroInfNanPreserve = 4461, - SpvExecutionModeRoundingModeRTE = 4462, - SpvExecutionModeRoundingModeRTZ = 4463, - SpvExecutionModeEarlyAndLateFragmentTestsAMD = 5017, - SpvExecutionModeStencilRefReplacingEXT = 5027, - SpvExecutionModeStencilRefUnchangedFrontAMD = 5079, - SpvExecutionModeStencilRefGreaterFrontAMD = 5080, - SpvExecutionModeStencilRefLessFrontAMD = 5081, - SpvExecutionModeStencilRefUnchangedBackAMD = 5082, - SpvExecutionModeStencilRefGreaterBackAMD = 5083, - SpvExecutionModeStencilRefLessBackAMD = 5084, - SpvExecutionModeOutputLinesEXT = 5269, - SpvExecutionModeOutputLinesNV = 5269, - SpvExecutionModeOutputPrimitivesEXT = 5270, - SpvExecutionModeOutputPrimitivesNV = 5270, - SpvExecutionModeDerivativeGroupQuadsNV = 5289, - SpvExecutionModeDerivativeGroupLinearNV = 5290, - SpvExecutionModeOutputTrianglesEXT = 5298, - SpvExecutionModeOutputTrianglesNV = 5298, - SpvExecutionModePixelInterlockOrderedEXT = 5366, - SpvExecutionModePixelInterlockUnorderedEXT = 5367, - SpvExecutionModeSampleInterlockOrderedEXT = 5368, - SpvExecutionModeSampleInterlockUnorderedEXT = 5369, - SpvExecutionModeShadingRateInterlockOrderedEXT = 5370, - SpvExecutionModeShadingRateInterlockUnorderedEXT = 5371, - SpvExecutionModeSharedLocalMemorySizeINTEL = 5618, - SpvExecutionModeRoundingModeRTPINTEL = 5620, - SpvExecutionModeRoundingModeRTNINTEL = 5621, - SpvExecutionModeFloatingPointModeALTINTEL = 5622, - SpvExecutionModeFloatingPointModeIEEEINTEL = 5623, - SpvExecutionModeMaxWorkgroupSizeINTEL = 5893, - SpvExecutionModeMaxWorkDimINTEL = 5894, - SpvExecutionModeNoGlobalOffsetINTEL = 5895, - SpvExecutionModeNumSIMDWorkitemsINTEL = 5896, - SpvExecutionModeSchedulerTargetFmaxMhzINTEL = 5903, - SpvExecutionModeNamedBarrierCountINTEL = 6417, - SpvExecutionModeMax = 0x7fffffff, -} SpvExecutionMode; - -typedef enum SpvStorageClass_ { - SpvStorageClassUniformConstant = 0, - SpvStorageClassInput = 1, - SpvStorageClassUniform = 2, - SpvStorageClassOutput = 3, - SpvStorageClassWorkgroup = 4, - SpvStorageClassCrossWorkgroup = 5, - SpvStorageClassPrivate = 6, - SpvStorageClassFunction = 7, - SpvStorageClassGeneric = 8, - SpvStorageClassPushConstant = 9, - SpvStorageClassAtomicCounter = 10, - SpvStorageClassImage = 11, - SpvStorageClassStorageBuffer = 12, - SpvStorageClassCallableDataKHR = 5328, - SpvStorageClassCallableDataNV = 5328, - SpvStorageClassIncomingCallableDataKHR = 5329, - SpvStorageClassIncomingCallableDataNV = 5329, - SpvStorageClassRayPayloadKHR = 5338, - SpvStorageClassRayPayloadNV = 5338, - SpvStorageClassHitAttributeKHR = 5339, - SpvStorageClassHitAttributeNV = 5339, - SpvStorageClassIncomingRayPayloadKHR = 5342, - SpvStorageClassIncomingRayPayloadNV = 5342, - SpvStorageClassShaderRecordBufferKHR = 5343, - SpvStorageClassShaderRecordBufferNV = 5343, - SpvStorageClassPhysicalStorageBuffer = 5349, - SpvStorageClassPhysicalStorageBufferEXT = 5349, - SpvStorageClassTaskPayloadWorkgroupEXT = 5402, - SpvStorageClassCodeSectionINTEL = 5605, - SpvStorageClassDeviceOnlyINTEL = 5936, - SpvStorageClassHostOnlyINTEL = 5937, - SpvStorageClassMax = 0x7fffffff, -} SpvStorageClass; - -typedef enum SpvDim_ { - SpvDim1D = 0, - SpvDim2D = 1, - SpvDim3D = 2, - SpvDimCube = 3, - SpvDimRect = 4, - SpvDimBuffer = 5, - SpvDimSubpassData = 6, - SpvDimMax = 0x7fffffff, -} SpvDim; - -typedef enum SpvSamplerAddressingMode_ { - SpvSamplerAddressingModeNone = 0, - SpvSamplerAddressingModeClampToEdge = 1, - SpvSamplerAddressingModeClamp = 2, - SpvSamplerAddressingModeRepeat = 3, - SpvSamplerAddressingModeRepeatMirrored = 4, - SpvSamplerAddressingModeMax = 0x7fffffff, -} SpvSamplerAddressingMode; - -typedef enum SpvSamplerFilterMode_ { - SpvSamplerFilterModeNearest = 0, - SpvSamplerFilterModeLinear = 1, - SpvSamplerFilterModeMax = 0x7fffffff, -} SpvSamplerFilterMode; - -typedef enum SpvImageFormat_ { - SpvImageFormatUnknown = 0, - SpvImageFormatRgba32f = 1, - SpvImageFormatRgba16f = 2, - SpvImageFormatR32f = 3, - SpvImageFormatRgba8 = 4, - SpvImageFormatRgba8Snorm = 5, - SpvImageFormatRg32f = 6, - SpvImageFormatRg16f = 7, - SpvImageFormatR11fG11fB10f = 8, - SpvImageFormatR16f = 9, - SpvImageFormatRgba16 = 10, - SpvImageFormatRgb10A2 = 11, - SpvImageFormatRg16 = 12, - SpvImageFormatRg8 = 13, - SpvImageFormatR16 = 14, - SpvImageFormatR8 = 15, - SpvImageFormatRgba16Snorm = 16, - SpvImageFormatRg16Snorm = 17, - SpvImageFormatRg8Snorm = 18, - SpvImageFormatR16Snorm = 19, - SpvImageFormatR8Snorm = 20, - SpvImageFormatRgba32i = 21, - SpvImageFormatRgba16i = 22, - SpvImageFormatRgba8i = 23, - SpvImageFormatR32i = 24, - SpvImageFormatRg32i = 25, - SpvImageFormatRg16i = 26, - SpvImageFormatRg8i = 27, - SpvImageFormatR16i = 28, - SpvImageFormatR8i = 29, - SpvImageFormatRgba32ui = 30, - SpvImageFormatRgba16ui = 31, - SpvImageFormatRgba8ui = 32, - SpvImageFormatR32ui = 33, - SpvImageFormatRgb10a2ui = 34, - SpvImageFormatRg32ui = 35, - SpvImageFormatRg16ui = 36, - SpvImageFormatRg8ui = 37, - SpvImageFormatR16ui = 38, - SpvImageFormatR8ui = 39, - SpvImageFormatR64ui = 40, - SpvImageFormatR64i = 41, - SpvImageFormatMax = 0x7fffffff, -} SpvImageFormat; - -typedef enum SpvImageChannelOrder_ { - SpvImageChannelOrderR = 0, - SpvImageChannelOrderA = 1, - SpvImageChannelOrderRG = 2, - SpvImageChannelOrderRA = 3, - SpvImageChannelOrderRGB = 4, - SpvImageChannelOrderRGBA = 5, - SpvImageChannelOrderBGRA = 6, - SpvImageChannelOrderARGB = 7, - SpvImageChannelOrderIntensity = 8, - SpvImageChannelOrderLuminance = 9, - SpvImageChannelOrderRx = 10, - SpvImageChannelOrderRGx = 11, - SpvImageChannelOrderRGBx = 12, - SpvImageChannelOrderDepth = 13, - SpvImageChannelOrderDepthStencil = 14, - SpvImageChannelOrdersRGB = 15, - SpvImageChannelOrdersRGBx = 16, - SpvImageChannelOrdersRGBA = 17, - SpvImageChannelOrdersBGRA = 18, - SpvImageChannelOrderABGR = 19, - SpvImageChannelOrderMax = 0x7fffffff, -} SpvImageChannelOrder; - -typedef enum SpvImageChannelDataType_ { - SpvImageChannelDataTypeSnormInt8 = 0, - SpvImageChannelDataTypeSnormInt16 = 1, - SpvImageChannelDataTypeUnormInt8 = 2, - SpvImageChannelDataTypeUnormInt16 = 3, - SpvImageChannelDataTypeUnormShort565 = 4, - SpvImageChannelDataTypeUnormShort555 = 5, - SpvImageChannelDataTypeUnormInt101010 = 6, - SpvImageChannelDataTypeSignedInt8 = 7, - SpvImageChannelDataTypeSignedInt16 = 8, - SpvImageChannelDataTypeSignedInt32 = 9, - SpvImageChannelDataTypeUnsignedInt8 = 10, - SpvImageChannelDataTypeUnsignedInt16 = 11, - SpvImageChannelDataTypeUnsignedInt32 = 12, - SpvImageChannelDataTypeHalfFloat = 13, - SpvImageChannelDataTypeFloat = 14, - SpvImageChannelDataTypeUnormInt24 = 15, - SpvImageChannelDataTypeUnormInt101010_2 = 16, - SpvImageChannelDataTypeMax = 0x7fffffff, -} SpvImageChannelDataType; - -typedef enum SpvImageOperandsShift_ { - SpvImageOperandsBiasShift = 0, - SpvImageOperandsLodShift = 1, - SpvImageOperandsGradShift = 2, - SpvImageOperandsConstOffsetShift = 3, - SpvImageOperandsOffsetShift = 4, - SpvImageOperandsConstOffsetsShift = 5, - SpvImageOperandsSampleShift = 6, - SpvImageOperandsMinLodShift = 7, - SpvImageOperandsMakeTexelAvailableShift = 8, - SpvImageOperandsMakeTexelAvailableKHRShift = 8, - SpvImageOperandsMakeTexelVisibleShift = 9, - SpvImageOperandsMakeTexelVisibleKHRShift = 9, - SpvImageOperandsNonPrivateTexelShift = 10, - SpvImageOperandsNonPrivateTexelKHRShift = 10, - SpvImageOperandsVolatileTexelShift = 11, - SpvImageOperandsVolatileTexelKHRShift = 11, - SpvImageOperandsSignExtendShift = 12, - SpvImageOperandsZeroExtendShift = 13, - SpvImageOperandsNontemporalShift = 14, - SpvImageOperandsOffsetsShift = 16, - SpvImageOperandsMax = 0x7fffffff, -} SpvImageOperandsShift; - -typedef enum SpvImageOperandsMask_ { - SpvImageOperandsMaskNone = 0, - SpvImageOperandsBiasMask = 0x00000001, - SpvImageOperandsLodMask = 0x00000002, - SpvImageOperandsGradMask = 0x00000004, - SpvImageOperandsConstOffsetMask = 0x00000008, - SpvImageOperandsOffsetMask = 0x00000010, - SpvImageOperandsConstOffsetsMask = 0x00000020, - SpvImageOperandsSampleMask = 0x00000040, - SpvImageOperandsMinLodMask = 0x00000080, - SpvImageOperandsMakeTexelAvailableMask = 0x00000100, - SpvImageOperandsMakeTexelAvailableKHRMask = 0x00000100, - SpvImageOperandsMakeTexelVisibleMask = 0x00000200, - SpvImageOperandsMakeTexelVisibleKHRMask = 0x00000200, - SpvImageOperandsNonPrivateTexelMask = 0x00000400, - SpvImageOperandsNonPrivateTexelKHRMask = 0x00000400, - SpvImageOperandsVolatileTexelMask = 0x00000800, - SpvImageOperandsVolatileTexelKHRMask = 0x00000800, - SpvImageOperandsSignExtendMask = 0x00001000, - SpvImageOperandsZeroExtendMask = 0x00002000, - SpvImageOperandsNontemporalMask = 0x00004000, - SpvImageOperandsOffsetsMask = 0x00010000, -} SpvImageOperandsMask; - -typedef enum SpvFPFastMathModeShift_ { - SpvFPFastMathModeNotNaNShift = 0, - SpvFPFastMathModeNotInfShift = 1, - SpvFPFastMathModeNSZShift = 2, - SpvFPFastMathModeAllowRecipShift = 3, - SpvFPFastMathModeFastShift = 4, - SpvFPFastMathModeAllowContractFastINTELShift = 16, - SpvFPFastMathModeAllowReassocINTELShift = 17, - SpvFPFastMathModeMax = 0x7fffffff, -} SpvFPFastMathModeShift; - -typedef enum SpvFPFastMathModeMask_ { - SpvFPFastMathModeMaskNone = 0, - SpvFPFastMathModeNotNaNMask = 0x00000001, - SpvFPFastMathModeNotInfMask = 0x00000002, - SpvFPFastMathModeNSZMask = 0x00000004, - SpvFPFastMathModeAllowRecipMask = 0x00000008, - SpvFPFastMathModeFastMask = 0x00000010, - SpvFPFastMathModeAllowContractFastINTELMask = 0x00010000, - SpvFPFastMathModeAllowReassocINTELMask = 0x00020000, -} SpvFPFastMathModeMask; - -typedef enum SpvFPRoundingMode_ { - SpvFPRoundingModeRTE = 0, - SpvFPRoundingModeRTZ = 1, - SpvFPRoundingModeRTP = 2, - SpvFPRoundingModeRTN = 3, - SpvFPRoundingModeMax = 0x7fffffff, -} SpvFPRoundingMode; - -typedef enum SpvLinkageType_ { - SpvLinkageTypeExport = 0, - SpvLinkageTypeImport = 1, - SpvLinkageTypeLinkOnceODR = 2, - SpvLinkageTypeMax = 0x7fffffff, -} SpvLinkageType; - -typedef enum SpvAccessQualifier_ { - SpvAccessQualifierReadOnly = 0, - SpvAccessQualifierWriteOnly = 1, - SpvAccessQualifierReadWrite = 2, - SpvAccessQualifierMax = 0x7fffffff, -} SpvAccessQualifier; - -typedef enum SpvFunctionParameterAttribute_ { - SpvFunctionParameterAttributeZext = 0, - SpvFunctionParameterAttributeSext = 1, - SpvFunctionParameterAttributeByVal = 2, - SpvFunctionParameterAttributeSret = 3, - SpvFunctionParameterAttributeNoAlias = 4, - SpvFunctionParameterAttributeNoCapture = 5, - SpvFunctionParameterAttributeNoWrite = 6, - SpvFunctionParameterAttributeNoReadWrite = 7, - SpvFunctionParameterAttributeMax = 0x7fffffff, -} SpvFunctionParameterAttribute; - -typedef enum SpvDecoration_ { - SpvDecorationRelaxedPrecision = 0, - SpvDecorationSpecId = 1, - SpvDecorationBlock = 2, - SpvDecorationBufferBlock = 3, - SpvDecorationRowMajor = 4, - SpvDecorationColMajor = 5, - SpvDecorationArrayStride = 6, - SpvDecorationMatrixStride = 7, - SpvDecorationGLSLShared = 8, - SpvDecorationGLSLPacked = 9, - SpvDecorationCPacked = 10, - SpvDecorationBuiltIn = 11, - SpvDecorationNoPerspective = 13, - SpvDecorationFlat = 14, - SpvDecorationPatch = 15, - SpvDecorationCentroid = 16, - SpvDecorationSample = 17, - SpvDecorationInvariant = 18, - SpvDecorationRestrict = 19, - SpvDecorationAliased = 20, - SpvDecorationVolatile = 21, - SpvDecorationConstant = 22, - SpvDecorationCoherent = 23, - SpvDecorationNonWritable = 24, - SpvDecorationNonReadable = 25, - SpvDecorationUniform = 26, - SpvDecorationUniformId = 27, - SpvDecorationSaturatedConversion = 28, - SpvDecorationStream = 29, - SpvDecorationLocation = 30, - SpvDecorationComponent = 31, - SpvDecorationIndex = 32, - SpvDecorationBinding = 33, - SpvDecorationDescriptorSet = 34, - SpvDecorationOffset = 35, - SpvDecorationXfbBuffer = 36, - SpvDecorationXfbStride = 37, - SpvDecorationFuncParamAttr = 38, - SpvDecorationFPRoundingMode = 39, - SpvDecorationFPFastMathMode = 40, - SpvDecorationLinkageAttributes = 41, - SpvDecorationNoContraction = 42, - SpvDecorationInputAttachmentIndex = 43, - SpvDecorationAlignment = 44, - SpvDecorationMaxByteOffset = 45, - SpvDecorationAlignmentId = 46, - SpvDecorationMaxByteOffsetId = 47, - SpvDecorationNoSignedWrap = 4469, - SpvDecorationNoUnsignedWrap = 4470, - SpvDecorationExplicitInterpAMD = 4999, - SpvDecorationOverrideCoverageNV = 5248, - SpvDecorationPassthroughNV = 5250, - SpvDecorationViewportRelativeNV = 5252, - SpvDecorationSecondaryViewportRelativeNV = 5256, - SpvDecorationPerPrimitiveEXT = 5271, - SpvDecorationPerPrimitiveNV = 5271, - SpvDecorationPerViewNV = 5272, - SpvDecorationPerTaskNV = 5273, - SpvDecorationPerVertexKHR = 5285, - SpvDecorationPerVertexNV = 5285, - SpvDecorationNonUniform = 5300, - SpvDecorationNonUniformEXT = 5300, - SpvDecorationRestrictPointer = 5355, - SpvDecorationRestrictPointerEXT = 5355, - SpvDecorationAliasedPointer = 5356, - SpvDecorationAliasedPointerEXT = 5356, - SpvDecorationBindlessSamplerNV = 5398, - SpvDecorationBindlessImageNV = 5399, - SpvDecorationBoundSamplerNV = 5400, - SpvDecorationBoundImageNV = 5401, - SpvDecorationSIMTCallINTEL = 5599, - SpvDecorationReferencedIndirectlyINTEL = 5602, - SpvDecorationClobberINTEL = 5607, - SpvDecorationSideEffectsINTEL = 5608, - SpvDecorationVectorComputeVariableINTEL = 5624, - SpvDecorationFuncParamIOKindINTEL = 5625, - SpvDecorationVectorComputeFunctionINTEL = 5626, - SpvDecorationStackCallINTEL = 5627, - SpvDecorationGlobalVariableOffsetINTEL = 5628, - SpvDecorationCounterBuffer = 5634, - SpvDecorationHlslCounterBufferGOOGLE = 5634, - SpvDecorationHlslSemanticGOOGLE = 5635, - SpvDecorationUserSemantic = 5635, - SpvDecorationUserTypeGOOGLE = 5636, - SpvDecorationFunctionRoundingModeINTEL = 5822, - SpvDecorationFunctionDenormModeINTEL = 5823, - SpvDecorationRegisterINTEL = 5825, - SpvDecorationMemoryINTEL = 5826, - SpvDecorationNumbanksINTEL = 5827, - SpvDecorationBankwidthINTEL = 5828, - SpvDecorationMaxPrivateCopiesINTEL = 5829, - SpvDecorationSinglepumpINTEL = 5830, - SpvDecorationDoublepumpINTEL = 5831, - SpvDecorationMaxReplicatesINTEL = 5832, - SpvDecorationSimpleDualPortINTEL = 5833, - SpvDecorationMergeINTEL = 5834, - SpvDecorationBankBitsINTEL = 5835, - SpvDecorationForcePow2DepthINTEL = 5836, - SpvDecorationBurstCoalesceINTEL = 5899, - SpvDecorationCacheSizeINTEL = 5900, - SpvDecorationDontStaticallyCoalesceINTEL = 5901, - SpvDecorationPrefetchINTEL = 5902, - SpvDecorationStallEnableINTEL = 5905, - SpvDecorationFuseLoopsInFunctionINTEL = 5907, - SpvDecorationAliasScopeINTEL = 5914, - SpvDecorationNoAliasINTEL = 5915, - SpvDecorationBufferLocationINTEL = 5921, - SpvDecorationIOPipeStorageINTEL = 5944, - SpvDecorationFunctionFloatingPointModeINTEL = 6080, - SpvDecorationSingleElementVectorINTEL = 6085, - SpvDecorationVectorComputeCallableFunctionINTEL = 6087, - SpvDecorationMediaBlockIOINTEL = 6140, - SpvDecorationMax = 0x7fffffff, -} SpvDecoration; - -typedef enum SpvBuiltIn_ { - SpvBuiltInPosition = 0, - SpvBuiltInPointSize = 1, - SpvBuiltInClipDistance = 3, - SpvBuiltInCullDistance = 4, - SpvBuiltInVertexId = 5, - SpvBuiltInInstanceId = 6, - SpvBuiltInPrimitiveId = 7, - SpvBuiltInInvocationId = 8, - SpvBuiltInLayer = 9, - SpvBuiltInViewportIndex = 10, - SpvBuiltInTessLevelOuter = 11, - SpvBuiltInTessLevelInner = 12, - SpvBuiltInTessCoord = 13, - SpvBuiltInPatchVertices = 14, - SpvBuiltInFragCoord = 15, - SpvBuiltInPointCoord = 16, - SpvBuiltInFrontFacing = 17, - SpvBuiltInSampleId = 18, - SpvBuiltInSamplePosition = 19, - SpvBuiltInSampleMask = 20, - SpvBuiltInFragDepth = 22, - SpvBuiltInHelperInvocation = 23, - SpvBuiltInNumWorkgroups = 24, - SpvBuiltInWorkgroupSize = 25, - SpvBuiltInWorkgroupId = 26, - SpvBuiltInLocalInvocationId = 27, - SpvBuiltInGlobalInvocationId = 28, - SpvBuiltInLocalInvocationIndex = 29, - SpvBuiltInWorkDim = 30, - SpvBuiltInGlobalSize = 31, - SpvBuiltInEnqueuedWorkgroupSize = 32, - SpvBuiltInGlobalOffset = 33, - SpvBuiltInGlobalLinearId = 34, - SpvBuiltInSubgroupSize = 36, - SpvBuiltInSubgroupMaxSize = 37, - SpvBuiltInNumSubgroups = 38, - SpvBuiltInNumEnqueuedSubgroups = 39, - SpvBuiltInSubgroupId = 40, - SpvBuiltInSubgroupLocalInvocationId = 41, - SpvBuiltInVertexIndex = 42, - SpvBuiltInInstanceIndex = 43, - SpvBuiltInSubgroupEqMask = 4416, - SpvBuiltInSubgroupEqMaskKHR = 4416, - SpvBuiltInSubgroupGeMask = 4417, - SpvBuiltInSubgroupGeMaskKHR = 4417, - SpvBuiltInSubgroupGtMask = 4418, - SpvBuiltInSubgroupGtMaskKHR = 4418, - SpvBuiltInSubgroupLeMask = 4419, - SpvBuiltInSubgroupLeMaskKHR = 4419, - SpvBuiltInSubgroupLtMask = 4420, - SpvBuiltInSubgroupLtMaskKHR = 4420, - SpvBuiltInBaseVertex = 4424, - SpvBuiltInBaseInstance = 4425, - SpvBuiltInDrawIndex = 4426, - SpvBuiltInPrimitiveShadingRateKHR = 4432, - SpvBuiltInDeviceIndex = 4438, - SpvBuiltInViewIndex = 4440, - SpvBuiltInShadingRateKHR = 4444, - SpvBuiltInBaryCoordNoPerspAMD = 4992, - SpvBuiltInBaryCoordNoPerspCentroidAMD = 4993, - SpvBuiltInBaryCoordNoPerspSampleAMD = 4994, - SpvBuiltInBaryCoordSmoothAMD = 4995, - SpvBuiltInBaryCoordSmoothCentroidAMD = 4996, - SpvBuiltInBaryCoordSmoothSampleAMD = 4997, - SpvBuiltInBaryCoordPullModelAMD = 4998, - SpvBuiltInFragStencilRefEXT = 5014, - SpvBuiltInViewportMaskNV = 5253, - SpvBuiltInSecondaryPositionNV = 5257, - SpvBuiltInSecondaryViewportMaskNV = 5258, - SpvBuiltInPositionPerViewNV = 5261, - SpvBuiltInViewportMaskPerViewNV = 5262, - SpvBuiltInFullyCoveredEXT = 5264, - SpvBuiltInTaskCountNV = 5274, - SpvBuiltInPrimitiveCountNV = 5275, - SpvBuiltInPrimitiveIndicesNV = 5276, - SpvBuiltInClipDistancePerViewNV = 5277, - SpvBuiltInCullDistancePerViewNV = 5278, - SpvBuiltInLayerPerViewNV = 5279, - SpvBuiltInMeshViewCountNV = 5280, - SpvBuiltInMeshViewIndicesNV = 5281, - SpvBuiltInBaryCoordKHR = 5286, - SpvBuiltInBaryCoordNV = 5286, - SpvBuiltInBaryCoordNoPerspKHR = 5287, - SpvBuiltInBaryCoordNoPerspNV = 5287, - SpvBuiltInFragSizeEXT = 5292, - SpvBuiltInFragmentSizeNV = 5292, - SpvBuiltInFragInvocationCountEXT = 5293, - SpvBuiltInInvocationsPerPixelNV = 5293, - SpvBuiltInPrimitivePointIndicesEXT = 5294, - SpvBuiltInPrimitiveLineIndicesEXT = 5295, - SpvBuiltInPrimitiveTriangleIndicesEXT = 5296, - SpvBuiltInCullPrimitiveEXT = 5299, - SpvBuiltInLaunchIdKHR = 5319, - SpvBuiltInLaunchIdNV = 5319, - SpvBuiltInLaunchSizeKHR = 5320, - SpvBuiltInLaunchSizeNV = 5320, - SpvBuiltInWorldRayOriginKHR = 5321, - SpvBuiltInWorldRayOriginNV = 5321, - SpvBuiltInWorldRayDirectionKHR = 5322, - SpvBuiltInWorldRayDirectionNV = 5322, - SpvBuiltInObjectRayOriginKHR = 5323, - SpvBuiltInObjectRayOriginNV = 5323, - SpvBuiltInObjectRayDirectionKHR = 5324, - SpvBuiltInObjectRayDirectionNV = 5324, - SpvBuiltInRayTminKHR = 5325, - SpvBuiltInRayTminNV = 5325, - SpvBuiltInRayTmaxKHR = 5326, - SpvBuiltInRayTmaxNV = 5326, - SpvBuiltInInstanceCustomIndexKHR = 5327, - SpvBuiltInInstanceCustomIndexNV = 5327, - SpvBuiltInObjectToWorldKHR = 5330, - SpvBuiltInObjectToWorldNV = 5330, - SpvBuiltInWorldToObjectKHR = 5331, - SpvBuiltInWorldToObjectNV = 5331, - SpvBuiltInHitTNV = 5332, - SpvBuiltInHitKindKHR = 5333, - SpvBuiltInHitKindNV = 5333, - SpvBuiltInCurrentRayTimeNV = 5334, - SpvBuiltInIncomingRayFlagsKHR = 5351, - SpvBuiltInIncomingRayFlagsNV = 5351, - SpvBuiltInRayGeometryIndexKHR = 5352, - SpvBuiltInWarpsPerSMNV = 5374, - SpvBuiltInSMCountNV = 5375, - SpvBuiltInWarpIDNV = 5376, - SpvBuiltInSMIDNV = 5377, - SpvBuiltInCullMaskKHR = 6021, - SpvBuiltInMax = 0x7fffffff, -} SpvBuiltIn; - -typedef enum SpvSelectionControlShift_ { - SpvSelectionControlFlattenShift = 0, - SpvSelectionControlDontFlattenShift = 1, - SpvSelectionControlMax = 0x7fffffff, -} SpvSelectionControlShift; - -typedef enum SpvSelectionControlMask_ { - SpvSelectionControlMaskNone = 0, - SpvSelectionControlFlattenMask = 0x00000001, - SpvSelectionControlDontFlattenMask = 0x00000002, -} SpvSelectionControlMask; - -typedef enum SpvLoopControlShift_ { - SpvLoopControlUnrollShift = 0, - SpvLoopControlDontUnrollShift = 1, - SpvLoopControlDependencyInfiniteShift = 2, - SpvLoopControlDependencyLengthShift = 3, - SpvLoopControlMinIterationsShift = 4, - SpvLoopControlMaxIterationsShift = 5, - SpvLoopControlIterationMultipleShift = 6, - SpvLoopControlPeelCountShift = 7, - SpvLoopControlPartialCountShift = 8, - SpvLoopControlInitiationIntervalINTELShift = 16, - SpvLoopControlMaxConcurrencyINTELShift = 17, - SpvLoopControlDependencyArrayINTELShift = 18, - SpvLoopControlPipelineEnableINTELShift = 19, - SpvLoopControlLoopCoalesceINTELShift = 20, - SpvLoopControlMaxInterleavingINTELShift = 21, - SpvLoopControlSpeculatedIterationsINTELShift = 22, - SpvLoopControlNoFusionINTELShift = 23, - SpvLoopControlMax = 0x7fffffff, -} SpvLoopControlShift; - -typedef enum SpvLoopControlMask_ { - SpvLoopControlMaskNone = 0, - SpvLoopControlUnrollMask = 0x00000001, - SpvLoopControlDontUnrollMask = 0x00000002, - SpvLoopControlDependencyInfiniteMask = 0x00000004, - SpvLoopControlDependencyLengthMask = 0x00000008, - SpvLoopControlMinIterationsMask = 0x00000010, - SpvLoopControlMaxIterationsMask = 0x00000020, - SpvLoopControlIterationMultipleMask = 0x00000040, - SpvLoopControlPeelCountMask = 0x00000080, - SpvLoopControlPartialCountMask = 0x00000100, - SpvLoopControlInitiationIntervalINTELMask = 0x00010000, - SpvLoopControlMaxConcurrencyINTELMask = 0x00020000, - SpvLoopControlDependencyArrayINTELMask = 0x00040000, - SpvLoopControlPipelineEnableINTELMask = 0x00080000, - SpvLoopControlLoopCoalesceINTELMask = 0x00100000, - SpvLoopControlMaxInterleavingINTELMask = 0x00200000, - SpvLoopControlSpeculatedIterationsINTELMask = 0x00400000, - SpvLoopControlNoFusionINTELMask = 0x00800000, -} SpvLoopControlMask; - -typedef enum SpvFunctionControlShift_ { - SpvFunctionControlInlineShift = 0, - SpvFunctionControlDontInlineShift = 1, - SpvFunctionControlPureShift = 2, - SpvFunctionControlConstShift = 3, - SpvFunctionControlOptNoneINTELShift = 16, - SpvFunctionControlMax = 0x7fffffff, -} SpvFunctionControlShift; - -typedef enum SpvFunctionControlMask_ { - SpvFunctionControlMaskNone = 0, - SpvFunctionControlInlineMask = 0x00000001, - SpvFunctionControlDontInlineMask = 0x00000002, - SpvFunctionControlPureMask = 0x00000004, - SpvFunctionControlConstMask = 0x00000008, - SpvFunctionControlOptNoneINTELMask = 0x00010000, -} SpvFunctionControlMask; - -typedef enum SpvMemorySemanticsShift_ { - SpvMemorySemanticsAcquireShift = 1, - SpvMemorySemanticsReleaseShift = 2, - SpvMemorySemanticsAcquireReleaseShift = 3, - SpvMemorySemanticsSequentiallyConsistentShift = 4, - SpvMemorySemanticsUniformMemoryShift = 6, - SpvMemorySemanticsSubgroupMemoryShift = 7, - SpvMemorySemanticsWorkgroupMemoryShift = 8, - SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, - SpvMemorySemanticsAtomicCounterMemoryShift = 10, - SpvMemorySemanticsImageMemoryShift = 11, - SpvMemorySemanticsOutputMemoryShift = 12, - SpvMemorySemanticsOutputMemoryKHRShift = 12, - SpvMemorySemanticsMakeAvailableShift = 13, - SpvMemorySemanticsMakeAvailableKHRShift = 13, - SpvMemorySemanticsMakeVisibleShift = 14, - SpvMemorySemanticsMakeVisibleKHRShift = 14, - SpvMemorySemanticsVolatileShift = 15, - SpvMemorySemanticsMax = 0x7fffffff, -} SpvMemorySemanticsShift; - -typedef enum SpvMemorySemanticsMask_ { - SpvMemorySemanticsMaskNone = 0, - SpvMemorySemanticsAcquireMask = 0x00000002, - SpvMemorySemanticsReleaseMask = 0x00000004, - SpvMemorySemanticsAcquireReleaseMask = 0x00000008, - SpvMemorySemanticsSequentiallyConsistentMask = 0x00000010, - SpvMemorySemanticsUniformMemoryMask = 0x00000040, - SpvMemorySemanticsSubgroupMemoryMask = 0x00000080, - SpvMemorySemanticsWorkgroupMemoryMask = 0x00000100, - SpvMemorySemanticsCrossWorkgroupMemoryMask = 0x00000200, - SpvMemorySemanticsAtomicCounterMemoryMask = 0x00000400, - SpvMemorySemanticsImageMemoryMask = 0x00000800, - SpvMemorySemanticsOutputMemoryMask = 0x00001000, - SpvMemorySemanticsOutputMemoryKHRMask = 0x00001000, - SpvMemorySemanticsMakeAvailableMask = 0x00002000, - SpvMemorySemanticsMakeAvailableKHRMask = 0x00002000, - SpvMemorySemanticsMakeVisibleMask = 0x00004000, - SpvMemorySemanticsMakeVisibleKHRMask = 0x00004000, - SpvMemorySemanticsVolatileMask = 0x00008000, -} SpvMemorySemanticsMask; - -typedef enum SpvMemoryAccessShift_ { - SpvMemoryAccessVolatileShift = 0, - SpvMemoryAccessAlignedShift = 1, - SpvMemoryAccessNontemporalShift = 2, - SpvMemoryAccessMakePointerAvailableShift = 3, - SpvMemoryAccessMakePointerAvailableKHRShift = 3, - SpvMemoryAccessMakePointerVisibleShift = 4, - SpvMemoryAccessMakePointerVisibleKHRShift = 4, - SpvMemoryAccessNonPrivatePointerShift = 5, - SpvMemoryAccessNonPrivatePointerKHRShift = 5, - SpvMemoryAccessAliasScopeINTELMaskShift = 16, - SpvMemoryAccessNoAliasINTELMaskShift = 17, - SpvMemoryAccessMax = 0x7fffffff, -} SpvMemoryAccessShift; - -typedef enum SpvMemoryAccessMask_ { - SpvMemoryAccessMaskNone = 0, - SpvMemoryAccessVolatileMask = 0x00000001, - SpvMemoryAccessAlignedMask = 0x00000002, - SpvMemoryAccessNontemporalMask = 0x00000004, - SpvMemoryAccessMakePointerAvailableMask = 0x00000008, - SpvMemoryAccessMakePointerAvailableKHRMask = 0x00000008, - SpvMemoryAccessMakePointerVisibleMask = 0x00000010, - SpvMemoryAccessMakePointerVisibleKHRMask = 0x00000010, - SpvMemoryAccessNonPrivatePointerMask = 0x00000020, - SpvMemoryAccessNonPrivatePointerKHRMask = 0x00000020, - SpvMemoryAccessAliasScopeINTELMaskMask = 0x00010000, - SpvMemoryAccessNoAliasINTELMaskMask = 0x00020000, -} SpvMemoryAccessMask; - -typedef enum SpvScope_ { - SpvScopeCrossDevice = 0, - SpvScopeDevice = 1, - SpvScopeWorkgroup = 2, - SpvScopeSubgroup = 3, - SpvScopeInvocation = 4, - SpvScopeQueueFamily = 5, - SpvScopeQueueFamilyKHR = 5, - SpvScopeShaderCallKHR = 6, - SpvScopeMax = 0x7fffffff, -} SpvScope; - -typedef enum SpvGroupOperation_ { - SpvGroupOperationReduce = 0, - SpvGroupOperationInclusiveScan = 1, - SpvGroupOperationExclusiveScan = 2, - SpvGroupOperationClusteredReduce = 3, - SpvGroupOperationPartitionedReduceNV = 6, - SpvGroupOperationPartitionedInclusiveScanNV = 7, - SpvGroupOperationPartitionedExclusiveScanNV = 8, - SpvGroupOperationMax = 0x7fffffff, -} SpvGroupOperation; - -typedef enum SpvKernelEnqueueFlags_ { - SpvKernelEnqueueFlagsNoWait = 0, - SpvKernelEnqueueFlagsWaitKernel = 1, - SpvKernelEnqueueFlagsWaitWorkGroup = 2, - SpvKernelEnqueueFlagsMax = 0x7fffffff, -} SpvKernelEnqueueFlags; - -typedef enum SpvKernelProfilingInfoShift_ { - SpvKernelProfilingInfoCmdExecTimeShift = 0, - SpvKernelProfilingInfoMax = 0x7fffffff, -} SpvKernelProfilingInfoShift; - -typedef enum SpvKernelProfilingInfoMask_ { - SpvKernelProfilingInfoMaskNone = 0, - SpvKernelProfilingInfoCmdExecTimeMask = 0x00000001, -} SpvKernelProfilingInfoMask; - -typedef enum SpvCapability_ { - SpvCapabilityMatrix = 0, - SpvCapabilityShader = 1, - SpvCapabilityGeometry = 2, - SpvCapabilityTessellation = 3, - SpvCapabilityAddresses = 4, - SpvCapabilityLinkage = 5, - SpvCapabilityKernel = 6, - SpvCapabilityVector16 = 7, - SpvCapabilityFloat16Buffer = 8, - SpvCapabilityFloat16 = 9, - SpvCapabilityFloat64 = 10, - SpvCapabilityInt64 = 11, - SpvCapabilityInt64Atomics = 12, - SpvCapabilityImageBasic = 13, - SpvCapabilityImageReadWrite = 14, - SpvCapabilityImageMipmap = 15, - SpvCapabilityPipes = 17, - SpvCapabilityGroups = 18, - SpvCapabilityDeviceEnqueue = 19, - SpvCapabilityLiteralSampler = 20, - SpvCapabilityAtomicStorage = 21, - SpvCapabilityInt16 = 22, - SpvCapabilityTessellationPointSize = 23, - SpvCapabilityGeometryPointSize = 24, - SpvCapabilityImageGatherExtended = 25, - SpvCapabilityStorageImageMultisample = 27, - SpvCapabilityUniformBufferArrayDynamicIndexing = 28, - SpvCapabilitySampledImageArrayDynamicIndexing = 29, - SpvCapabilityStorageBufferArrayDynamicIndexing = 30, - SpvCapabilityStorageImageArrayDynamicIndexing = 31, - SpvCapabilityClipDistance = 32, - SpvCapabilityCullDistance = 33, - SpvCapabilityImageCubeArray = 34, - SpvCapabilitySampleRateShading = 35, - SpvCapabilityImageRect = 36, - SpvCapabilitySampledRect = 37, - SpvCapabilityGenericPointer = 38, - SpvCapabilityInt8 = 39, - SpvCapabilityInputAttachment = 40, - SpvCapabilitySparseResidency = 41, - SpvCapabilityMinLod = 42, - SpvCapabilitySampled1D = 43, - SpvCapabilityImage1D = 44, - SpvCapabilitySampledCubeArray = 45, - SpvCapabilitySampledBuffer = 46, - SpvCapabilityImageBuffer = 47, - SpvCapabilityImageMSArray = 48, - SpvCapabilityStorageImageExtendedFormats = 49, - SpvCapabilityImageQuery = 50, - SpvCapabilityDerivativeControl = 51, - SpvCapabilityInterpolationFunction = 52, - SpvCapabilityTransformFeedback = 53, - SpvCapabilityGeometryStreams = 54, - SpvCapabilityStorageImageReadWithoutFormat = 55, - SpvCapabilityStorageImageWriteWithoutFormat = 56, - SpvCapabilityMultiViewport = 57, - SpvCapabilitySubgroupDispatch = 58, - SpvCapabilityNamedBarrier = 59, - SpvCapabilityPipeStorage = 60, - SpvCapabilityGroupNonUniform = 61, - SpvCapabilityGroupNonUniformVote = 62, - SpvCapabilityGroupNonUniformArithmetic = 63, - SpvCapabilityGroupNonUniformBallot = 64, - SpvCapabilityGroupNonUniformShuffle = 65, - SpvCapabilityGroupNonUniformShuffleRelative = 66, - SpvCapabilityGroupNonUniformClustered = 67, - SpvCapabilityGroupNonUniformQuad = 68, - SpvCapabilityShaderLayer = 69, - SpvCapabilityShaderViewportIndex = 70, - SpvCapabilityUniformDecoration = 71, - SpvCapabilityFragmentShadingRateKHR = 4422, - SpvCapabilitySubgroupBallotKHR = 4423, - SpvCapabilityDrawParameters = 4427, - SpvCapabilityWorkgroupMemoryExplicitLayoutKHR = 4428, - SpvCapabilityWorkgroupMemoryExplicitLayout8BitAccessKHR = 4429, - SpvCapabilityWorkgroupMemoryExplicitLayout16BitAccessKHR = 4430, - SpvCapabilitySubgroupVoteKHR = 4431, - SpvCapabilityStorageBuffer16BitAccess = 4433, - SpvCapabilityStorageUniformBufferBlock16 = 4433, - SpvCapabilityStorageUniform16 = 4434, - SpvCapabilityUniformAndStorageBuffer16BitAccess = 4434, - SpvCapabilityStoragePushConstant16 = 4435, - SpvCapabilityStorageInputOutput16 = 4436, - SpvCapabilityDeviceGroup = 4437, - SpvCapabilityMultiView = 4439, - SpvCapabilityVariablePointersStorageBuffer = 4441, - SpvCapabilityVariablePointers = 4442, - SpvCapabilityAtomicStorageOps = 4445, - SpvCapabilitySampleMaskPostDepthCoverage = 4447, - SpvCapabilityStorageBuffer8BitAccess = 4448, - SpvCapabilityUniformAndStorageBuffer8BitAccess = 4449, - SpvCapabilityStoragePushConstant8 = 4450, - SpvCapabilityDenormPreserve = 4464, - SpvCapabilityDenormFlushToZero = 4465, - SpvCapabilitySignedZeroInfNanPreserve = 4466, - SpvCapabilityRoundingModeRTE = 4467, - SpvCapabilityRoundingModeRTZ = 4468, - SpvCapabilityRayQueryProvisionalKHR = 4471, - SpvCapabilityRayQueryKHR = 4472, - SpvCapabilityRayTraversalPrimitiveCullingKHR = 4478, - SpvCapabilityRayTracingKHR = 4479, - SpvCapabilityFloat16ImageAMD = 5008, - SpvCapabilityImageGatherBiasLodAMD = 5009, - SpvCapabilityFragmentMaskAMD = 5010, - SpvCapabilityStencilExportEXT = 5013, - SpvCapabilityImageReadWriteLodAMD = 5015, - SpvCapabilityInt64ImageEXT = 5016, - SpvCapabilityShaderClockKHR = 5055, - SpvCapabilitySampleMaskOverrideCoverageNV = 5249, - SpvCapabilityGeometryShaderPassthroughNV = 5251, - SpvCapabilityShaderViewportIndexLayerEXT = 5254, - SpvCapabilityShaderViewportIndexLayerNV = 5254, - SpvCapabilityShaderViewportMaskNV = 5255, - SpvCapabilityShaderStereoViewNV = 5259, - SpvCapabilityPerViewAttributesNV = 5260, - SpvCapabilityFragmentFullyCoveredEXT = 5265, - SpvCapabilityMeshShadingNV = 5266, - SpvCapabilityImageFootprintNV = 5282, - SpvCapabilityMeshShadingEXT = 5283, - SpvCapabilityFragmentBarycentricKHR = 5284, - SpvCapabilityFragmentBarycentricNV = 5284, - SpvCapabilityComputeDerivativeGroupQuadsNV = 5288, - SpvCapabilityFragmentDensityEXT = 5291, - SpvCapabilityShadingRateNV = 5291, - SpvCapabilityGroupNonUniformPartitionedNV = 5297, - SpvCapabilityShaderNonUniform = 5301, - SpvCapabilityShaderNonUniformEXT = 5301, - SpvCapabilityRuntimeDescriptorArray = 5302, - SpvCapabilityRuntimeDescriptorArrayEXT = 5302, - SpvCapabilityInputAttachmentArrayDynamicIndexing = 5303, - SpvCapabilityInputAttachmentArrayDynamicIndexingEXT = 5303, - SpvCapabilityUniformTexelBufferArrayDynamicIndexing = 5304, - SpvCapabilityUniformTexelBufferArrayDynamicIndexingEXT = 5304, - SpvCapabilityStorageTexelBufferArrayDynamicIndexing = 5305, - SpvCapabilityStorageTexelBufferArrayDynamicIndexingEXT = 5305, - SpvCapabilityUniformBufferArrayNonUniformIndexing = 5306, - SpvCapabilityUniformBufferArrayNonUniformIndexingEXT = 5306, - SpvCapabilitySampledImageArrayNonUniformIndexing = 5307, - SpvCapabilitySampledImageArrayNonUniformIndexingEXT = 5307, - SpvCapabilityStorageBufferArrayNonUniformIndexing = 5308, - SpvCapabilityStorageBufferArrayNonUniformIndexingEXT = 5308, - SpvCapabilityStorageImageArrayNonUniformIndexing = 5309, - SpvCapabilityStorageImageArrayNonUniformIndexingEXT = 5309, - SpvCapabilityInputAttachmentArrayNonUniformIndexing = 5310, - SpvCapabilityInputAttachmentArrayNonUniformIndexingEXT = 5310, - SpvCapabilityUniformTexelBufferArrayNonUniformIndexing = 5311, - SpvCapabilityUniformTexelBufferArrayNonUniformIndexingEXT = 5311, - SpvCapabilityStorageTexelBufferArrayNonUniformIndexing = 5312, - SpvCapabilityStorageTexelBufferArrayNonUniformIndexingEXT = 5312, - SpvCapabilityRayTracingNV = 5340, - SpvCapabilityRayTracingMotionBlurNV = 5341, - SpvCapabilityVulkanMemoryModel = 5345, - SpvCapabilityVulkanMemoryModelKHR = 5345, - SpvCapabilityVulkanMemoryModelDeviceScope = 5346, - SpvCapabilityVulkanMemoryModelDeviceScopeKHR = 5346, - SpvCapabilityPhysicalStorageBufferAddresses = 5347, - SpvCapabilityPhysicalStorageBufferAddressesEXT = 5347, - SpvCapabilityComputeDerivativeGroupLinearNV = 5350, - SpvCapabilityRayTracingProvisionalKHR = 5353, - SpvCapabilityCooperativeMatrixNV = 5357, - SpvCapabilityFragmentShaderSampleInterlockEXT = 5363, - SpvCapabilityFragmentShaderShadingRateInterlockEXT = 5372, - SpvCapabilityShaderSMBuiltinsNV = 5373, - SpvCapabilityFragmentShaderPixelInterlockEXT = 5378, - SpvCapabilityDemoteToHelperInvocation = 5379, - SpvCapabilityDemoteToHelperInvocationEXT = 5379, - SpvCapabilityBindlessTextureNV = 5390, - SpvCapabilitySubgroupShuffleINTEL = 5568, - SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, - SpvCapabilitySubgroupImageBlockIOINTEL = 5570, - SpvCapabilitySubgroupImageMediaBlockIOINTEL = 5579, - SpvCapabilityRoundToInfinityINTEL = 5582, - SpvCapabilityFloatingPointModeINTEL = 5583, - SpvCapabilityIntegerFunctions2INTEL = 5584, - SpvCapabilityFunctionPointersINTEL = 5603, - SpvCapabilityIndirectReferencesINTEL = 5604, - SpvCapabilityAsmINTEL = 5606, - SpvCapabilityAtomicFloat32MinMaxEXT = 5612, - SpvCapabilityAtomicFloat64MinMaxEXT = 5613, - SpvCapabilityAtomicFloat16MinMaxEXT = 5616, - SpvCapabilityVectorComputeINTEL = 5617, - SpvCapabilityVectorAnyINTEL = 5619, - SpvCapabilityExpectAssumeKHR = 5629, - SpvCapabilitySubgroupAvcMotionEstimationINTEL = 5696, - SpvCapabilitySubgroupAvcMotionEstimationIntraINTEL = 5697, - SpvCapabilitySubgroupAvcMotionEstimationChromaINTEL = 5698, - SpvCapabilityVariableLengthArrayINTEL = 5817, - SpvCapabilityFunctionFloatControlINTEL = 5821, - SpvCapabilityFPGAMemoryAttributesINTEL = 5824, - SpvCapabilityFPFastMathModeINTEL = 5837, - SpvCapabilityArbitraryPrecisionIntegersINTEL = 5844, - SpvCapabilityArbitraryPrecisionFloatingPointINTEL = 5845, - SpvCapabilityUnstructuredLoopControlsINTEL = 5886, - SpvCapabilityFPGALoopControlsINTEL = 5888, - SpvCapabilityKernelAttributesINTEL = 5892, - SpvCapabilityFPGAKernelAttributesINTEL = 5897, - SpvCapabilityFPGAMemoryAccessesINTEL = 5898, - SpvCapabilityFPGAClusterAttributesINTEL = 5904, - SpvCapabilityLoopFuseINTEL = 5906, - SpvCapabilityMemoryAccessAliasingINTEL = 5910, - SpvCapabilityFPGABufferLocationINTEL = 5920, - SpvCapabilityArbitraryPrecisionFixedPointINTEL = 5922, - SpvCapabilityUSMStorageClassesINTEL = 5935, - SpvCapabilityIOPipesINTEL = 5943, - SpvCapabilityBlockingPipesINTEL = 5945, - SpvCapabilityFPGARegINTEL = 5948, - SpvCapabilityDotProductInputAll = 6016, - SpvCapabilityDotProductInputAllKHR = 6016, - SpvCapabilityDotProductInput4x8Bit = 6017, - SpvCapabilityDotProductInput4x8BitKHR = 6017, - SpvCapabilityDotProductInput4x8BitPacked = 6018, - SpvCapabilityDotProductInput4x8BitPackedKHR = 6018, - SpvCapabilityDotProduct = 6019, - SpvCapabilityDotProductKHR = 6019, - SpvCapabilityRayCullMaskKHR = 6020, - SpvCapabilityBitInstructions = 6025, - SpvCapabilityGroupNonUniformRotateKHR = 6026, - SpvCapabilityAtomicFloat32AddEXT = 6033, - SpvCapabilityAtomicFloat64AddEXT = 6034, - SpvCapabilityLongConstantCompositeINTEL = 6089, - SpvCapabilityOptNoneINTEL = 6094, - SpvCapabilityAtomicFloat16AddEXT = 6095, - SpvCapabilityDebugInfoModuleINTEL = 6114, - SpvCapabilitySplitBarrierINTEL = 6141, - SpvCapabilityGroupUniformArithmeticKHR = 6400, - SpvCapabilityMax = 0x7fffffff, -} SpvCapability; - -typedef enum SpvRayFlagsShift_ { - SpvRayFlagsOpaqueKHRShift = 0, - SpvRayFlagsNoOpaqueKHRShift = 1, - SpvRayFlagsTerminateOnFirstHitKHRShift = 2, - SpvRayFlagsSkipClosestHitShaderKHRShift = 3, - SpvRayFlagsCullBackFacingTrianglesKHRShift = 4, - SpvRayFlagsCullFrontFacingTrianglesKHRShift = 5, - SpvRayFlagsCullOpaqueKHRShift = 6, - SpvRayFlagsCullNoOpaqueKHRShift = 7, - SpvRayFlagsSkipTrianglesKHRShift = 8, - SpvRayFlagsSkipAABBsKHRShift = 9, - SpvRayFlagsMax = 0x7fffffff, -} SpvRayFlagsShift; - -typedef enum SpvRayFlagsMask_ { - SpvRayFlagsMaskNone = 0, - SpvRayFlagsOpaqueKHRMask = 0x00000001, - SpvRayFlagsNoOpaqueKHRMask = 0x00000002, - SpvRayFlagsTerminateOnFirstHitKHRMask = 0x00000004, - SpvRayFlagsSkipClosestHitShaderKHRMask = 0x00000008, - SpvRayFlagsCullBackFacingTrianglesKHRMask = 0x00000010, - SpvRayFlagsCullFrontFacingTrianglesKHRMask = 0x00000020, - SpvRayFlagsCullOpaqueKHRMask = 0x00000040, - SpvRayFlagsCullNoOpaqueKHRMask = 0x00000080, - SpvRayFlagsSkipTrianglesKHRMask = 0x00000100, - SpvRayFlagsSkipAABBsKHRMask = 0x00000200, -} SpvRayFlagsMask; - -typedef enum SpvRayQueryIntersection_ { - SpvRayQueryIntersectionRayQueryCandidateIntersectionKHR = 0, - SpvRayQueryIntersectionRayQueryCommittedIntersectionKHR = 1, - SpvRayQueryIntersectionMax = 0x7fffffff, -} SpvRayQueryIntersection; - -typedef enum SpvRayQueryCommittedIntersectionType_ { - SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionNoneKHR = 0, - SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionTriangleKHR = 1, - SpvRayQueryCommittedIntersectionTypeRayQueryCommittedIntersectionGeneratedKHR = 2, - SpvRayQueryCommittedIntersectionTypeMax = 0x7fffffff, -} SpvRayQueryCommittedIntersectionType; - -typedef enum SpvRayQueryCandidateIntersectionType_ { - SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionTriangleKHR = 0, - SpvRayQueryCandidateIntersectionTypeRayQueryCandidateIntersectionAABBKHR = 1, - SpvRayQueryCandidateIntersectionTypeMax = 0x7fffffff, -} SpvRayQueryCandidateIntersectionType; - -typedef enum SpvFragmentShadingRateShift_ { - SpvFragmentShadingRateVertical2PixelsShift = 0, - SpvFragmentShadingRateVertical4PixelsShift = 1, - SpvFragmentShadingRateHorizontal2PixelsShift = 2, - SpvFragmentShadingRateHorizontal4PixelsShift = 3, - SpvFragmentShadingRateMax = 0x7fffffff, -} SpvFragmentShadingRateShift; - -typedef enum SpvFragmentShadingRateMask_ { - SpvFragmentShadingRateMaskNone = 0, - SpvFragmentShadingRateVertical2PixelsMask = 0x00000001, - SpvFragmentShadingRateVertical4PixelsMask = 0x00000002, - SpvFragmentShadingRateHorizontal2PixelsMask = 0x00000004, - SpvFragmentShadingRateHorizontal4PixelsMask = 0x00000008, -} SpvFragmentShadingRateMask; - -typedef enum SpvFPDenormMode_ { - SpvFPDenormModePreserve = 0, - SpvFPDenormModeFlushToZero = 1, - SpvFPDenormModeMax = 0x7fffffff, -} SpvFPDenormMode; - -typedef enum SpvFPOperationMode_ { - SpvFPOperationModeIEEE = 0, - SpvFPOperationModeALT = 1, - SpvFPOperationModeMax = 0x7fffffff, -} SpvFPOperationMode; - -typedef enum SpvQuantizationModes_ { - SpvQuantizationModesTRN = 0, - SpvQuantizationModesTRN_ZERO = 1, - SpvQuantizationModesRND = 2, - SpvQuantizationModesRND_ZERO = 3, - SpvQuantizationModesRND_INF = 4, - SpvQuantizationModesRND_MIN_INF = 5, - SpvQuantizationModesRND_CONV = 6, - SpvQuantizationModesRND_CONV_ODD = 7, - SpvQuantizationModesMax = 0x7fffffff, -} SpvQuantizationModes; - -typedef enum SpvOverflowModes_ { - SpvOverflowModesWRAP = 0, - SpvOverflowModesSAT = 1, - SpvOverflowModesSAT_ZERO = 2, - SpvOverflowModesSAT_SYM = 3, - SpvOverflowModesMax = 0x7fffffff, -} SpvOverflowModes; - -typedef enum SpvPackedVectorFormat_ { - SpvPackedVectorFormatPackedVectorFormat4x8Bit = 0, - SpvPackedVectorFormatPackedVectorFormat4x8BitKHR = 0, - SpvPackedVectorFormatMax = 0x7fffffff, -} SpvPackedVectorFormat; - -typedef enum SpvOp_ { - SpvOpNop = 0, - SpvOpUndef = 1, - SpvOpSourceContinued = 2, - SpvOpSource = 3, - SpvOpSourceExtension = 4, - SpvOpName = 5, - SpvOpMemberName = 6, - SpvOpString = 7, - SpvOpLine = 8, - SpvOpExtension = 10, - SpvOpExtInstImport = 11, - SpvOpExtInst = 12, - SpvOpMemoryModel = 14, - SpvOpEntryPoint = 15, - SpvOpExecutionMode = 16, - SpvOpCapability = 17, - SpvOpTypeVoid = 19, - SpvOpTypeBool = 20, - SpvOpTypeInt = 21, - SpvOpTypeFloat = 22, - SpvOpTypeVector = 23, - SpvOpTypeMatrix = 24, - SpvOpTypeImage = 25, - SpvOpTypeSampler = 26, - SpvOpTypeSampledImage = 27, - SpvOpTypeArray = 28, - SpvOpTypeRuntimeArray = 29, - SpvOpTypeStruct = 30, - SpvOpTypeOpaque = 31, - SpvOpTypePointer = 32, - SpvOpTypeFunction = 33, - SpvOpTypeEvent = 34, - SpvOpTypeDeviceEvent = 35, - SpvOpTypeReserveId = 36, - SpvOpTypeQueue = 37, - SpvOpTypePipe = 38, - SpvOpTypeForwardPointer = 39, - SpvOpConstantTrue = 41, - SpvOpConstantFalse = 42, - SpvOpConstant = 43, - SpvOpConstantComposite = 44, - SpvOpConstantSampler = 45, - SpvOpConstantNull = 46, - SpvOpSpecConstantTrue = 48, - SpvOpSpecConstantFalse = 49, - SpvOpSpecConstant = 50, - SpvOpSpecConstantComposite = 51, - SpvOpSpecConstantOp = 52, - SpvOpFunction = 54, - SpvOpFunctionParameter = 55, - SpvOpFunctionEnd = 56, - SpvOpFunctionCall = 57, - SpvOpVariable = 59, - SpvOpImageTexelPointer = 60, - SpvOpLoad = 61, - SpvOpStore = 62, - SpvOpCopyMemory = 63, - SpvOpCopyMemorySized = 64, - SpvOpAccessChain = 65, - SpvOpInBoundsAccessChain = 66, - SpvOpPtrAccessChain = 67, - SpvOpArrayLength = 68, - SpvOpGenericPtrMemSemantics = 69, - SpvOpInBoundsPtrAccessChain = 70, - SpvOpDecorate = 71, - SpvOpMemberDecorate = 72, - SpvOpDecorationGroup = 73, - SpvOpGroupDecorate = 74, - SpvOpGroupMemberDecorate = 75, - SpvOpVectorExtractDynamic = 77, - SpvOpVectorInsertDynamic = 78, - SpvOpVectorShuffle = 79, - SpvOpCompositeConstruct = 80, - SpvOpCompositeExtract = 81, - SpvOpCompositeInsert = 82, - SpvOpCopyObject = 83, - SpvOpTranspose = 84, - SpvOpSampledImage = 86, - SpvOpImageSampleImplicitLod = 87, - SpvOpImageSampleExplicitLod = 88, - SpvOpImageSampleDrefImplicitLod = 89, - SpvOpImageSampleDrefExplicitLod = 90, - SpvOpImageSampleProjImplicitLod = 91, - SpvOpImageSampleProjExplicitLod = 92, - SpvOpImageSampleProjDrefImplicitLod = 93, - SpvOpImageSampleProjDrefExplicitLod = 94, - SpvOpImageFetch = 95, - SpvOpImageGather = 96, - SpvOpImageDrefGather = 97, - SpvOpImageRead = 98, - SpvOpImageWrite = 99, - SpvOpImage = 100, - SpvOpImageQueryFormat = 101, - SpvOpImageQueryOrder = 102, - SpvOpImageQuerySizeLod = 103, - SpvOpImageQuerySize = 104, - SpvOpImageQueryLod = 105, - SpvOpImageQueryLevels = 106, - SpvOpImageQuerySamples = 107, - SpvOpConvertFToU = 109, - SpvOpConvertFToS = 110, - SpvOpConvertSToF = 111, - SpvOpConvertUToF = 112, - SpvOpUConvert = 113, - SpvOpSConvert = 114, - SpvOpFConvert = 115, - SpvOpQuantizeToF16 = 116, - SpvOpConvertPtrToU = 117, - SpvOpSatConvertSToU = 118, - SpvOpSatConvertUToS = 119, - SpvOpConvertUToPtr = 120, - SpvOpPtrCastToGeneric = 121, - SpvOpGenericCastToPtr = 122, - SpvOpGenericCastToPtrExplicit = 123, - SpvOpBitcast = 124, - SpvOpSNegate = 126, - SpvOpFNegate = 127, - SpvOpIAdd = 128, - SpvOpFAdd = 129, - SpvOpISub = 130, - SpvOpFSub = 131, - SpvOpIMul = 132, - SpvOpFMul = 133, - SpvOpUDiv = 134, - SpvOpSDiv = 135, - SpvOpFDiv = 136, - SpvOpUMod = 137, - SpvOpSRem = 138, - SpvOpSMod = 139, - SpvOpFRem = 140, - SpvOpFMod = 141, - SpvOpVectorTimesScalar = 142, - SpvOpMatrixTimesScalar = 143, - SpvOpVectorTimesMatrix = 144, - SpvOpMatrixTimesVector = 145, - SpvOpMatrixTimesMatrix = 146, - SpvOpOuterProduct = 147, - SpvOpDot = 148, - SpvOpIAddCarry = 149, - SpvOpISubBorrow = 150, - SpvOpUMulExtended = 151, - SpvOpSMulExtended = 152, - SpvOpAny = 154, - SpvOpAll = 155, - SpvOpIsNan = 156, - SpvOpIsInf = 157, - SpvOpIsFinite = 158, - SpvOpIsNormal = 159, - SpvOpSignBitSet = 160, - SpvOpLessOrGreater = 161, - SpvOpOrdered = 162, - SpvOpUnordered = 163, - SpvOpLogicalEqual = 164, - SpvOpLogicalNotEqual = 165, - SpvOpLogicalOr = 166, - SpvOpLogicalAnd = 167, - SpvOpLogicalNot = 168, - SpvOpSelect = 169, - SpvOpIEqual = 170, - SpvOpINotEqual = 171, - SpvOpUGreaterThan = 172, - SpvOpSGreaterThan = 173, - SpvOpUGreaterThanEqual = 174, - SpvOpSGreaterThanEqual = 175, - SpvOpULessThan = 176, - SpvOpSLessThan = 177, - SpvOpULessThanEqual = 178, - SpvOpSLessThanEqual = 179, - SpvOpFOrdEqual = 180, - SpvOpFUnordEqual = 181, - SpvOpFOrdNotEqual = 182, - SpvOpFUnordNotEqual = 183, - SpvOpFOrdLessThan = 184, - SpvOpFUnordLessThan = 185, - SpvOpFOrdGreaterThan = 186, - SpvOpFUnordGreaterThan = 187, - SpvOpFOrdLessThanEqual = 188, - SpvOpFUnordLessThanEqual = 189, - SpvOpFOrdGreaterThanEqual = 190, - SpvOpFUnordGreaterThanEqual = 191, - SpvOpShiftRightLogical = 194, - SpvOpShiftRightArithmetic = 195, - SpvOpShiftLeftLogical = 196, - SpvOpBitwiseOr = 197, - SpvOpBitwiseXor = 198, - SpvOpBitwiseAnd = 199, - SpvOpNot = 200, - SpvOpBitFieldInsert = 201, - SpvOpBitFieldSExtract = 202, - SpvOpBitFieldUExtract = 203, - SpvOpBitReverse = 204, - SpvOpBitCount = 205, - SpvOpDPdx = 207, - SpvOpDPdy = 208, - SpvOpFwidth = 209, - SpvOpDPdxFine = 210, - SpvOpDPdyFine = 211, - SpvOpFwidthFine = 212, - SpvOpDPdxCoarse = 213, - SpvOpDPdyCoarse = 214, - SpvOpFwidthCoarse = 215, - SpvOpEmitVertex = 218, - SpvOpEndPrimitive = 219, - SpvOpEmitStreamVertex = 220, - SpvOpEndStreamPrimitive = 221, - SpvOpControlBarrier = 224, - SpvOpMemoryBarrier = 225, - SpvOpAtomicLoad = 227, - SpvOpAtomicStore = 228, - SpvOpAtomicExchange = 229, - SpvOpAtomicCompareExchange = 230, - SpvOpAtomicCompareExchangeWeak = 231, - SpvOpAtomicIIncrement = 232, - SpvOpAtomicIDecrement = 233, - SpvOpAtomicIAdd = 234, - SpvOpAtomicISub = 235, - SpvOpAtomicSMin = 236, - SpvOpAtomicUMin = 237, - SpvOpAtomicSMax = 238, - SpvOpAtomicUMax = 239, - SpvOpAtomicAnd = 240, - SpvOpAtomicOr = 241, - SpvOpAtomicXor = 242, - SpvOpPhi = 245, - SpvOpLoopMerge = 246, - SpvOpSelectionMerge = 247, - SpvOpLabel = 248, - SpvOpBranch = 249, - SpvOpBranchConditional = 250, - SpvOpSwitch = 251, - SpvOpKill = 252, - SpvOpReturn = 253, - SpvOpReturnValue = 254, - SpvOpUnreachable = 255, - SpvOpLifetimeStart = 256, - SpvOpLifetimeStop = 257, - SpvOpGroupAsyncCopy = 259, - SpvOpGroupWaitEvents = 260, - SpvOpGroupAll = 261, - SpvOpGroupAny = 262, - SpvOpGroupBroadcast = 263, - SpvOpGroupIAdd = 264, - SpvOpGroupFAdd = 265, - SpvOpGroupFMin = 266, - SpvOpGroupUMin = 267, - SpvOpGroupSMin = 268, - SpvOpGroupFMax = 269, - SpvOpGroupUMax = 270, - SpvOpGroupSMax = 271, - SpvOpReadPipe = 274, - SpvOpWritePipe = 275, - SpvOpReservedReadPipe = 276, - SpvOpReservedWritePipe = 277, - SpvOpReserveReadPipePackets = 278, - SpvOpReserveWritePipePackets = 279, - SpvOpCommitReadPipe = 280, - SpvOpCommitWritePipe = 281, - SpvOpIsValidReserveId = 282, - SpvOpGetNumPipePackets = 283, - SpvOpGetMaxPipePackets = 284, - SpvOpGroupReserveReadPipePackets = 285, - SpvOpGroupReserveWritePipePackets = 286, - SpvOpGroupCommitReadPipe = 287, - SpvOpGroupCommitWritePipe = 288, - SpvOpEnqueueMarker = 291, - SpvOpEnqueueKernel = 292, - SpvOpGetKernelNDrangeSubGroupCount = 293, - SpvOpGetKernelNDrangeMaxSubGroupSize = 294, - SpvOpGetKernelWorkGroupSize = 295, - SpvOpGetKernelPreferredWorkGroupSizeMultiple = 296, - SpvOpRetainEvent = 297, - SpvOpReleaseEvent = 298, - SpvOpCreateUserEvent = 299, - SpvOpIsValidEvent = 300, - SpvOpSetUserEventStatus = 301, - SpvOpCaptureEventProfilingInfo = 302, - SpvOpGetDefaultQueue = 303, - SpvOpBuildNDRange = 304, - SpvOpImageSparseSampleImplicitLod = 305, - SpvOpImageSparseSampleExplicitLod = 306, - SpvOpImageSparseSampleDrefImplicitLod = 307, - SpvOpImageSparseSampleDrefExplicitLod = 308, - SpvOpImageSparseSampleProjImplicitLod = 309, - SpvOpImageSparseSampleProjExplicitLod = 310, - SpvOpImageSparseSampleProjDrefImplicitLod = 311, - SpvOpImageSparseSampleProjDrefExplicitLod = 312, - SpvOpImageSparseFetch = 313, - SpvOpImageSparseGather = 314, - SpvOpImageSparseDrefGather = 315, - SpvOpImageSparseTexelsResident = 316, - SpvOpNoLine = 317, - SpvOpAtomicFlagTestAndSet = 318, - SpvOpAtomicFlagClear = 319, - SpvOpImageSparseRead = 320, - SpvOpSizeOf = 321, - SpvOpTypePipeStorage = 322, - SpvOpConstantPipeStorage = 323, - SpvOpCreatePipeFromPipeStorage = 324, - SpvOpGetKernelLocalSizeForSubgroupCount = 325, - SpvOpGetKernelMaxNumSubgroups = 326, - SpvOpTypeNamedBarrier = 327, - SpvOpNamedBarrierInitialize = 328, - SpvOpMemoryNamedBarrier = 329, - SpvOpModuleProcessed = 330, - SpvOpExecutionModeId = 331, - SpvOpDecorateId = 332, - SpvOpGroupNonUniformElect = 333, - SpvOpGroupNonUniformAll = 334, - SpvOpGroupNonUniformAny = 335, - SpvOpGroupNonUniformAllEqual = 336, - SpvOpGroupNonUniformBroadcast = 337, - SpvOpGroupNonUniformBroadcastFirst = 338, - SpvOpGroupNonUniformBallot = 339, - SpvOpGroupNonUniformInverseBallot = 340, - SpvOpGroupNonUniformBallotBitExtract = 341, - SpvOpGroupNonUniformBallotBitCount = 342, - SpvOpGroupNonUniformBallotFindLSB = 343, - SpvOpGroupNonUniformBallotFindMSB = 344, - SpvOpGroupNonUniformShuffle = 345, - SpvOpGroupNonUniformShuffleXor = 346, - SpvOpGroupNonUniformShuffleUp = 347, - SpvOpGroupNonUniformShuffleDown = 348, - SpvOpGroupNonUniformIAdd = 349, - SpvOpGroupNonUniformFAdd = 350, - SpvOpGroupNonUniformIMul = 351, - SpvOpGroupNonUniformFMul = 352, - SpvOpGroupNonUniformSMin = 353, - SpvOpGroupNonUniformUMin = 354, - SpvOpGroupNonUniformFMin = 355, - SpvOpGroupNonUniformSMax = 356, - SpvOpGroupNonUniformUMax = 357, - SpvOpGroupNonUniformFMax = 358, - SpvOpGroupNonUniformBitwiseAnd = 359, - SpvOpGroupNonUniformBitwiseOr = 360, - SpvOpGroupNonUniformBitwiseXor = 361, - SpvOpGroupNonUniformLogicalAnd = 362, - SpvOpGroupNonUniformLogicalOr = 363, - SpvOpGroupNonUniformLogicalXor = 364, - SpvOpGroupNonUniformQuadBroadcast = 365, - SpvOpGroupNonUniformQuadSwap = 366, - SpvOpCopyLogical = 400, - SpvOpPtrEqual = 401, - SpvOpPtrNotEqual = 402, - SpvOpPtrDiff = 403, - SpvOpTerminateInvocation = 4416, - SpvOpSubgroupBallotKHR = 4421, - SpvOpSubgroupFirstInvocationKHR = 4422, - SpvOpSubgroupAllKHR = 4428, - SpvOpSubgroupAnyKHR = 4429, - SpvOpSubgroupAllEqualKHR = 4430, - SpvOpGroupNonUniformRotateKHR = 4431, - SpvOpSubgroupReadInvocationKHR = 4432, - SpvOpTraceRayKHR = 4445, - SpvOpExecuteCallableKHR = 4446, - SpvOpConvertUToAccelerationStructureKHR = 4447, - SpvOpIgnoreIntersectionKHR = 4448, - SpvOpTerminateRayKHR = 4449, - SpvOpSDot = 4450, - SpvOpSDotKHR = 4450, - SpvOpUDot = 4451, - SpvOpUDotKHR = 4451, - SpvOpSUDot = 4452, - SpvOpSUDotKHR = 4452, - SpvOpSDotAccSat = 4453, - SpvOpSDotAccSatKHR = 4453, - SpvOpUDotAccSat = 4454, - SpvOpUDotAccSatKHR = 4454, - SpvOpSUDotAccSat = 4455, - SpvOpSUDotAccSatKHR = 4455, - SpvOpTypeRayQueryKHR = 4472, - SpvOpRayQueryInitializeKHR = 4473, - SpvOpRayQueryTerminateKHR = 4474, - SpvOpRayQueryGenerateIntersectionKHR = 4475, - SpvOpRayQueryConfirmIntersectionKHR = 4476, - SpvOpRayQueryProceedKHR = 4477, - SpvOpRayQueryGetIntersectionTypeKHR = 4479, - SpvOpGroupIAddNonUniformAMD = 5000, - SpvOpGroupFAddNonUniformAMD = 5001, - SpvOpGroupFMinNonUniformAMD = 5002, - SpvOpGroupUMinNonUniformAMD = 5003, - SpvOpGroupSMinNonUniformAMD = 5004, - SpvOpGroupFMaxNonUniformAMD = 5005, - SpvOpGroupUMaxNonUniformAMD = 5006, - SpvOpGroupSMaxNonUniformAMD = 5007, - SpvOpFragmentMaskFetchAMD = 5011, - SpvOpFragmentFetchAMD = 5012, - SpvOpReadClockKHR = 5056, - SpvOpImageSampleFootprintNV = 5283, - SpvOpEmitMeshTasksEXT = 5294, - SpvOpSetMeshOutputsEXT = 5295, - SpvOpGroupNonUniformPartitionNV = 5296, - SpvOpWritePackedPrimitiveIndices4x8NV = 5299, - SpvOpReportIntersectionKHR = 5334, - SpvOpReportIntersectionNV = 5334, - SpvOpIgnoreIntersectionNV = 5335, - SpvOpTerminateRayNV = 5336, - SpvOpTraceNV = 5337, - SpvOpTraceMotionNV = 5338, - SpvOpTraceRayMotionNV = 5339, - SpvOpTypeAccelerationStructureKHR = 5341, - SpvOpTypeAccelerationStructureNV = 5341, - SpvOpExecuteCallableNV = 5344, - SpvOpTypeCooperativeMatrixNV = 5358, - SpvOpCooperativeMatrixLoadNV = 5359, - SpvOpCooperativeMatrixStoreNV = 5360, - SpvOpCooperativeMatrixMulAddNV = 5361, - SpvOpCooperativeMatrixLengthNV = 5362, - SpvOpBeginInvocationInterlockEXT = 5364, - SpvOpEndInvocationInterlockEXT = 5365, - SpvOpDemoteToHelperInvocation = 5380, - SpvOpDemoteToHelperInvocationEXT = 5380, - SpvOpIsHelperInvocationEXT = 5381, - SpvOpConvertUToImageNV = 5391, - SpvOpConvertUToSamplerNV = 5392, - SpvOpConvertImageToUNV = 5393, - SpvOpConvertSamplerToUNV = 5394, - SpvOpConvertUToSampledImageNV = 5395, - SpvOpConvertSampledImageToUNV = 5396, - SpvOpSamplerImageAddressingModeNV = 5397, - SpvOpSubgroupShuffleINTEL = 5571, - SpvOpSubgroupShuffleDownINTEL = 5572, - SpvOpSubgroupShuffleUpINTEL = 5573, - SpvOpSubgroupShuffleXorINTEL = 5574, - SpvOpSubgroupBlockReadINTEL = 5575, - SpvOpSubgroupBlockWriteINTEL = 5576, - SpvOpSubgroupImageBlockReadINTEL = 5577, - SpvOpSubgroupImageBlockWriteINTEL = 5578, - SpvOpSubgroupImageMediaBlockReadINTEL = 5580, - SpvOpSubgroupImageMediaBlockWriteINTEL = 5581, - SpvOpUCountLeadingZerosINTEL = 5585, - SpvOpUCountTrailingZerosINTEL = 5586, - SpvOpAbsISubINTEL = 5587, - SpvOpAbsUSubINTEL = 5588, - SpvOpIAddSatINTEL = 5589, - SpvOpUAddSatINTEL = 5590, - SpvOpIAverageINTEL = 5591, - SpvOpUAverageINTEL = 5592, - SpvOpIAverageRoundedINTEL = 5593, - SpvOpUAverageRoundedINTEL = 5594, - SpvOpISubSatINTEL = 5595, - SpvOpUSubSatINTEL = 5596, - SpvOpIMul32x16INTEL = 5597, - SpvOpUMul32x16INTEL = 5598, - SpvOpConstantFunctionPointerINTEL = 5600, - SpvOpFunctionPointerCallINTEL = 5601, - SpvOpAsmTargetINTEL = 5609, - SpvOpAsmINTEL = 5610, - SpvOpAsmCallINTEL = 5611, - SpvOpAtomicFMinEXT = 5614, - SpvOpAtomicFMaxEXT = 5615, - SpvOpAssumeTrueKHR = 5630, - SpvOpExpectKHR = 5631, - SpvOpDecorateString = 5632, - SpvOpDecorateStringGOOGLE = 5632, - SpvOpMemberDecorateString = 5633, - SpvOpMemberDecorateStringGOOGLE = 5633, - SpvOpVmeImageINTEL = 5699, - SpvOpTypeVmeImageINTEL = 5700, - SpvOpTypeAvcImePayloadINTEL = 5701, - SpvOpTypeAvcRefPayloadINTEL = 5702, - SpvOpTypeAvcSicPayloadINTEL = 5703, - SpvOpTypeAvcMcePayloadINTEL = 5704, - SpvOpTypeAvcMceResultINTEL = 5705, - SpvOpTypeAvcImeResultINTEL = 5706, - SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL = 5707, - SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL = 5708, - SpvOpTypeAvcImeSingleReferenceStreaminINTEL = 5709, - SpvOpTypeAvcImeDualReferenceStreaminINTEL = 5710, - SpvOpTypeAvcRefResultINTEL = 5711, - SpvOpTypeAvcSicResultINTEL = 5712, - SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL = 5713, - SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL = 5714, - SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL = 5715, - SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL = 5716, - SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL = 5717, - SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL = 5718, - SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL = 5719, - SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL = 5720, - SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL = 5721, - SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL = 5722, - SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL = 5723, - SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL = 5724, - SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL = 5725, - SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL = 5726, - SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL = 5727, - SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL = 5728, - SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL = 5729, - SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL = 5730, - SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL = 5731, - SpvOpSubgroupAvcMceConvertToImePayloadINTEL = 5732, - SpvOpSubgroupAvcMceConvertToImeResultINTEL = 5733, - SpvOpSubgroupAvcMceConvertToRefPayloadINTEL = 5734, - SpvOpSubgroupAvcMceConvertToRefResultINTEL = 5735, - SpvOpSubgroupAvcMceConvertToSicPayloadINTEL = 5736, - SpvOpSubgroupAvcMceConvertToSicResultINTEL = 5737, - SpvOpSubgroupAvcMceGetMotionVectorsINTEL = 5738, - SpvOpSubgroupAvcMceGetInterDistortionsINTEL = 5739, - SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL = 5740, - SpvOpSubgroupAvcMceGetInterMajorShapeINTEL = 5741, - SpvOpSubgroupAvcMceGetInterMinorShapeINTEL = 5742, - SpvOpSubgroupAvcMceGetInterDirectionsINTEL = 5743, - SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL = 5744, - SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL = 5745, - SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL = 5746, - SpvOpSubgroupAvcImeInitializeINTEL = 5747, - SpvOpSubgroupAvcImeSetSingleReferenceINTEL = 5748, - SpvOpSubgroupAvcImeSetDualReferenceINTEL = 5749, - SpvOpSubgroupAvcImeRefWindowSizeINTEL = 5750, - SpvOpSubgroupAvcImeAdjustRefOffsetINTEL = 5751, - SpvOpSubgroupAvcImeConvertToMcePayloadINTEL = 5752, - SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL = 5753, - SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL = 5754, - SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL = 5755, - SpvOpSubgroupAvcImeSetWeightedSadINTEL = 5756, - SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL = 5757, - SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL = 5758, - SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL = 5759, - SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL = 5760, - SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL = 5761, - SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL = 5762, - SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL = 5763, - SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL = 5764, - SpvOpSubgroupAvcImeConvertToMceResultINTEL = 5765, - SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL = 5766, - SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL = 5767, - SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL = 5768, - SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL = 5769, - SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL = 5770, - SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL = 5771, - SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL = 5772, - SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL = 5773, - SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL = 5774, - SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL = 5775, - SpvOpSubgroupAvcImeGetBorderReachedINTEL = 5776, - SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL = 5777, - SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL = 5778, - SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL = 5779, - SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL = 5780, - SpvOpSubgroupAvcFmeInitializeINTEL = 5781, - SpvOpSubgroupAvcBmeInitializeINTEL = 5782, - SpvOpSubgroupAvcRefConvertToMcePayloadINTEL = 5783, - SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL = 5784, - SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL = 5785, - SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL = 5786, - SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL = 5787, - SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL = 5788, - SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL = 5789, - SpvOpSubgroupAvcRefConvertToMceResultINTEL = 5790, - SpvOpSubgroupAvcSicInitializeINTEL = 5791, - SpvOpSubgroupAvcSicConfigureSkcINTEL = 5792, - SpvOpSubgroupAvcSicConfigureIpeLumaINTEL = 5793, - SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL = 5794, - SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL = 5795, - SpvOpSubgroupAvcSicConvertToMcePayloadINTEL = 5796, - SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL = 5797, - SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL = 5798, - SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL = 5799, - SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL = 5800, - SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL = 5801, - SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL = 5802, - SpvOpSubgroupAvcSicEvaluateIpeINTEL = 5803, - SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL = 5804, - SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL = 5805, - SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL = 5806, - SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL = 5807, - SpvOpSubgroupAvcSicConvertToMceResultINTEL = 5808, - SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL = 5809, - SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL = 5810, - SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL = 5811, - SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL = 5812, - SpvOpSubgroupAvcSicGetIpeChromaModeINTEL = 5813, - SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL = 5814, - SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL = 5815, - SpvOpSubgroupAvcSicGetInterRawSadsINTEL = 5816, - SpvOpVariableLengthArrayINTEL = 5818, - SpvOpSaveMemoryINTEL = 5819, - SpvOpRestoreMemoryINTEL = 5820, - SpvOpArbitraryFloatSinCosPiINTEL = 5840, - SpvOpArbitraryFloatCastINTEL = 5841, - SpvOpArbitraryFloatCastFromIntINTEL = 5842, - SpvOpArbitraryFloatCastToIntINTEL = 5843, - SpvOpArbitraryFloatAddINTEL = 5846, - SpvOpArbitraryFloatSubINTEL = 5847, - SpvOpArbitraryFloatMulINTEL = 5848, - SpvOpArbitraryFloatDivINTEL = 5849, - SpvOpArbitraryFloatGTINTEL = 5850, - SpvOpArbitraryFloatGEINTEL = 5851, - SpvOpArbitraryFloatLTINTEL = 5852, - SpvOpArbitraryFloatLEINTEL = 5853, - SpvOpArbitraryFloatEQINTEL = 5854, - SpvOpArbitraryFloatRecipINTEL = 5855, - SpvOpArbitraryFloatRSqrtINTEL = 5856, - SpvOpArbitraryFloatCbrtINTEL = 5857, - SpvOpArbitraryFloatHypotINTEL = 5858, - SpvOpArbitraryFloatSqrtINTEL = 5859, - SpvOpArbitraryFloatLogINTEL = 5860, - SpvOpArbitraryFloatLog2INTEL = 5861, - SpvOpArbitraryFloatLog10INTEL = 5862, - SpvOpArbitraryFloatLog1pINTEL = 5863, - SpvOpArbitraryFloatExpINTEL = 5864, - SpvOpArbitraryFloatExp2INTEL = 5865, - SpvOpArbitraryFloatExp10INTEL = 5866, - SpvOpArbitraryFloatExpm1INTEL = 5867, - SpvOpArbitraryFloatSinINTEL = 5868, - SpvOpArbitraryFloatCosINTEL = 5869, - SpvOpArbitraryFloatSinCosINTEL = 5870, - SpvOpArbitraryFloatSinPiINTEL = 5871, - SpvOpArbitraryFloatCosPiINTEL = 5872, - SpvOpArbitraryFloatASinINTEL = 5873, - SpvOpArbitraryFloatASinPiINTEL = 5874, - SpvOpArbitraryFloatACosINTEL = 5875, - SpvOpArbitraryFloatACosPiINTEL = 5876, - SpvOpArbitraryFloatATanINTEL = 5877, - SpvOpArbitraryFloatATanPiINTEL = 5878, - SpvOpArbitraryFloatATan2INTEL = 5879, - SpvOpArbitraryFloatPowINTEL = 5880, - SpvOpArbitraryFloatPowRINTEL = 5881, - SpvOpArbitraryFloatPowNINTEL = 5882, - SpvOpLoopControlINTEL = 5887, - SpvOpAliasDomainDeclINTEL = 5911, - SpvOpAliasScopeDeclINTEL = 5912, - SpvOpAliasScopeListDeclINTEL = 5913, - SpvOpFixedSqrtINTEL = 5923, - SpvOpFixedRecipINTEL = 5924, - SpvOpFixedRsqrtINTEL = 5925, - SpvOpFixedSinINTEL = 5926, - SpvOpFixedCosINTEL = 5927, - SpvOpFixedSinCosINTEL = 5928, - SpvOpFixedSinPiINTEL = 5929, - SpvOpFixedCosPiINTEL = 5930, - SpvOpFixedSinCosPiINTEL = 5931, - SpvOpFixedLogINTEL = 5932, - SpvOpFixedExpINTEL = 5933, - SpvOpPtrCastToCrossWorkgroupINTEL = 5934, - SpvOpCrossWorkgroupCastToPtrINTEL = 5938, - SpvOpReadPipeBlockingINTEL = 5946, - SpvOpWritePipeBlockingINTEL = 5947, - SpvOpFPGARegINTEL = 5949, - SpvOpRayQueryGetRayTMinKHR = 6016, - SpvOpRayQueryGetRayFlagsKHR = 6017, - SpvOpRayQueryGetIntersectionTKHR = 6018, - SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR = 6019, - SpvOpRayQueryGetIntersectionInstanceIdKHR = 6020, - SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR = 6021, - SpvOpRayQueryGetIntersectionGeometryIndexKHR = 6022, - SpvOpRayQueryGetIntersectionPrimitiveIndexKHR = 6023, - SpvOpRayQueryGetIntersectionBarycentricsKHR = 6024, - SpvOpRayQueryGetIntersectionFrontFaceKHR = 6025, - SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR = 6026, - SpvOpRayQueryGetIntersectionObjectRayDirectionKHR = 6027, - SpvOpRayQueryGetIntersectionObjectRayOriginKHR = 6028, - SpvOpRayQueryGetWorldRayDirectionKHR = 6029, - SpvOpRayQueryGetWorldRayOriginKHR = 6030, - SpvOpRayQueryGetIntersectionObjectToWorldKHR = 6031, - SpvOpRayQueryGetIntersectionWorldToObjectKHR = 6032, - SpvOpAtomicFAddEXT = 6035, - SpvOpTypeBufferSurfaceINTEL = 6086, - SpvOpTypeStructContinuedINTEL = 6090, - SpvOpConstantCompositeContinuedINTEL = 6091, - SpvOpSpecConstantCompositeContinuedINTEL = 6092, - SpvOpControlBarrierArriveINTEL = 6142, - SpvOpControlBarrierWaitINTEL = 6143, - SpvOpGroupIMulKHR = 6401, - SpvOpGroupFMulKHR = 6402, - SpvOpGroupBitwiseAndKHR = 6403, - SpvOpGroupBitwiseOrKHR = 6404, - SpvOpGroupBitwiseXorKHR = 6405, - SpvOpGroupLogicalAndKHR = 6406, - SpvOpGroupLogicalOrKHR = 6407, - SpvOpGroupLogicalXorKHR = 6408, - SpvOpMax = 0x7fffffff, -} SpvOp; - -#ifdef SPV_ENABLE_UTILITY_CODE -#ifndef __cplusplus -#include -#endif -inline void SpvHasResultAndType(SpvOp opcode, bool *hasResult, bool *hasResultType) { - *hasResult = *hasResultType = false; - switch (opcode) { - default: /* unknown opcode */ break; - case SpvOpNop: *hasResult = false; *hasResultType = false; break; - case SpvOpUndef: *hasResult = true; *hasResultType = true; break; - case SpvOpSourceContinued: *hasResult = false; *hasResultType = false; break; - case SpvOpSource: *hasResult = false; *hasResultType = false; break; - case SpvOpSourceExtension: *hasResult = false; *hasResultType = false; break; - case SpvOpName: *hasResult = false; *hasResultType = false; break; - case SpvOpMemberName: *hasResult = false; *hasResultType = false; break; - case SpvOpString: *hasResult = true; *hasResultType = false; break; - case SpvOpLine: *hasResult = false; *hasResultType = false; break; - case SpvOpExtension: *hasResult = false; *hasResultType = false; break; - case SpvOpExtInstImport: *hasResult = true; *hasResultType = false; break; - case SpvOpExtInst: *hasResult = true; *hasResultType = true; break; - case SpvOpMemoryModel: *hasResult = false; *hasResultType = false; break; - case SpvOpEntryPoint: *hasResult = false; *hasResultType = false; break; - case SpvOpExecutionMode: *hasResult = false; *hasResultType = false; break; - case SpvOpCapability: *hasResult = false; *hasResultType = false; break; - case SpvOpTypeVoid: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeBool: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeInt: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeFloat: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeVector: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeMatrix: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeImage: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeSampler: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeSampledImage: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeArray: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeRuntimeArray: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeStruct: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeOpaque: *hasResult = true; *hasResultType = false; break; - case SpvOpTypePointer: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeFunction: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeEvent: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeDeviceEvent: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeReserveId: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeQueue: *hasResult = true; *hasResultType = false; break; - case SpvOpTypePipe: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeForwardPointer: *hasResult = false; *hasResultType = false; break; - case SpvOpConstantTrue: *hasResult = true; *hasResultType = true; break; - case SpvOpConstantFalse: *hasResult = true; *hasResultType = true; break; - case SpvOpConstant: *hasResult = true; *hasResultType = true; break; - case SpvOpConstantComposite: *hasResult = true; *hasResultType = true; break; - case SpvOpConstantSampler: *hasResult = true; *hasResultType = true; break; - case SpvOpConstantNull: *hasResult = true; *hasResultType = true; break; - case SpvOpSpecConstantTrue: *hasResult = true; *hasResultType = true; break; - case SpvOpSpecConstantFalse: *hasResult = true; *hasResultType = true; break; - case SpvOpSpecConstant: *hasResult = true; *hasResultType = true; break; - case SpvOpSpecConstantComposite: *hasResult = true; *hasResultType = true; break; - case SpvOpSpecConstantOp: *hasResult = true; *hasResultType = true; break; - case SpvOpFunction: *hasResult = true; *hasResultType = true; break; - case SpvOpFunctionParameter: *hasResult = true; *hasResultType = true; break; - case SpvOpFunctionEnd: *hasResult = false; *hasResultType = false; break; - case SpvOpFunctionCall: *hasResult = true; *hasResultType = true; break; - case SpvOpVariable: *hasResult = true; *hasResultType = true; break; - case SpvOpImageTexelPointer: *hasResult = true; *hasResultType = true; break; - case SpvOpLoad: *hasResult = true; *hasResultType = true; break; - case SpvOpStore: *hasResult = false; *hasResultType = false; break; - case SpvOpCopyMemory: *hasResult = false; *hasResultType = false; break; - case SpvOpCopyMemorySized: *hasResult = false; *hasResultType = false; break; - case SpvOpAccessChain: *hasResult = true; *hasResultType = true; break; - case SpvOpInBoundsAccessChain: *hasResult = true; *hasResultType = true; break; - case SpvOpPtrAccessChain: *hasResult = true; *hasResultType = true; break; - case SpvOpArrayLength: *hasResult = true; *hasResultType = true; break; - case SpvOpGenericPtrMemSemantics: *hasResult = true; *hasResultType = true; break; - case SpvOpInBoundsPtrAccessChain: *hasResult = true; *hasResultType = true; break; - case SpvOpDecorate: *hasResult = false; *hasResultType = false; break; - case SpvOpMemberDecorate: *hasResult = false; *hasResultType = false; break; - case SpvOpDecorationGroup: *hasResult = true; *hasResultType = false; break; - case SpvOpGroupDecorate: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupMemberDecorate: *hasResult = false; *hasResultType = false; break; - case SpvOpVectorExtractDynamic: *hasResult = true; *hasResultType = true; break; - case SpvOpVectorInsertDynamic: *hasResult = true; *hasResultType = true; break; - case SpvOpVectorShuffle: *hasResult = true; *hasResultType = true; break; - case SpvOpCompositeConstruct: *hasResult = true; *hasResultType = true; break; - case SpvOpCompositeExtract: *hasResult = true; *hasResultType = true; break; - case SpvOpCompositeInsert: *hasResult = true; *hasResultType = true; break; - case SpvOpCopyObject: *hasResult = true; *hasResultType = true; break; - case SpvOpTranspose: *hasResult = true; *hasResultType = true; break; - case SpvOpSampledImage: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageFetch: *hasResult = true; *hasResultType = true; break; - case SpvOpImageGather: *hasResult = true; *hasResultType = true; break; - case SpvOpImageDrefGather: *hasResult = true; *hasResultType = true; break; - case SpvOpImageRead: *hasResult = true; *hasResultType = true; break; - case SpvOpImageWrite: *hasResult = false; *hasResultType = false; break; - case SpvOpImage: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQueryFormat: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQueryOrder: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQuerySizeLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQuerySize: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQueryLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQueryLevels: *hasResult = true; *hasResultType = true; break; - case SpvOpImageQuerySamples: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertFToU: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertFToS: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertSToF: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertUToF: *hasResult = true; *hasResultType = true; break; - case SpvOpUConvert: *hasResult = true; *hasResultType = true; break; - case SpvOpSConvert: *hasResult = true; *hasResultType = true; break; - case SpvOpFConvert: *hasResult = true; *hasResultType = true; break; - case SpvOpQuantizeToF16: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertPtrToU: *hasResult = true; *hasResultType = true; break; - case SpvOpSatConvertSToU: *hasResult = true; *hasResultType = true; break; - case SpvOpSatConvertUToS: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertUToPtr: *hasResult = true; *hasResultType = true; break; - case SpvOpPtrCastToGeneric: *hasResult = true; *hasResultType = true; break; - case SpvOpGenericCastToPtr: *hasResult = true; *hasResultType = true; break; - case SpvOpGenericCastToPtrExplicit: *hasResult = true; *hasResultType = true; break; - case SpvOpBitcast: *hasResult = true; *hasResultType = true; break; - case SpvOpSNegate: *hasResult = true; *hasResultType = true; break; - case SpvOpFNegate: *hasResult = true; *hasResultType = true; break; - case SpvOpIAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpFAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpISub: *hasResult = true; *hasResultType = true; break; - case SpvOpFSub: *hasResult = true; *hasResultType = true; break; - case SpvOpIMul: *hasResult = true; *hasResultType = true; break; - case SpvOpFMul: *hasResult = true; *hasResultType = true; break; - case SpvOpUDiv: *hasResult = true; *hasResultType = true; break; - case SpvOpSDiv: *hasResult = true; *hasResultType = true; break; - case SpvOpFDiv: *hasResult = true; *hasResultType = true; break; - case SpvOpUMod: *hasResult = true; *hasResultType = true; break; - case SpvOpSRem: *hasResult = true; *hasResultType = true; break; - case SpvOpSMod: *hasResult = true; *hasResultType = true; break; - case SpvOpFRem: *hasResult = true; *hasResultType = true; break; - case SpvOpFMod: *hasResult = true; *hasResultType = true; break; - case SpvOpVectorTimesScalar: *hasResult = true; *hasResultType = true; break; - case SpvOpMatrixTimesScalar: *hasResult = true; *hasResultType = true; break; - case SpvOpVectorTimesMatrix: *hasResult = true; *hasResultType = true; break; - case SpvOpMatrixTimesVector: *hasResult = true; *hasResultType = true; break; - case SpvOpMatrixTimesMatrix: *hasResult = true; *hasResultType = true; break; - case SpvOpOuterProduct: *hasResult = true; *hasResultType = true; break; - case SpvOpDot: *hasResult = true; *hasResultType = true; break; - case SpvOpIAddCarry: *hasResult = true; *hasResultType = true; break; - case SpvOpISubBorrow: *hasResult = true; *hasResultType = true; break; - case SpvOpUMulExtended: *hasResult = true; *hasResultType = true; break; - case SpvOpSMulExtended: *hasResult = true; *hasResultType = true; break; - case SpvOpAny: *hasResult = true; *hasResultType = true; break; - case SpvOpAll: *hasResult = true; *hasResultType = true; break; - case SpvOpIsNan: *hasResult = true; *hasResultType = true; break; - case SpvOpIsInf: *hasResult = true; *hasResultType = true; break; - case SpvOpIsFinite: *hasResult = true; *hasResultType = true; break; - case SpvOpIsNormal: *hasResult = true; *hasResultType = true; break; - case SpvOpSignBitSet: *hasResult = true; *hasResultType = true; break; - case SpvOpLessOrGreater: *hasResult = true; *hasResultType = true; break; - case SpvOpOrdered: *hasResult = true; *hasResultType = true; break; - case SpvOpUnordered: *hasResult = true; *hasResultType = true; break; - case SpvOpLogicalEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpLogicalNotEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpLogicalOr: *hasResult = true; *hasResultType = true; break; - case SpvOpLogicalAnd: *hasResult = true; *hasResultType = true; break; - case SpvOpLogicalNot: *hasResult = true; *hasResultType = true; break; - case SpvOpSelect: *hasResult = true; *hasResultType = true; break; - case SpvOpIEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpINotEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpUGreaterThan: *hasResult = true; *hasResultType = true; break; - case SpvOpSGreaterThan: *hasResult = true; *hasResultType = true; break; - case SpvOpUGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpSGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpULessThan: *hasResult = true; *hasResultType = true; break; - case SpvOpSLessThan: *hasResult = true; *hasResultType = true; break; - case SpvOpULessThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpSLessThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFOrdEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFUnordEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFOrdNotEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFUnordNotEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFOrdLessThan: *hasResult = true; *hasResultType = true; break; - case SpvOpFUnordLessThan: *hasResult = true; *hasResultType = true; break; - case SpvOpFOrdGreaterThan: *hasResult = true; *hasResultType = true; break; - case SpvOpFUnordGreaterThan: *hasResult = true; *hasResultType = true; break; - case SpvOpFOrdLessThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFUnordLessThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFOrdGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpFUnordGreaterThanEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpShiftRightLogical: *hasResult = true; *hasResultType = true; break; - case SpvOpShiftRightArithmetic: *hasResult = true; *hasResultType = true; break; - case SpvOpShiftLeftLogical: *hasResult = true; *hasResultType = true; break; - case SpvOpBitwiseOr: *hasResult = true; *hasResultType = true; break; - case SpvOpBitwiseXor: *hasResult = true; *hasResultType = true; break; - case SpvOpBitwiseAnd: *hasResult = true; *hasResultType = true; break; - case SpvOpNot: *hasResult = true; *hasResultType = true; break; - case SpvOpBitFieldInsert: *hasResult = true; *hasResultType = true; break; - case SpvOpBitFieldSExtract: *hasResult = true; *hasResultType = true; break; - case SpvOpBitFieldUExtract: *hasResult = true; *hasResultType = true; break; - case SpvOpBitReverse: *hasResult = true; *hasResultType = true; break; - case SpvOpBitCount: *hasResult = true; *hasResultType = true; break; - case SpvOpDPdx: *hasResult = true; *hasResultType = true; break; - case SpvOpDPdy: *hasResult = true; *hasResultType = true; break; - case SpvOpFwidth: *hasResult = true; *hasResultType = true; break; - case SpvOpDPdxFine: *hasResult = true; *hasResultType = true; break; - case SpvOpDPdyFine: *hasResult = true; *hasResultType = true; break; - case SpvOpFwidthFine: *hasResult = true; *hasResultType = true; break; - case SpvOpDPdxCoarse: *hasResult = true; *hasResultType = true; break; - case SpvOpDPdyCoarse: *hasResult = true; *hasResultType = true; break; - case SpvOpFwidthCoarse: *hasResult = true; *hasResultType = true; break; - case SpvOpEmitVertex: *hasResult = false; *hasResultType = false; break; - case SpvOpEndPrimitive: *hasResult = false; *hasResultType = false; break; - case SpvOpEmitStreamVertex: *hasResult = false; *hasResultType = false; break; - case SpvOpEndStreamPrimitive: *hasResult = false; *hasResultType = false; break; - case SpvOpControlBarrier: *hasResult = false; *hasResultType = false; break; - case SpvOpMemoryBarrier: *hasResult = false; *hasResultType = false; break; - case SpvOpAtomicLoad: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicStore: *hasResult = false; *hasResultType = false; break; - case SpvOpAtomicExchange: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicCompareExchange: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicCompareExchangeWeak: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicIIncrement: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicIDecrement: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicIAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicISub: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicSMin: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicUMin: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicSMax: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicUMax: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicAnd: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicOr: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicXor: *hasResult = true; *hasResultType = true; break; - case SpvOpPhi: *hasResult = true; *hasResultType = true; break; - case SpvOpLoopMerge: *hasResult = false; *hasResultType = false; break; - case SpvOpSelectionMerge: *hasResult = false; *hasResultType = false; break; - case SpvOpLabel: *hasResult = true; *hasResultType = false; break; - case SpvOpBranch: *hasResult = false; *hasResultType = false; break; - case SpvOpBranchConditional: *hasResult = false; *hasResultType = false; break; - case SpvOpSwitch: *hasResult = false; *hasResultType = false; break; - case SpvOpKill: *hasResult = false; *hasResultType = false; break; - case SpvOpReturn: *hasResult = false; *hasResultType = false; break; - case SpvOpReturnValue: *hasResult = false; *hasResultType = false; break; - case SpvOpUnreachable: *hasResult = false; *hasResultType = false; break; - case SpvOpLifetimeStart: *hasResult = false; *hasResultType = false; break; - case SpvOpLifetimeStop: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupAsyncCopy: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupWaitEvents: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupAll: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupAny: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupBroadcast: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupIAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFMin: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupUMin: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupSMin: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFMax: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupUMax: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupSMax: *hasResult = true; *hasResultType = true; break; - case SpvOpReadPipe: *hasResult = true; *hasResultType = true; break; - case SpvOpWritePipe: *hasResult = true; *hasResultType = true; break; - case SpvOpReservedReadPipe: *hasResult = true; *hasResultType = true; break; - case SpvOpReservedWritePipe: *hasResult = true; *hasResultType = true; break; - case SpvOpReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; - case SpvOpReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; - case SpvOpCommitReadPipe: *hasResult = false; *hasResultType = false; break; - case SpvOpCommitWritePipe: *hasResult = false; *hasResultType = false; break; - case SpvOpIsValidReserveId: *hasResult = true; *hasResultType = true; break; - case SpvOpGetNumPipePackets: *hasResult = true; *hasResultType = true; break; - case SpvOpGetMaxPipePackets: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupReserveReadPipePackets: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupReserveWritePipePackets: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupCommitReadPipe: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupCommitWritePipe: *hasResult = false; *hasResultType = false; break; - case SpvOpEnqueueMarker: *hasResult = true; *hasResultType = true; break; - case SpvOpEnqueueKernel: *hasResult = true; *hasResultType = true; break; - case SpvOpGetKernelNDrangeSubGroupCount: *hasResult = true; *hasResultType = true; break; - case SpvOpGetKernelNDrangeMaxSubGroupSize: *hasResult = true; *hasResultType = true; break; - case SpvOpGetKernelWorkGroupSize: *hasResult = true; *hasResultType = true; break; - case SpvOpGetKernelPreferredWorkGroupSizeMultiple: *hasResult = true; *hasResultType = true; break; - case SpvOpRetainEvent: *hasResult = false; *hasResultType = false; break; - case SpvOpReleaseEvent: *hasResult = false; *hasResultType = false; break; - case SpvOpCreateUserEvent: *hasResult = true; *hasResultType = true; break; - case SpvOpIsValidEvent: *hasResult = true; *hasResultType = true; break; - case SpvOpSetUserEventStatus: *hasResult = false; *hasResultType = false; break; - case SpvOpCaptureEventProfilingInfo: *hasResult = false; *hasResultType = false; break; - case SpvOpGetDefaultQueue: *hasResult = true; *hasResultType = true; break; - case SpvOpBuildNDRange: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleProjImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleProjExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleProjDrefImplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseSampleProjDrefExplicitLod: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseFetch: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseGather: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseDrefGather: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSparseTexelsResident: *hasResult = true; *hasResultType = true; break; - case SpvOpNoLine: *hasResult = false; *hasResultType = false; break; - case SpvOpAtomicFlagTestAndSet: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicFlagClear: *hasResult = false; *hasResultType = false; break; - case SpvOpImageSparseRead: *hasResult = true; *hasResultType = true; break; - case SpvOpSizeOf: *hasResult = true; *hasResultType = true; break; - case SpvOpTypePipeStorage: *hasResult = true; *hasResultType = false; break; - case SpvOpConstantPipeStorage: *hasResult = true; *hasResultType = true; break; - case SpvOpCreatePipeFromPipeStorage: *hasResult = true; *hasResultType = true; break; - case SpvOpGetKernelLocalSizeForSubgroupCount: *hasResult = true; *hasResultType = true; break; - case SpvOpGetKernelMaxNumSubgroups: *hasResult = true; *hasResultType = true; break; - case SpvOpTypeNamedBarrier: *hasResult = true; *hasResultType = false; break; - case SpvOpNamedBarrierInitialize: *hasResult = true; *hasResultType = true; break; - case SpvOpMemoryNamedBarrier: *hasResult = false; *hasResultType = false; break; - case SpvOpModuleProcessed: *hasResult = false; *hasResultType = false; break; - case SpvOpExecutionModeId: *hasResult = false; *hasResultType = false; break; - case SpvOpDecorateId: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupNonUniformElect: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformAll: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformAny: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformAllEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBroadcast: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBroadcastFirst: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBallot: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformInverseBallot: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBallotBitExtract: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBallotBitCount: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBallotFindLSB: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBallotFindMSB: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformShuffle: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformShuffleXor: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformShuffleUp: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformShuffleDown: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformIAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformFAdd: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformIMul: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformFMul: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformSMin: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformUMin: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformFMin: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformSMax: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformUMax: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformFMax: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBitwiseAnd: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBitwiseOr: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformBitwiseXor: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformLogicalAnd: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformLogicalOr: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformLogicalXor: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformQuadBroadcast: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformQuadSwap: *hasResult = true; *hasResultType = true; break; - case SpvOpCopyLogical: *hasResult = true; *hasResultType = true; break; - case SpvOpPtrEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpPtrNotEqual: *hasResult = true; *hasResultType = true; break; - case SpvOpPtrDiff: *hasResult = true; *hasResultType = true; break; - case SpvOpTerminateInvocation: *hasResult = false; *hasResultType = false; break; - case SpvOpSubgroupBallotKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupFirstInvocationKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAllKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAnyKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAllEqualKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupNonUniformRotateKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupReadInvocationKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpTraceRayKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpExecuteCallableKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpConvertUToAccelerationStructureKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpIgnoreIntersectionKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpTerminateRayKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpSDot: *hasResult = true; *hasResultType = true; break; - case SpvOpUDot: *hasResult = true; *hasResultType = true; break; - case SpvOpSUDot: *hasResult = true; *hasResultType = true; break; - case SpvOpSDotAccSat: *hasResult = true; *hasResultType = true; break; - case SpvOpUDotAccSat: *hasResult = true; *hasResultType = true; break; - case SpvOpSUDotAccSat: *hasResult = true; *hasResultType = true; break; - case SpvOpTypeRayQueryKHR: *hasResult = true; *hasResultType = false; break; - case SpvOpRayQueryInitializeKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpRayQueryTerminateKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpRayQueryGenerateIntersectionKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpRayQueryConfirmIntersectionKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpRayQueryProceedKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionTypeKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupIAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFAddNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupUMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupSMinNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupUMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupSMaxNonUniformAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpFragmentMaskFetchAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpFragmentFetchAMD: *hasResult = true; *hasResultType = true; break; - case SpvOpReadClockKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpImageSampleFootprintNV: *hasResult = true; *hasResultType = true; break; - case SpvOpEmitMeshTasksEXT: *hasResult = false; *hasResultType = false; break; - case SpvOpSetMeshOutputsEXT: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupNonUniformPartitionNV: *hasResult = true; *hasResultType = true; break; - case SpvOpWritePackedPrimitiveIndices4x8NV: *hasResult = false; *hasResultType = false; break; - case SpvOpReportIntersectionNV: *hasResult = true; *hasResultType = true; break; - case SpvOpIgnoreIntersectionNV: *hasResult = false; *hasResultType = false; break; - case SpvOpTerminateRayNV: *hasResult = false; *hasResultType = false; break; - case SpvOpTraceNV: *hasResult = false; *hasResultType = false; break; - case SpvOpTraceMotionNV: *hasResult = false; *hasResultType = false; break; - case SpvOpTraceRayMotionNV: *hasResult = false; *hasResultType = false; break; - case SpvOpTypeAccelerationStructureNV: *hasResult = true; *hasResultType = false; break; - case SpvOpExecuteCallableNV: *hasResult = false; *hasResultType = false; break; - case SpvOpTypeCooperativeMatrixNV: *hasResult = true; *hasResultType = false; break; - case SpvOpCooperativeMatrixLoadNV: *hasResult = true; *hasResultType = true; break; - case SpvOpCooperativeMatrixStoreNV: *hasResult = false; *hasResultType = false; break; - case SpvOpCooperativeMatrixMulAddNV: *hasResult = true; *hasResultType = true; break; - case SpvOpCooperativeMatrixLengthNV: *hasResult = true; *hasResultType = true; break; - case SpvOpBeginInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; - case SpvOpEndInvocationInterlockEXT: *hasResult = false; *hasResultType = false; break; - case SpvOpDemoteToHelperInvocation: *hasResult = false; *hasResultType = false; break; - case SpvOpIsHelperInvocationEXT: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertUToImageNV: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertUToSamplerNV: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertImageToUNV: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertSamplerToUNV: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertUToSampledImageNV: *hasResult = true; *hasResultType = true; break; - case SpvOpConvertSampledImageToUNV: *hasResult = true; *hasResultType = true; break; - case SpvOpSamplerImageAddressingModeNV: *hasResult = false; *hasResultType = false; break; - case SpvOpSubgroupShuffleINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupShuffleDownINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupShuffleUpINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupShuffleXorINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupBlockReadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpSubgroupImageBlockReadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupImageBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpSubgroupImageMediaBlockReadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupImageMediaBlockWriteINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpUCountLeadingZerosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpUCountTrailingZerosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpAbsISubINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpAbsUSubINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpIAddSatINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpUAddSatINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpIAverageINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpUAverageINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpIAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpUAverageRoundedINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpISubSatINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpUSubSatINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpIMul32x16INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpUMul32x16INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpConstantFunctionPointerINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFunctionPointerCallINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpAsmTargetINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpAsmINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpAsmCallINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicFMinEXT: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicFMaxEXT: *hasResult = true; *hasResultType = true; break; - case SpvOpAssumeTrueKHR: *hasResult = false; *hasResultType = false; break; - case SpvOpExpectKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpDecorateString: *hasResult = false; *hasResultType = false; break; - case SpvOpMemberDecorateString: *hasResult = false; *hasResultType = false; break; - case SpvOpVmeImageINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpTypeVmeImageINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcImePayloadINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcRefPayloadINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcSicPayloadINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcMcePayloadINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcMceResultINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcImeResultINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcImeResultSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcImeResultDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcImeSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcImeDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcRefResultINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeAvcSicResultINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpSubgroupAvcMceGetDefaultInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetInterBaseMultiReferencePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetInterShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetInterDirectionPenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultInterMotionVectorCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultHighPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultMediumPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultLowPenaltyCostTableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetMotionVectorCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultIntraLumaModePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultNonDcLumaIntraPenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetDefaultIntraChromaModeBasePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetAcOnlyHaarINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetSourceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetSingleReferenceInterlacedFieldPolarityINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceSetDualReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceConvertToImePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceConvertToImeResultINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceConvertToRefPayloadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceConvertToRefResultINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceConvertToSicPayloadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceConvertToSicResultINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetBestInterDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterMajorShapeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterMinorShapeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterDirectionsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcMceGetInterReferenceInterlacedFieldPolaritiesINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeSetSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeSetDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeRefWindowSizeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeAdjustRefOffsetINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeSetMaxMotionVectorCountINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeSetUnidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeSetEarlySearchTerminationThresholdINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeSetWeightedSadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithSingleReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeEvaluateWithDualReferenceStreaminoutINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetSingleReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetDualReferenceStreaminINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeStripSingleReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeStripDualReferenceStreamoutINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetStreamoutSingleReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeMotionVectorsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeDistortionsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetStreamoutDualReferenceMajorShapeReferenceIdsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetBorderReachedINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetTruncatedSearchIndicationINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetUnidirectionalEarlySearchTerminationINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetWeightingPatternMinimumMotionVectorINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcImeGetWeightingPatternMinimumDistortionINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcFmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcBmeInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefSetBidirectionalMixDisableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcRefConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicInitializeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicConfigureSkcINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicConfigureIpeLumaINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicConfigureIpeLumaChromaINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetMotionVectorMaskINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicConvertToMcePayloadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicSetIntraLumaShapePenaltyINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicSetIntraLumaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicSetIntraChromaModeCostFunctionINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicSetBilinearFilterEnableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicSetSkcForwardTransformEnableINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicSetBlockBasedRawSkipSadINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicEvaluateIpeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicEvaluateWithSingleReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicEvaluateWithDualReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicEvaluateWithMultiReferenceInterlacedINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicConvertToMceResultINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetIpeLumaShapeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetBestIpeLumaDistortionINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetBestIpeChromaDistortionINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetPackedIpeLumaModesINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetIpeChromaModeINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetPackedSkcLumaCountThresholdINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetPackedSkcLumaSumThresholdINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSubgroupAvcSicGetInterRawSadsINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpVariableLengthArrayINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpSaveMemoryINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpRestoreMemoryINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpArbitraryFloatSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatCastINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatCastFromIntINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatCastToIntINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatAddINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatSubINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatMulINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatDivINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatGTINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatGEINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatLTINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatLEINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatEQINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatRecipINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatRSqrtINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatCbrtINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatHypotINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatSqrtINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatLogINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatLog2INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatLog10INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatLog1pINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatExpINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatExp2INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatExp10INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatExpm1INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatSinINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatCosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatSinCosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatSinPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatCosPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatASinINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatASinPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatACosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatACosPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatATanINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatATanPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatATan2INTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatPowINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatPowRINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpArbitraryFloatPowNINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpLoopControlINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpAliasDomainDeclINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpAliasScopeDeclINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpAliasScopeListDeclINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpFixedSqrtINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedRecipINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedRsqrtINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedSinINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedCosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedSinCosINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedSinPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedCosPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedSinCosPiINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedLogINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFixedExpINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpPtrCastToCrossWorkgroupINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpCrossWorkgroupCastToPtrINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpReadPipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpWritePipeBlockingINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpFPGARegINTEL: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetRayTMinKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetRayFlagsKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionTKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionInstanceCustomIndexKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionInstanceIdKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffsetKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionGeometryIndexKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionPrimitiveIndexKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionBarycentricsKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionFrontFaceKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionCandidateAABBOpaqueKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionObjectRayDirectionKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionObjectRayOriginKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetWorldRayDirectionKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetWorldRayOriginKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionObjectToWorldKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpRayQueryGetIntersectionWorldToObjectKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpAtomicFAddEXT: *hasResult = true; *hasResultType = true; break; - case SpvOpTypeBufferSurfaceINTEL: *hasResult = true; *hasResultType = false; break; - case SpvOpTypeStructContinuedINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpSpecConstantCompositeContinuedINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpControlBarrierArriveINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpControlBarrierWaitINTEL: *hasResult = false; *hasResultType = false; break; - case SpvOpGroupIMulKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupFMulKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupBitwiseAndKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupBitwiseOrKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupBitwiseXorKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupLogicalAndKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupLogicalOrKHR: *hasResult = true; *hasResultType = true; break; - case SpvOpGroupLogicalXorKHR: *hasResult = true; *hasResultType = true; break; - } -} -#endif /* SPV_ENABLE_UTILITY_CODE */ - -#endif - diff --git a/src/libraries/spirv_cross/spirv_cross_c.cpp b/src/libraries/spirv_cross/spirv_cross_c.cpp deleted file mode 100644 index dc2e5ea81..000000000 --- a/src/libraries/spirv_cross/spirv_cross_c.cpp +++ /dev/null @@ -1,2875 +0,0 @@ -/* - * Copyright 2019-2021 Hans-Kristian Arntzen - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - * 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. - */ - -/* - * At your option, you may choose to accept this material under either: - * 1. The Apache License, Version 2.0, found at , or - * 2. The MIT License, found at . - */ - -#include "spirv_cross_c.h" - -#if SPIRV_CROSS_C_API_CPP -#include "spirv_cpp.hpp" -#endif -#if SPIRV_CROSS_C_API_GLSL -#include "spirv_glsl.hpp" -#else -#include "spirv_cross.hpp" -#endif -#if SPIRV_CROSS_C_API_HLSL -#include "spirv_hlsl.hpp" -#endif -#if SPIRV_CROSS_C_API_MSL -#include "spirv_msl.hpp" -#endif -#if SPIRV_CROSS_C_API_REFLECT -#include "spirv_reflect.hpp" -#endif - -#ifdef HAVE_SPIRV_CROSS_GIT_VERSION -#include "gitversion.h" -#endif - -#include "spirv_parser.hpp" -#include -#include -#include - -// clang-format off - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4996) -#endif - -#ifndef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS -#define SPVC_BEGIN_SAFE_SCOPE try -#else -#define SPVC_BEGIN_SAFE_SCOPE -#endif - -#ifndef SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS -#define SPVC_END_SAFE_SCOPE(context, error) \ - catch (const std::exception &e) \ - { \ - (context)->report_error(e.what()); \ - return (error); \ - } -#else -#define SPVC_END_SAFE_SCOPE(context, error) -#endif - -using namespace std; -using namespace SPIRV_CROSS_NAMESPACE; - -struct ScratchMemoryAllocation -{ - virtual ~ScratchMemoryAllocation() = default; -}; - -struct StringAllocation : ScratchMemoryAllocation -{ - explicit StringAllocation(const char *name) - : str(name) - { - } - - explicit StringAllocation(std::string name) - : str(std::move(name)) - { - } - - std::string str; -}; - -template -struct TemporaryBuffer : ScratchMemoryAllocation -{ - SmallVector buffer; -}; - -template -static inline std::unique_ptr spvc_allocate(Ts &&... ts) -{ - return std::unique_ptr(new T(std::forward(ts)...)); -} - -struct spvc_context_s -{ - string last_error; - SmallVector> allocations; - const char *allocate_name(const std::string &name); - - spvc_error_callback callback = nullptr; - void *callback_userdata = nullptr; - void report_error(std::string msg); -}; - -void spvc_context_s::report_error(std::string msg) -{ - last_error = std::move(msg); - if (callback) - callback(callback_userdata, last_error.c_str()); -} - -const char *spvc_context_s::allocate_name(const std::string &name) -{ - SPVC_BEGIN_SAFE_SCOPE - { - auto alloc = spvc_allocate(name); - auto *ret = alloc->str.c_str(); - allocations.emplace_back(std::move(alloc)); - return ret; - } - SPVC_END_SAFE_SCOPE(this, nullptr) -} - -struct spvc_parsed_ir_s : ScratchMemoryAllocation -{ - spvc_context context = nullptr; - ParsedIR parsed; -}; - -struct spvc_compiler_s : ScratchMemoryAllocation -{ - spvc_context context = nullptr; - unique_ptr compiler; - spvc_backend backend = SPVC_BACKEND_NONE; -}; - -struct spvc_compiler_options_s : ScratchMemoryAllocation -{ - spvc_context context = nullptr; - uint32_t backend_flags = 0; -#if SPIRV_CROSS_C_API_GLSL - CompilerGLSL::Options glsl; -#endif -#if SPIRV_CROSS_C_API_MSL - CompilerMSL::Options msl; -#endif -#if SPIRV_CROSS_C_API_HLSL - CompilerHLSL::Options hlsl; -#endif -}; - -struct spvc_set_s : ScratchMemoryAllocation -{ - std::unordered_set set; -}; - -// Dummy-inherit to we can keep our opaque type handle type safe in C-land as well, -// and avoid just throwing void * around. -struct spvc_type_s : SPIRType -{ -}; - -struct spvc_constant_s : SPIRConstant -{ -}; - -struct spvc_resources_s : ScratchMemoryAllocation -{ - spvc_context context = nullptr; - SmallVector uniform_buffers; - SmallVector storage_buffers; - SmallVector stage_inputs; - SmallVector stage_outputs; - SmallVector subpass_inputs; - SmallVector storage_images; - SmallVector sampled_images; - SmallVector atomic_counters; - SmallVector push_constant_buffers; - SmallVector shader_record_buffers; - SmallVector separate_images; - SmallVector separate_samplers; - SmallVector acceleration_structures; - SmallVector builtin_inputs; - SmallVector builtin_outputs; - - bool copy_resources(SmallVector &outputs, const SmallVector &inputs); - bool copy_resources(SmallVector &outputs, const SmallVector &inputs); - bool copy_resources(const ShaderResources &resources); -}; - -spvc_result spvc_context_create(spvc_context *context) -{ - auto *ctx = new (std::nothrow) spvc_context_s; - if (!ctx) - return SPVC_ERROR_OUT_OF_MEMORY; - - *context = ctx; - return SPVC_SUCCESS; -} - -void spvc_context_destroy(spvc_context context) -{ - delete context; -} - -void spvc_context_release_allocations(spvc_context context) -{ - context->allocations.clear(); -} - -const char *spvc_context_get_last_error_string(spvc_context context) -{ - return context->last_error.c_str(); -} - -SPVC_PUBLIC_API void spvc_context_set_error_callback(spvc_context context, spvc_error_callback cb, void *userdata) -{ - context->callback = cb; - context->callback_userdata = userdata; -} - -spvc_result spvc_context_parse_spirv(spvc_context context, const SpvId *spirv, size_t word_count, - spvc_parsed_ir *parsed_ir) -{ - SPVC_BEGIN_SAFE_SCOPE - { - std::unique_ptr pir(new (std::nothrow) spvc_parsed_ir_s); - if (!pir) - { - context->report_error("Out of memory."); - return SPVC_ERROR_OUT_OF_MEMORY; - } - - pir->context = context; - Parser parser(spirv, word_count); - parser.parse(); - pir->parsed = std::move(parser.get_parsed_ir()); - *parsed_ir = pir.get(); - context->allocations.push_back(std::move(pir)); - } - SPVC_END_SAFE_SCOPE(context, SPVC_ERROR_INVALID_SPIRV) - return SPVC_SUCCESS; -} - -spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend backend, spvc_parsed_ir parsed_ir, - spvc_capture_mode mode, spvc_compiler *compiler) -{ - SPVC_BEGIN_SAFE_SCOPE - { - std::unique_ptr comp(new (std::nothrow) spvc_compiler_s); - if (!comp) - { - context->report_error("Out of memory."); - return SPVC_ERROR_OUT_OF_MEMORY; - } - comp->backend = backend; - comp->context = context; - - if (mode != SPVC_CAPTURE_MODE_COPY && mode != SPVC_CAPTURE_MODE_TAKE_OWNERSHIP) - { - context->report_error("Invalid argument for capture mode."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - switch (backend) - { - case SPVC_BACKEND_NONE: - if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP) - comp->compiler.reset(new Compiler(std::move(parsed_ir->parsed))); - else if (mode == SPVC_CAPTURE_MODE_COPY) - comp->compiler.reset(new Compiler(parsed_ir->parsed)); - break; - -#if SPIRV_CROSS_C_API_GLSL - case SPVC_BACKEND_GLSL: - if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP) - comp->compiler.reset(new CompilerGLSL(std::move(parsed_ir->parsed))); - else if (mode == SPVC_CAPTURE_MODE_COPY) - comp->compiler.reset(new CompilerGLSL(parsed_ir->parsed)); - break; -#endif - -#if SPIRV_CROSS_C_API_HLSL - case SPVC_BACKEND_HLSL: - if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP) - comp->compiler.reset(new CompilerHLSL(std::move(parsed_ir->parsed))); - else if (mode == SPVC_CAPTURE_MODE_COPY) - comp->compiler.reset(new CompilerHLSL(parsed_ir->parsed)); - break; -#endif - -#if SPIRV_CROSS_C_API_MSL - case SPVC_BACKEND_MSL: - if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP) - comp->compiler.reset(new CompilerMSL(std::move(parsed_ir->parsed))); - else if (mode == SPVC_CAPTURE_MODE_COPY) - comp->compiler.reset(new CompilerMSL(parsed_ir->parsed)); - break; -#endif - -#if SPIRV_CROSS_C_API_CPP - case SPVC_BACKEND_CPP: - if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP) - comp->compiler.reset(new CompilerCPP(std::move(parsed_ir->parsed))); - else if (mode == SPVC_CAPTURE_MODE_COPY) - comp->compiler.reset(new CompilerCPP(parsed_ir->parsed)); - break; -#endif - -#if SPIRV_CROSS_C_API_REFLECT - case SPVC_BACKEND_JSON: - if (mode == SPVC_CAPTURE_MODE_TAKE_OWNERSHIP) - comp->compiler.reset(new CompilerReflection(std::move(parsed_ir->parsed))); - else if (mode == SPVC_CAPTURE_MODE_COPY) - comp->compiler.reset(new CompilerReflection(parsed_ir->parsed)); - break; -#endif - - default: - context->report_error("Invalid backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - *compiler = comp.get(); - context->allocations.push_back(std::move(comp)); - } - SPVC_END_SAFE_SCOPE(context, SPVC_ERROR_OUT_OF_MEMORY) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_create_compiler_options(spvc_compiler compiler, spvc_compiler_options *options) -{ - SPVC_BEGIN_SAFE_SCOPE - { - std::unique_ptr opt(new (std::nothrow) spvc_compiler_options_s); - if (!opt) - { - compiler->context->report_error("Out of memory."); - return SPVC_ERROR_OUT_OF_MEMORY; - } - - opt->context = compiler->context; - opt->backend_flags = 0; - switch (compiler->backend) - { -#if SPIRV_CROSS_C_API_MSL - case SPVC_BACKEND_MSL: - opt->backend_flags |= SPVC_COMPILER_OPTION_MSL_BIT | SPVC_COMPILER_OPTION_COMMON_BIT; - opt->glsl = static_cast(compiler->compiler.get())->get_common_options(); - opt->msl = static_cast(compiler->compiler.get())->get_msl_options(); - break; -#endif - -#if SPIRV_CROSS_C_API_HLSL - case SPVC_BACKEND_HLSL: - opt->backend_flags |= SPVC_COMPILER_OPTION_HLSL_BIT | SPVC_COMPILER_OPTION_COMMON_BIT; - opt->glsl = static_cast(compiler->compiler.get())->get_common_options(); - opt->hlsl = static_cast(compiler->compiler.get())->get_hlsl_options(); - break; -#endif - -#if SPIRV_CROSS_C_API_GLSL - case SPVC_BACKEND_GLSL: - opt->backend_flags |= SPVC_COMPILER_OPTION_GLSL_BIT | SPVC_COMPILER_OPTION_COMMON_BIT; - opt->glsl = static_cast(compiler->compiler.get())->get_common_options(); - break; -#endif - - default: - break; - } - - *options = opt.get(); - compiler->context->allocations.push_back(std::move(opt)); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_options_set_bool(spvc_compiler_options options, spvc_compiler_option option, - spvc_bool value) -{ - return spvc_compiler_options_set_uint(options, option, value ? 1 : 0); -} - -spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, spvc_compiler_option option, unsigned value) -{ - (void)value; - (void)option; - uint32_t supported_mask = options->backend_flags; - uint32_t required_mask = option & SPVC_COMPILER_OPTION_LANG_BITS; - if ((required_mask | supported_mask) != supported_mask) - { - options->context->report_error("Option is not supported by current backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - switch (option) - { -#if SPIRV_CROSS_C_API_GLSL - case SPVC_COMPILER_OPTION_FORCE_TEMPORARY: - options->glsl.force_temporary = value != 0; - break; - case SPVC_COMPILER_OPTION_FLATTEN_MULTIDIMENSIONAL_ARRAYS: - options->glsl.flatten_multidimensional_arrays = value != 0; - break; - case SPVC_COMPILER_OPTION_FIXUP_DEPTH_CONVENTION: - options->glsl.vertex.fixup_clipspace = value != 0; - break; - case SPVC_COMPILER_OPTION_FLIP_VERTEX_Y: - options->glsl.vertex.flip_vert_y = value != 0; - break; - case SPVC_COMPILER_OPTION_EMIT_LINE_DIRECTIVES: - options->glsl.emit_line_directives = value != 0; - break; - case SPVC_COMPILER_OPTION_ENABLE_STORAGE_IMAGE_QUALIFIER_DEDUCTION: - options->glsl.enable_storage_image_qualifier_deduction = value != 0; - break; - case SPVC_COMPILER_OPTION_FORCE_ZERO_INITIALIZED_VARIABLES: - options->glsl.force_zero_initialized_variables = value != 0; - break; - - case SPVC_COMPILER_OPTION_GLSL_SUPPORT_NONZERO_BASE_INSTANCE: - options->glsl.vertex.support_nonzero_base_instance = value != 0; - break; - case SPVC_COMPILER_OPTION_GLSL_SEPARATE_SHADER_OBJECTS: - options->glsl.separate_shader_objects = value != 0; - break; - case SPVC_COMPILER_OPTION_GLSL_ENABLE_420PACK_EXTENSION: - options->glsl.enable_420pack_extension = value != 0; - break; - case SPVC_COMPILER_OPTION_GLSL_VERSION: - options->glsl.version = value; - break; - case SPVC_COMPILER_OPTION_GLSL_ES: - options->glsl.es = value != 0; - break; - case SPVC_COMPILER_OPTION_GLSL_VULKAN_SEMANTICS: - options->glsl.vulkan_semantics = value != 0; - break; - case SPVC_COMPILER_OPTION_GLSL_ES_DEFAULT_FLOAT_PRECISION_HIGHP: - options->glsl.fragment.default_float_precision = - value != 0 ? CompilerGLSL::Options::Precision::Highp : CompilerGLSL::Options::Precision::Mediump; - break; - case SPVC_COMPILER_OPTION_GLSL_ES_DEFAULT_INT_PRECISION_HIGHP: - options->glsl.fragment.default_int_precision = - value != 0 ? CompilerGLSL::Options::Precision::Highp : CompilerGLSL::Options::Precision::Mediump; - break; - case SPVC_COMPILER_OPTION_GLSL_EMIT_PUSH_CONSTANT_AS_UNIFORM_BUFFER: - options->glsl.emit_push_constant_as_uniform_buffer = value != 0; - break; - case SPVC_COMPILER_OPTION_GLSL_EMIT_UNIFORM_BUFFER_AS_PLAIN_UNIFORMS: - options->glsl.emit_uniform_buffer_as_plain_uniforms = value != 0; - break; - case SPVC_COMPILER_OPTION_GLSL_FORCE_FLATTENED_IO_BLOCKS: - options->glsl.force_flattened_io_blocks = value != 0; - break; - case SPVC_COMPILER_OPTION_GLSL_OVR_MULTIVIEW_VIEW_COUNT: - options->glsl.ovr_multiview_view_count = value; - break; - case SPVC_COMPILER_OPTION_RELAX_NAN_CHECKS: - options->glsl.relax_nan_checks = value != 0; - break; - case SPVC_COMPILER_OPTION_GLSL_ENABLE_ROW_MAJOR_LOAD_WORKAROUND: - options->glsl.enable_row_major_load_workaround = value != 0; - break; -#endif - -#if SPIRV_CROSS_C_API_HLSL - case SPVC_COMPILER_OPTION_HLSL_SHADER_MODEL: - options->hlsl.shader_model = value; - break; - - case SPVC_COMPILER_OPTION_HLSL_POINT_SIZE_COMPAT: - options->hlsl.point_size_compat = value != 0; - break; - - case SPVC_COMPILER_OPTION_HLSL_POINT_COORD_COMPAT: - options->hlsl.point_coord_compat = value != 0; - break; - - case SPVC_COMPILER_OPTION_HLSL_SUPPORT_NONZERO_BASE_VERTEX_BASE_INSTANCE: - options->hlsl.support_nonzero_base_vertex_base_instance = value != 0; - break; - - case SPVC_COMPILER_OPTION_HLSL_FORCE_STORAGE_BUFFER_AS_UAV: - options->hlsl.force_storage_buffer_as_uav = value != 0; - break; - - case SPVC_COMPILER_OPTION_HLSL_NONWRITABLE_UAV_TEXTURE_AS_SRV: - options->hlsl.nonwritable_uav_texture_as_srv = value != 0; - break; - - case SPVC_COMPILER_OPTION_HLSL_ENABLE_16BIT_TYPES: - options->hlsl.enable_16bit_types = value != 0; - break; - - case SPVC_COMPILER_OPTION_HLSL_FLATTEN_MATRIX_VERTEX_INPUT_SEMANTICS: - options->hlsl.flatten_matrix_vertex_input_semantics = value != 0; - break; -#endif - -#if SPIRV_CROSS_C_API_MSL - case SPVC_COMPILER_OPTION_MSL_VERSION: - options->msl.msl_version = value; - break; - - case SPVC_COMPILER_OPTION_MSL_TEXEL_BUFFER_TEXTURE_WIDTH: - options->msl.texel_buffer_texture_width = value; - break; - - case SPVC_COMPILER_OPTION_MSL_SWIZZLE_BUFFER_INDEX: - options->msl.swizzle_buffer_index = value; - break; - - case SPVC_COMPILER_OPTION_MSL_INDIRECT_PARAMS_BUFFER_INDEX: - options->msl.indirect_params_buffer_index = value; - break; - - case SPVC_COMPILER_OPTION_MSL_SHADER_OUTPUT_BUFFER_INDEX: - options->msl.shader_output_buffer_index = value; - break; - - case SPVC_COMPILER_OPTION_MSL_SHADER_PATCH_OUTPUT_BUFFER_INDEX: - options->msl.shader_patch_output_buffer_index = value; - break; - - case SPVC_COMPILER_OPTION_MSL_SHADER_TESS_FACTOR_OUTPUT_BUFFER_INDEX: - options->msl.shader_tess_factor_buffer_index = value; - break; - - case SPVC_COMPILER_OPTION_MSL_SHADER_INPUT_WORKGROUP_INDEX: - options->msl.shader_input_wg_index = value; - break; - - case SPVC_COMPILER_OPTION_MSL_ENABLE_POINT_SIZE_BUILTIN: - options->msl.enable_point_size_builtin = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_DISABLE_RASTERIZATION: - options->msl.disable_rasterization = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_CAPTURE_OUTPUT_TO_BUFFER: - options->msl.capture_output_to_buffer = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_SWIZZLE_TEXTURE_SAMPLES: - options->msl.swizzle_texture_samples = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_PAD_FRAGMENT_OUTPUT_COMPONENTS: - options->msl.pad_fragment_output_components = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_TESS_DOMAIN_ORIGIN_LOWER_LEFT: - options->msl.tess_domain_origin_lower_left = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_PLATFORM: - options->msl.platform = static_cast(value); - break; - - case SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS: - options->msl.argument_buffers = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_TEXTURE_BUFFER_NATIVE: - options->msl.texture_buffer_native = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_BUFFER_SIZE_BUFFER_INDEX: - options->msl.buffer_size_buffer_index = value; - break; - - case SPVC_COMPILER_OPTION_MSL_MULTIVIEW: - options->msl.multiview = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_VIEW_MASK_BUFFER_INDEX: - options->msl.view_mask_buffer_index = value; - break; - - case SPVC_COMPILER_OPTION_MSL_DEVICE_INDEX: - options->msl.device_index = value; - break; - - case SPVC_COMPILER_OPTION_MSL_VIEW_INDEX_FROM_DEVICE_INDEX: - options->msl.view_index_from_device_index = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_DISPATCH_BASE: - options->msl.dispatch_base = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_DYNAMIC_OFFSETS_BUFFER_INDEX: - options->msl.dynamic_offsets_buffer_index = value; - break; - - case SPVC_COMPILER_OPTION_MSL_TEXTURE_1D_AS_2D: - options->msl.texture_1D_as_2D = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_ENABLE_BASE_INDEX_ZERO: - options->msl.enable_base_index_zero = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_FRAMEBUFFER_FETCH_SUBPASS: - options->msl.use_framebuffer_fetch_subpasses = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_INVARIANT_FP_MATH: - options->msl.invariant_float_math = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_EMULATE_CUBEMAP_ARRAY: - options->msl.emulate_cube_array = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_ENABLE_DECORATION_BINDING: - options->msl.enable_decoration_binding = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_FORCE_ACTIVE_ARGUMENT_BUFFER_RESOURCES: - options->msl.force_active_argument_buffer_resources = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_FORCE_NATIVE_ARRAYS: - options->msl.force_native_arrays = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_ENABLE_FRAG_OUTPUT_MASK: - options->msl.enable_frag_output_mask = value; - break; - - case SPVC_COMPILER_OPTION_MSL_ENABLE_FRAG_DEPTH_BUILTIN: - options->msl.enable_frag_depth_builtin = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_ENABLE_FRAG_STENCIL_REF_BUILTIN: - options->msl.enable_frag_stencil_ref_builtin = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_ENABLE_CLIP_DISTANCE_USER_VARYING: - options->msl.enable_clip_distance_user_varying = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_MULTI_PATCH_WORKGROUP: - options->msl.multi_patch_workgroup = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_SHADER_INPUT_BUFFER_INDEX: - options->msl.shader_input_buffer_index = value; - break; - - case SPVC_COMPILER_OPTION_MSL_SHADER_INDEX_BUFFER_INDEX: - options->msl.shader_index_buffer_index = value; - break; - - case SPVC_COMPILER_OPTION_MSL_VERTEX_FOR_TESSELLATION: - options->msl.vertex_for_tessellation = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_VERTEX_INDEX_TYPE: - options->msl.vertex_index_type = static_cast(value); - break; - - case SPVC_COMPILER_OPTION_MSL_MULTIVIEW_LAYERED_RENDERING: - options->msl.multiview_layered_rendering = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_ARRAYED_SUBPASS_INPUT: - options->msl.arrayed_subpass_input = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_R32UI_LINEAR_TEXTURE_ALIGNMENT: - options->msl.r32ui_linear_texture_alignment = value; - break; - - case SPVC_COMPILER_OPTION_MSL_R32UI_ALIGNMENT_CONSTANT_ID: - options->msl.r32ui_alignment_constant_id = value; - break; - - case SPVC_COMPILER_OPTION_MSL_IOS_USE_SIMDGROUP_FUNCTIONS: - options->msl.ios_use_simdgroup_functions = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_EMULATE_SUBGROUPS: - options->msl.emulate_subgroups = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_FIXED_SUBGROUP_SIZE: - options->msl.fixed_subgroup_size = value; - break; - - case SPVC_COMPILER_OPTION_MSL_FORCE_SAMPLE_RATE_SHADING: - options->msl.force_sample_rate_shading = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_IOS_SUPPORT_BASE_VERTEX_INSTANCE: - options->msl.ios_support_base_vertex_instance = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_RAW_BUFFER_TESE_INPUT: - options->msl.raw_buffer_tese_input = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_SHADER_PATCH_INPUT_BUFFER_INDEX: - options->msl.shader_patch_input_buffer_index = value; - break; - - case SPVC_COMPILER_OPTION_MSL_MANUAL_HELPER_INVOCATION_UPDATES: - options->msl.manual_helper_invocation_updates = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_CHECK_DISCARDED_FRAG_STORES: - options->msl.check_discarded_frag_stores = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS_TIER: - options->msl.argument_buffers_tier = static_cast(value); - break; - - case SPVC_COMPILER_OPTION_MSL_SAMPLE_DREF_LOD_ARRAY_AS_GRAD: - options->msl.sample_dref_lod_array_as_grad = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_READWRITE_TEXTURE_FENCES: - options->msl.readwrite_texture_fences = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_REPLACE_RECURSIVE_INPUTS: - options->msl.replace_recursive_inputs = value != 0; - break; - - case SPVC_COMPILER_OPTION_MSL_AGX_MANUAL_CUBE_GRAD_FIXUP: - options->msl.agx_manual_cube_grad_fixup = value != 0; - break; -#endif - - default: - options->context->report_error("Unknown option."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_install_compiler_options(spvc_compiler compiler, spvc_compiler_options options) -{ - (void)options; - switch (compiler->backend) - { -#if SPIRV_CROSS_C_API_GLSL - case SPVC_BACKEND_GLSL: - static_cast(*compiler->compiler).set_common_options(options->glsl); - break; -#endif - -#if SPIRV_CROSS_C_API_HLSL - case SPVC_BACKEND_HLSL: - static_cast(*compiler->compiler).set_common_options(options->glsl); - static_cast(*compiler->compiler).set_hlsl_options(options->hlsl); - break; -#endif - -#if SPIRV_CROSS_C_API_MSL - case SPVC_BACKEND_MSL: - static_cast(*compiler->compiler).set_common_options(options->glsl); - static_cast(*compiler->compiler).set_msl_options(options->msl); - break; -#endif - - default: - break; - } - - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_add_header_line(spvc_compiler compiler, const char *line) -{ -#if SPIRV_CROSS_C_API_GLSL - if (compiler->backend == SPVC_BACKEND_NONE) - { - compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - static_cast(compiler->compiler.get())->add_header_line(line); - return SPVC_SUCCESS; -#else - (void)line; - compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_require_extension(spvc_compiler compiler, const char *line) -{ -#if SPIRV_CROSS_C_API_GLSL - if (compiler->backend == SPVC_BACKEND_NONE) - { - compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - static_cast(compiler->compiler.get())->require_extension(line); - return SPVC_SUCCESS; -#else - (void)line; - compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -size_t spvc_compiler_get_num_required_extensions(spvc_compiler compiler) -{ -#if SPIRV_CROSS_C_API_GLSL - if (compiler->backend != SPVC_BACKEND_GLSL) - { - compiler->context->report_error("Enabled extensions can only be queried on GLSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - return static_cast(compiler->compiler.get())->get_required_extensions().size(); -#else - compiler->context->report_error("Enabled extensions can only be queried on GLSL backend."); - return 0; -#endif -} - -const char *spvc_compiler_get_required_extension(spvc_compiler compiler, size_t index) -{ -#if SPIRV_CROSS_C_API_GLSL - if (compiler->backend != SPVC_BACKEND_GLSL) - { - compiler->context->report_error("Enabled extensions can only be queried on GLSL backend."); - return nullptr; - } - - auto &exts = static_cast(compiler->compiler.get())->get_required_extensions(); - if (index < exts.size()) - return exts[index].c_str(); - else - return nullptr; -#else - (void)index; - compiler->context->report_error("Enabled extensions can only be queried on GLSL backend."); - return nullptr; -#endif -} - -spvc_result spvc_compiler_flatten_buffer_block(spvc_compiler compiler, spvc_variable_id id) -{ -#if SPIRV_CROSS_C_API_GLSL - if (compiler->backend == SPVC_BACKEND_NONE) - { - compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - static_cast(compiler->compiler.get())->flatten_buffer_block(id); - return SPVC_SUCCESS; -#else - (void)id; - compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_bool spvc_compiler_variable_is_depth_or_compare(spvc_compiler compiler, spvc_variable_id id) -{ -#if SPIRV_CROSS_C_API_GLSL - if (compiler->backend == SPVC_BACKEND_NONE) - { - compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - return static_cast(compiler->compiler.get())->variable_is_depth_or_compare(id) ? SPVC_TRUE : SPVC_FALSE; -#else - (void)id; - compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection."); - return SPVC_FALSE; -#endif -} - -spvc_result spvc_compiler_mask_stage_output_by_location(spvc_compiler compiler, - unsigned location, unsigned component) -{ -#if SPIRV_CROSS_C_API_GLSL - if (compiler->backend == SPVC_BACKEND_NONE) - { - compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - static_cast(compiler->compiler.get())->mask_stage_output_by_location(location, component); - return SPVC_SUCCESS; -#else - (void)location; - (void)component; - compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_mask_stage_output_by_builtin(spvc_compiler compiler, SpvBuiltIn builtin) -{ -#if SPIRV_CROSS_C_API_GLSL - if (compiler->backend == SPVC_BACKEND_NONE) - { - compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - static_cast(compiler->compiler.get())->mask_stage_output_by_builtin(spv::BuiltIn(builtin)); - return SPVC_SUCCESS; -#else - (void)builtin; - compiler->context->report_error("Cross-compilation related option used on NONE backend which only supports reflection."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_hlsl_set_root_constants_layout(spvc_compiler compiler, - const spvc_hlsl_root_constants *constant_info, - size_t count) -{ -#if SPIRV_CROSS_C_API_HLSL - if (compiler->backend != SPVC_BACKEND_HLSL) - { - compiler->context->report_error("HLSL function used on a non-HLSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &hlsl = *static_cast(compiler->compiler.get()); - vector roots; - roots.reserve(count); - for (size_t i = 0; i < count; i++) - { - RootConstants root; - root.binding = constant_info[i].binding; - root.space = constant_info[i].space; - root.start = constant_info[i].start; - root.end = constant_info[i].end; - roots.push_back(root); - } - - hlsl.set_root_constant_layouts(std::move(roots)); - return SPVC_SUCCESS; -#else - (void)constant_info; - (void)count; - compiler->context->report_error("HLSL function used on a non-HLSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_hlsl_add_vertex_attribute_remap(spvc_compiler compiler, - const spvc_hlsl_vertex_attribute_remap *remap, - size_t count) -{ -#if SPIRV_CROSS_C_API_HLSL - if (compiler->backend != SPVC_BACKEND_HLSL) - { - compiler->context->report_error("HLSL function used on a non-HLSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - HLSLVertexAttributeRemap re; - auto &hlsl = *static_cast(compiler->compiler.get()); - for (size_t i = 0; i < count; i++) - { - re.location = remap[i].location; - re.semantic = remap[i].semantic; - hlsl.add_vertex_attribute_remap(re); - } - - return SPVC_SUCCESS; -#else - (void)remap; - (void)count; - compiler->context->report_error("HLSL function used on a non-HLSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_variable_id spvc_compiler_hlsl_remap_num_workgroups_builtin(spvc_compiler compiler) -{ -#if SPIRV_CROSS_C_API_HLSL - if (compiler->backend != SPVC_BACKEND_HLSL) - { - compiler->context->report_error("HLSL function used on a non-HLSL backend."); - return 0; - } - - auto &hlsl = *static_cast(compiler->compiler.get()); - return hlsl.remap_num_workgroups_builtin(); -#else - compiler->context->report_error("HLSL function used on a non-HLSL backend."); - return 0; -#endif -} - -spvc_result spvc_compiler_hlsl_set_resource_binding_flags(spvc_compiler compiler, - spvc_hlsl_binding_flags flags) -{ -#if SPIRV_CROSS_C_API_HLSL - if (compiler->backend != SPVC_BACKEND_HLSL) - { - compiler->context->report_error("HLSL function used on a non-HLSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &hlsl = *static_cast(compiler->compiler.get()); - hlsl.set_resource_binding_flags(flags); - return SPVC_SUCCESS; -#else - (void)flags; - compiler->context->report_error("HLSL function used on a non-HLSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_hlsl_add_resource_binding(spvc_compiler compiler, - const spvc_hlsl_resource_binding *binding) -{ -#if SPIRV_CROSS_C_API_HLSL - if (compiler->backend != SPVC_BACKEND_HLSL) - { - compiler->context->report_error("HLSL function used on a non-HLSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &hlsl = *static_cast(compiler->compiler.get()); - HLSLResourceBinding bind; - bind.binding = binding->binding; - bind.desc_set = binding->desc_set; - bind.stage = static_cast(binding->stage); - bind.cbv.register_binding = binding->cbv.register_binding; - bind.cbv.register_space = binding->cbv.register_space; - bind.uav.register_binding = binding->uav.register_binding; - bind.uav.register_space = binding->uav.register_space; - bind.srv.register_binding = binding->srv.register_binding; - bind.srv.register_space = binding->srv.register_space; - bind.sampler.register_binding = binding->sampler.register_binding; - bind.sampler.register_space = binding->sampler.register_space; - hlsl.add_hlsl_resource_binding(bind); - return SPVC_SUCCESS; -#else - (void)binding; - compiler->context->report_error("HLSL function used on a non-HLSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_bool spvc_compiler_hlsl_is_resource_used(spvc_compiler compiler, SpvExecutionModel model, unsigned set, - unsigned binding) -{ -#if SPIRV_CROSS_C_API_HLSL - if (compiler->backend != SPVC_BACKEND_HLSL) - { - compiler->context->report_error("HLSL function used on a non-HLSL backend."); - return SPVC_FALSE; - } - - auto &hlsl = *static_cast(compiler->compiler.get()); - return hlsl.is_hlsl_resource_binding_used(static_cast(model), set, binding) ? SPVC_TRUE : - SPVC_FALSE; -#else - (void)model; - (void)set; - (void)binding; - compiler->context->report_error("HLSL function used on a non-HLSL backend."); - return SPVC_FALSE; -#endif -} - -spvc_bool spvc_compiler_msl_is_rasterization_disabled(spvc_compiler compiler) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; - } - - auto &msl = *static_cast(compiler->compiler.get()); - return msl.get_is_rasterization_disabled() ? SPVC_TRUE : SPVC_FALSE; -#else - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; -#endif -} - -spvc_bool spvc_compiler_msl_needs_swizzle_buffer(spvc_compiler compiler) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; - } - - auto &msl = *static_cast(compiler->compiler.get()); - return msl.needs_swizzle_buffer() ? SPVC_TRUE : SPVC_FALSE; -#else - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; -#endif -} - -spvc_bool spvc_compiler_msl_needs_buffer_size_buffer(spvc_compiler compiler) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; - } - - auto &msl = *static_cast(compiler->compiler.get()); - return msl.needs_buffer_size_buffer() ? SPVC_TRUE : SPVC_FALSE; -#else - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; -#endif -} - -spvc_bool spvc_compiler_msl_needs_aux_buffer(spvc_compiler compiler) -{ - return spvc_compiler_msl_needs_swizzle_buffer(compiler); -} - -spvc_bool spvc_compiler_msl_needs_output_buffer(spvc_compiler compiler) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; - } - - auto &msl = *static_cast(compiler->compiler.get()); - return msl.needs_output_buffer() ? SPVC_TRUE : SPVC_FALSE; -#else - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; -#endif -} - -spvc_bool spvc_compiler_msl_needs_patch_output_buffer(spvc_compiler compiler) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; - } - - auto &msl = *static_cast(compiler->compiler.get()); - return msl.needs_patch_output_buffer() ? SPVC_TRUE : SPVC_FALSE; -#else - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; -#endif -} - -spvc_bool spvc_compiler_msl_needs_input_threadgroup_mem(spvc_compiler compiler) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; - } - - auto &msl = *static_cast(compiler->compiler.get()); - return msl.needs_input_threadgroup_mem() ? SPVC_TRUE : SPVC_FALSE; -#else - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; -#endif -} - -spvc_result spvc_compiler_msl_add_vertex_attribute(spvc_compiler compiler, const spvc_msl_vertex_attribute *va) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - MSLShaderInterfaceVariable attr; - attr.location = va->location; - attr.format = static_cast(va->format); - attr.builtin = static_cast(va->builtin); - msl.add_msl_shader_input(attr); - return SPVC_SUCCESS; -#else - (void)va; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler, const spvc_msl_shader_interface_var *si) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - MSLShaderInterfaceVariable input; - input.location = si->location; - input.format = static_cast(si->format); - input.builtin = static_cast(si->builtin); - input.vecsize = si->vecsize; - msl.add_msl_shader_input(input); - return SPVC_SUCCESS; -#else - (void)si; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_msl_add_shader_input_2(spvc_compiler compiler, const spvc_msl_shader_interface_var_2 *si) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - MSLShaderInterfaceVariable input; - input.location = si->location; - input.format = static_cast(si->format); - input.builtin = static_cast(si->builtin); - input.vecsize = si->vecsize; - input.rate = static_cast(si->rate); - msl.add_msl_shader_input(input); - return SPVC_SUCCESS; -#else - (void)si; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_msl_add_shader_output(spvc_compiler compiler, const spvc_msl_shader_interface_var *so) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - MSLShaderInterfaceVariable output; - output.location = so->location; - output.format = static_cast(so->format); - output.builtin = static_cast(so->builtin); - output.vecsize = so->vecsize; - msl.add_msl_shader_output(output); - return SPVC_SUCCESS; -#else - (void)so; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_msl_add_shader_output_2(spvc_compiler compiler, const spvc_msl_shader_interface_var_2 *so) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - MSLShaderInterfaceVariable output; - output.location = so->location; - output.format = static_cast(so->format); - output.builtin = static_cast(so->builtin); - output.vecsize = so->vecsize; - output.rate = static_cast(so->rate); - msl.add_msl_shader_output(output); - return SPVC_SUCCESS; -#else - (void)so; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_msl_add_resource_binding(spvc_compiler compiler, - const spvc_msl_resource_binding *binding) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - MSLResourceBinding bind; - bind.binding = binding->binding; - bind.desc_set = binding->desc_set; - bind.stage = static_cast(binding->stage); - bind.msl_buffer = binding->msl_buffer; - bind.msl_texture = binding->msl_texture; - bind.msl_sampler = binding->msl_sampler; - msl.add_msl_resource_binding(bind); - return SPVC_SUCCESS; -#else - (void)binding; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_msl_add_dynamic_buffer(spvc_compiler compiler, unsigned desc_set, unsigned binding, unsigned index) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - msl.add_dynamic_buffer(desc_set, binding, index); - return SPVC_SUCCESS; -#else - (void)binding; - (void)desc_set; - (void)index; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_msl_add_inline_uniform_block(spvc_compiler compiler, unsigned desc_set, unsigned binding) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - msl.add_inline_uniform_block(desc_set, binding); - return SPVC_SUCCESS; -#else - (void)binding; - (void)desc_set; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_msl_add_discrete_descriptor_set(spvc_compiler compiler, unsigned desc_set) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - msl.add_discrete_descriptor_set(desc_set); - return SPVC_SUCCESS; -#else - (void)desc_set; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_msl_set_argument_buffer_device_address_space(spvc_compiler compiler, unsigned desc_set, spvc_bool device_address) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - msl.set_argument_buffer_device_address_space(desc_set, bool(device_address)); - return SPVC_SUCCESS; -#else - (void)desc_set; - (void)device_address; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_bool spvc_compiler_msl_is_shader_input_used(spvc_compiler compiler, unsigned location) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; - } - - auto &msl = *static_cast(compiler->compiler.get()); - return msl.is_msl_shader_input_used(location) ? SPVC_TRUE : SPVC_FALSE; -#else - (void)location; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; -#endif -} - -spvc_bool spvc_compiler_msl_is_shader_output_used(spvc_compiler compiler, unsigned location) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; - } - - auto &msl = *static_cast(compiler->compiler.get()); - return msl.is_msl_shader_output_used(location) ? SPVC_TRUE : SPVC_FALSE; -#else - (void)location; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; -#endif -} - -spvc_bool spvc_compiler_msl_is_vertex_attribute_used(spvc_compiler compiler, unsigned location) -{ - return spvc_compiler_msl_is_shader_input_used(compiler, location); -} - -spvc_bool spvc_compiler_msl_is_resource_used(spvc_compiler compiler, SpvExecutionModel model, unsigned set, - unsigned binding) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; - } - - auto &msl = *static_cast(compiler->compiler.get()); - return msl.is_msl_resource_binding_used(static_cast(model), set, binding) ? SPVC_TRUE : - SPVC_FALSE; -#else - (void)model; - (void)set; - (void)binding; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_FALSE; -#endif -} - -spvc_result spvc_compiler_msl_set_combined_sampler_suffix(spvc_compiler compiler, const char *suffix) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - msl.set_combined_sampler_suffix(suffix); - return SPVC_SUCCESS; -#else - (void)suffix; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -const char *spvc_compiler_msl_get_combined_sampler_suffix(spvc_compiler compiler) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return ""; - } - - auto &msl = *static_cast(compiler->compiler.get()); - return msl.get_combined_sampler_suffix(); -#else - compiler->context->report_error("MSL function used on a non-MSL backend."); - return ""; -#endif -} - -#if SPIRV_CROSS_C_API_MSL -static void spvc_convert_msl_sampler(MSLConstexprSampler &samp, const spvc_msl_constexpr_sampler *sampler) -{ - samp.s_address = static_cast(sampler->s_address); - samp.t_address = static_cast(sampler->t_address); - samp.r_address = static_cast(sampler->r_address); - samp.lod_clamp_min = sampler->lod_clamp_min; - samp.lod_clamp_max = sampler->lod_clamp_max; - samp.lod_clamp_enable = sampler->lod_clamp_enable != 0; - samp.min_filter = static_cast(sampler->min_filter); - samp.mag_filter = static_cast(sampler->mag_filter); - samp.mip_filter = static_cast(sampler->mip_filter); - samp.compare_enable = sampler->compare_enable != 0; - samp.anisotropy_enable = sampler->anisotropy_enable != 0; - samp.max_anisotropy = sampler->max_anisotropy; - samp.compare_func = static_cast(sampler->compare_func); - samp.coord = static_cast(sampler->coord); - samp.border_color = static_cast(sampler->border_color); -} - -static void spvc_convert_msl_sampler_ycbcr_conversion(MSLConstexprSampler &samp, const spvc_msl_sampler_ycbcr_conversion *conv) -{ - samp.ycbcr_conversion_enable = conv != nullptr; - if (conv == nullptr) return; - samp.planes = conv->planes; - samp.resolution = static_cast(conv->resolution); - samp.chroma_filter = static_cast(conv->chroma_filter); - samp.x_chroma_offset = static_cast(conv->x_chroma_offset); - samp.y_chroma_offset = static_cast(conv->y_chroma_offset); - for (int i = 0; i < 4; i++) - samp.swizzle[i] = static_cast(conv->swizzle[i]); - samp.ycbcr_model = static_cast(conv->ycbcr_model); - samp.ycbcr_range = static_cast(conv->ycbcr_range); - samp.bpc = conv->bpc; -} -#endif - -spvc_result spvc_compiler_msl_remap_constexpr_sampler(spvc_compiler compiler, spvc_variable_id id, - const spvc_msl_constexpr_sampler *sampler) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - MSLConstexprSampler samp; - spvc_convert_msl_sampler(samp, sampler); - msl.remap_constexpr_sampler(id, samp); - return SPVC_SUCCESS; -#else - (void)id; - (void)sampler; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_msl_remap_constexpr_sampler_by_binding(spvc_compiler compiler, - unsigned desc_set, unsigned binding, - const spvc_msl_constexpr_sampler *sampler) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - MSLConstexprSampler samp; - spvc_convert_msl_sampler(samp, sampler); - msl.remap_constexpr_sampler_by_binding(desc_set, binding, samp); - return SPVC_SUCCESS; -#else - (void)desc_set; - (void)binding; - (void)sampler; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_msl_remap_constexpr_sampler_ycbcr(spvc_compiler compiler, spvc_variable_id id, - const spvc_msl_constexpr_sampler *sampler, - const spvc_msl_sampler_ycbcr_conversion *conv) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - MSLConstexprSampler samp; - spvc_convert_msl_sampler(samp, sampler); - spvc_convert_msl_sampler_ycbcr_conversion(samp, conv); - msl.remap_constexpr_sampler(id, samp); - return SPVC_SUCCESS; -#else - (void)id; - (void)sampler; - (void)conv; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_msl_remap_constexpr_sampler_by_binding_ycbcr(spvc_compiler compiler, - unsigned desc_set, unsigned binding, - const spvc_msl_constexpr_sampler *sampler, - const spvc_msl_sampler_ycbcr_conversion *conv) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - MSLConstexprSampler samp; - spvc_convert_msl_sampler(samp, sampler); - spvc_convert_msl_sampler_ycbcr_conversion(samp, conv); - msl.remap_constexpr_sampler_by_binding(desc_set, binding, samp); - return SPVC_SUCCESS; -#else - (void)desc_set; - (void)binding; - (void)sampler; - (void)conv; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -spvc_result spvc_compiler_msl_set_fragment_output_components(spvc_compiler compiler, unsigned location, - unsigned components) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - auto &msl = *static_cast(compiler->compiler.get()); - msl.set_fragment_output_components(location, components); - return SPVC_SUCCESS; -#else - (void)location; - (void)components; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return SPVC_ERROR_INVALID_ARGUMENT; -#endif -} - -unsigned spvc_compiler_msl_get_automatic_resource_binding(spvc_compiler compiler, spvc_variable_id id) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return uint32_t(-1); - } - - auto &msl = *static_cast(compiler->compiler.get()); - return msl.get_automatic_msl_resource_binding(id); -#else - (void)id; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return uint32_t(-1); -#endif -} - -unsigned spvc_compiler_msl_get_automatic_resource_binding_secondary(spvc_compiler compiler, spvc_variable_id id) -{ -#if SPIRV_CROSS_C_API_MSL - if (compiler->backend != SPVC_BACKEND_MSL) - { - compiler->context->report_error("MSL function used on a non-MSL backend."); - return uint32_t(-1); - } - - auto &msl = *static_cast(compiler->compiler.get()); - return msl.get_automatic_msl_resource_binding_secondary(id); -#else - (void)id; - compiler->context->report_error("MSL function used on a non-MSL backend."); - return uint32_t(-1); -#endif -} - -spvc_result spvc_compiler_compile(spvc_compiler compiler, const char **source) -{ - SPVC_BEGIN_SAFE_SCOPE - { - auto result = compiler->compiler->compile(); - if (result.empty()) - { - compiler->context->report_error("Unsupported SPIR-V."); - return SPVC_ERROR_UNSUPPORTED_SPIRV; - } - - *source = compiler->context->allocate_name(result); - if (!*source) - { - compiler->context->report_error("Out of memory."); - return SPVC_ERROR_OUT_OF_MEMORY; - } - return SPVC_SUCCESS; - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_UNSUPPORTED_SPIRV) -} - -bool spvc_resources_s::copy_resources(SmallVector &outputs, - const SmallVector &inputs) -{ - for (auto &i : inputs) - { - spvc_reflected_resource r; - r.base_type_id = i.base_type_id; - r.type_id = i.type_id; - r.id = i.id; - r.name = context->allocate_name(i.name); - if (!r.name) - return false; - - outputs.push_back(r); - } - - return true; -} - -bool spvc_resources_s::copy_resources(SmallVector &outputs, - const SmallVector &inputs) -{ - for (auto &i : inputs) - { - spvc_reflected_builtin_resource br; - - br.value_type_id = i.value_type_id; - br.builtin = SpvBuiltIn(i.builtin); - - auto &r = br.resource; - r.base_type_id = i.resource.base_type_id; - r.type_id = i.resource.type_id; - r.id = i.resource.id; - r.name = context->allocate_name(i.resource.name); - if (!r.name) - return false; - - outputs.push_back(br); - } - - return true; -} - -bool spvc_resources_s::copy_resources(const ShaderResources &resources) -{ - if (!copy_resources(uniform_buffers, resources.uniform_buffers)) - return false; - if (!copy_resources(storage_buffers, resources.storage_buffers)) - return false; - if (!copy_resources(stage_inputs, resources.stage_inputs)) - return false; - if (!copy_resources(stage_outputs, resources.stage_outputs)) - return false; - if (!copy_resources(subpass_inputs, resources.subpass_inputs)) - return false; - if (!copy_resources(storage_images, resources.storage_images)) - return false; - if (!copy_resources(sampled_images, resources.sampled_images)) - return false; - if (!copy_resources(atomic_counters, resources.atomic_counters)) - return false; - if (!copy_resources(push_constant_buffers, resources.push_constant_buffers)) - return false; - if (!copy_resources(shader_record_buffers, resources.shader_record_buffers)) - return false; - if (!copy_resources(separate_images, resources.separate_images)) - return false; - if (!copy_resources(separate_samplers, resources.separate_samplers)) - return false; - if (!copy_resources(acceleration_structures, resources.acceleration_structures)) - return false; - if (!copy_resources(builtin_inputs, resources.builtin_inputs)) - return false; - if (!copy_resources(builtin_outputs, resources.builtin_outputs)) - return false; - - return true; -} - -spvc_result spvc_compiler_get_active_interface_variables(spvc_compiler compiler, spvc_set *set) -{ - SPVC_BEGIN_SAFE_SCOPE - { - std::unique_ptr ptr(new (std::nothrow) spvc_set_s); - if (!ptr) - { - compiler->context->report_error("Out of memory."); - return SPVC_ERROR_OUT_OF_MEMORY; - } - - auto active = compiler->compiler->get_active_interface_variables(); - ptr->set = std::move(active); - *set = ptr.get(); - compiler->context->allocations.push_back(std::move(ptr)); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_set_enabled_interface_variables(spvc_compiler compiler, spvc_set set) -{ - SPVC_BEGIN_SAFE_SCOPE - { - compiler->compiler->set_enabled_interface_variables(set->set); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_create_shader_resources_for_active_variables(spvc_compiler compiler, spvc_resources *resources, - spvc_set set) -{ - SPVC_BEGIN_SAFE_SCOPE - { - std::unique_ptr res(new (std::nothrow) spvc_resources_s); - if (!res) - { - compiler->context->report_error("Out of memory."); - return SPVC_ERROR_OUT_OF_MEMORY; - } - - res->context = compiler->context; - auto accessed_resources = compiler->compiler->get_shader_resources(set->set); - - if (!res->copy_resources(accessed_resources)) - { - res->context->report_error("Out of memory."); - return SPVC_ERROR_OUT_OF_MEMORY; - } - *resources = res.get(); - compiler->context->allocations.push_back(std::move(res)); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_create_shader_resources(spvc_compiler compiler, spvc_resources *resources) -{ - SPVC_BEGIN_SAFE_SCOPE - { - std::unique_ptr res(new (std::nothrow) spvc_resources_s); - if (!res) - { - compiler->context->report_error("Out of memory."); - return SPVC_ERROR_OUT_OF_MEMORY; - } - - res->context = compiler->context; - auto accessed_resources = compiler->compiler->get_shader_resources(); - - if (!res->copy_resources(accessed_resources)) - { - res->context->report_error("Out of memory."); - return SPVC_ERROR_OUT_OF_MEMORY; - } - - *resources = res.get(); - compiler->context->allocations.push_back(std::move(res)); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY) - return SPVC_SUCCESS; -} - -spvc_result spvc_resources_get_resource_list_for_type(spvc_resources resources, spvc_resource_type type, - const spvc_reflected_resource **resource_list, - size_t *resource_size) -{ - const SmallVector *list = nullptr; - switch (type) - { - case SPVC_RESOURCE_TYPE_UNIFORM_BUFFER: - list = &resources->uniform_buffers; - break; - - case SPVC_RESOURCE_TYPE_STORAGE_BUFFER: - list = &resources->storage_buffers; - break; - - case SPVC_RESOURCE_TYPE_STAGE_INPUT: - list = &resources->stage_inputs; - break; - - case SPVC_RESOURCE_TYPE_STAGE_OUTPUT: - list = &resources->stage_outputs; - break; - - case SPVC_RESOURCE_TYPE_SUBPASS_INPUT: - list = &resources->subpass_inputs; - break; - - case SPVC_RESOURCE_TYPE_STORAGE_IMAGE: - list = &resources->storage_images; - break; - - case SPVC_RESOURCE_TYPE_SAMPLED_IMAGE: - list = &resources->sampled_images; - break; - - case SPVC_RESOURCE_TYPE_ATOMIC_COUNTER: - list = &resources->atomic_counters; - break; - - case SPVC_RESOURCE_TYPE_PUSH_CONSTANT: - list = &resources->push_constant_buffers; - break; - - case SPVC_RESOURCE_TYPE_SEPARATE_IMAGE: - list = &resources->separate_images; - break; - - case SPVC_RESOURCE_TYPE_SEPARATE_SAMPLERS: - list = &resources->separate_samplers; - break; - - case SPVC_RESOURCE_TYPE_ACCELERATION_STRUCTURE: - list = &resources->acceleration_structures; - break; - - case SPVC_RESOURCE_TYPE_SHADER_RECORD_BUFFER: - list = &resources->shader_record_buffers; - break; - - default: - break; - } - - if (!list) - { - resources->context->report_error("Invalid argument."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - *resource_size = list->size(); - *resource_list = list->data(); - return SPVC_SUCCESS; -} - -spvc_result spvc_resources_get_builtin_resource_list_for_type( - spvc_resources resources, spvc_builtin_resource_type type, - const spvc_reflected_builtin_resource **resource_list, - size_t *resource_size) -{ - const SmallVector *list = nullptr; - switch (type) - { - case SPVC_BUILTIN_RESOURCE_TYPE_STAGE_INPUT: - list = &resources->builtin_inputs; - break; - - case SPVC_BUILTIN_RESOURCE_TYPE_STAGE_OUTPUT: - list = &resources->builtin_outputs; - break; - - default: - break; - } - - if (!list) - { - resources->context->report_error("Invalid argument."); - return SPVC_ERROR_INVALID_ARGUMENT; - } - - *resource_size = list->size(); - *resource_list = list->data(); - return SPVC_SUCCESS; -} - -void spvc_compiler_set_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration, unsigned argument) -{ - compiler->compiler->set_decoration(id, static_cast(decoration), argument); -} - -void spvc_compiler_set_decoration_string(spvc_compiler compiler, SpvId id, SpvDecoration decoration, - const char *argument) -{ - compiler->compiler->set_decoration_string(id, static_cast(decoration), argument); -} - -void spvc_compiler_set_name(spvc_compiler compiler, SpvId id, const char *argument) -{ - compiler->compiler->set_name(id, argument); -} - -void spvc_compiler_set_member_decoration(spvc_compiler compiler, spvc_type_id id, unsigned member_index, - SpvDecoration decoration, unsigned argument) -{ - compiler->compiler->set_member_decoration(id, member_index, static_cast(decoration), argument); -} - -void spvc_compiler_set_member_decoration_string(spvc_compiler compiler, spvc_type_id id, unsigned member_index, - SpvDecoration decoration, const char *argument) -{ - compiler->compiler->set_member_decoration_string(id, member_index, static_cast(decoration), - argument); -} - -void spvc_compiler_set_member_name(spvc_compiler compiler, spvc_type_id id, unsigned member_index, const char *argument) -{ - compiler->compiler->set_member_name(id, member_index, argument); -} - -void spvc_compiler_unset_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration) -{ - compiler->compiler->unset_decoration(id, static_cast(decoration)); -} - -void spvc_compiler_unset_member_decoration(spvc_compiler compiler, spvc_type_id id, unsigned member_index, - SpvDecoration decoration) -{ - compiler->compiler->unset_member_decoration(id, member_index, static_cast(decoration)); -} - -spvc_bool spvc_compiler_has_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration) -{ - return compiler->compiler->has_decoration(id, static_cast(decoration)) ? SPVC_TRUE : SPVC_FALSE; -} - -spvc_bool spvc_compiler_has_member_decoration(spvc_compiler compiler, spvc_type_id id, unsigned member_index, - SpvDecoration decoration) -{ - return compiler->compiler->has_member_decoration(id, member_index, static_cast(decoration)) ? - SPVC_TRUE : - SPVC_FALSE; -} - -const char *spvc_compiler_get_name(spvc_compiler compiler, SpvId id) -{ - return compiler->compiler->get_name(id).c_str(); -} - -unsigned spvc_compiler_get_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration) -{ - return compiler->compiler->get_decoration(id, static_cast(decoration)); -} - -const char *spvc_compiler_get_decoration_string(spvc_compiler compiler, SpvId id, SpvDecoration decoration) -{ - return compiler->compiler->get_decoration_string(id, static_cast(decoration)).c_str(); -} - -unsigned spvc_compiler_get_member_decoration(spvc_compiler compiler, spvc_type_id id, unsigned member_index, - SpvDecoration decoration) -{ - return compiler->compiler->get_member_decoration(id, member_index, static_cast(decoration)); -} - -const char *spvc_compiler_get_member_decoration_string(spvc_compiler compiler, spvc_type_id id, unsigned member_index, - SpvDecoration decoration) -{ - return compiler->compiler->get_member_decoration_string(id, member_index, static_cast(decoration)) - .c_str(); -} - -const char *spvc_compiler_get_member_name(spvc_compiler compiler, spvc_type_id id, unsigned member_index) -{ - return compiler->compiler->get_member_name(id, member_index).c_str(); -} - -spvc_result spvc_compiler_get_entry_points(spvc_compiler compiler, const spvc_entry_point **entry_points, - size_t *num_entry_points) -{ - SPVC_BEGIN_SAFE_SCOPE - { - auto entries = compiler->compiler->get_entry_points_and_stages(); - SmallVector translated; - translated.reserve(entries.size()); - - for (auto &entry : entries) - { - spvc_entry_point new_entry; - new_entry.execution_model = static_cast(entry.execution_model); - new_entry.name = compiler->context->allocate_name(entry.name); - if (!new_entry.name) - { - compiler->context->report_error("Out of memory."); - return SPVC_ERROR_OUT_OF_MEMORY; - } - translated.push_back(new_entry); - } - - auto ptr = spvc_allocate>(); - ptr->buffer = std::move(translated); - *entry_points = ptr->buffer.data(); - *num_entry_points = ptr->buffer.size(); - compiler->context->allocations.push_back(std::move(ptr)); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_set_entry_point(spvc_compiler compiler, const char *name, SpvExecutionModel model) -{ - compiler->compiler->set_entry_point(name, static_cast(model)); - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_rename_entry_point(spvc_compiler compiler, const char *old_name, const char *new_name, - SpvExecutionModel model) -{ - SPVC_BEGIN_SAFE_SCOPE - { - compiler->compiler->rename_entry_point(old_name, new_name, static_cast(model)); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT) - return SPVC_SUCCESS; -} - -const char *spvc_compiler_get_cleansed_entry_point_name(spvc_compiler compiler, const char *name, - SpvExecutionModel model) -{ - SPVC_BEGIN_SAFE_SCOPE - { - auto cleansed_name = - compiler->compiler->get_cleansed_entry_point_name(name, static_cast(model)); - return compiler->context->allocate_name(cleansed_name); - } - SPVC_END_SAFE_SCOPE(compiler->context, nullptr) -} - -void spvc_compiler_set_execution_mode(spvc_compiler compiler, SpvExecutionMode mode) -{ - compiler->compiler->set_execution_mode(static_cast(mode)); -} - -void spvc_compiler_set_execution_mode_with_arguments(spvc_compiler compiler, SpvExecutionMode mode, unsigned arg0, - unsigned arg1, - unsigned arg2) -{ - compiler->compiler->set_execution_mode(static_cast(mode), arg0, arg1, arg2); -} - -void spvc_compiler_unset_execution_mode(spvc_compiler compiler, SpvExecutionMode mode) -{ - compiler->compiler->unset_execution_mode(static_cast(mode)); -} - -spvc_result spvc_compiler_get_execution_modes(spvc_compiler compiler, const SpvExecutionMode **modes, size_t *num_modes) -{ - SPVC_BEGIN_SAFE_SCOPE - { - auto ptr = spvc_allocate>(); - - compiler->compiler->get_execution_mode_bitset().for_each_bit( - [&](uint32_t bit) { ptr->buffer.push_back(static_cast(bit)); }); - - *modes = ptr->buffer.data(); - *num_modes = ptr->buffer.size(); - compiler->context->allocations.push_back(std::move(ptr)); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY) - return SPVC_SUCCESS; -} - -unsigned spvc_compiler_get_execution_mode_argument(spvc_compiler compiler, SpvExecutionMode mode) -{ - return compiler->compiler->get_execution_mode_argument(static_cast(mode)); -} - -unsigned spvc_compiler_get_execution_mode_argument_by_index(spvc_compiler compiler, SpvExecutionMode mode, - unsigned index) -{ - return compiler->compiler->get_execution_mode_argument(static_cast(mode), index); -} - -SpvExecutionModel spvc_compiler_get_execution_model(spvc_compiler compiler) -{ - return static_cast(compiler->compiler->get_execution_model()); -} - -void spvc_compiler_update_active_builtins(spvc_compiler compiler) -{ - compiler->compiler->update_active_builtins(); -} - -spvc_bool spvc_compiler_has_active_builtin(spvc_compiler compiler, SpvBuiltIn builtin, SpvStorageClass storage) -{ - return compiler->compiler->has_active_builtin(static_cast(builtin), static_cast(storage)) ? - SPVC_TRUE : - SPVC_FALSE; -} - -spvc_type spvc_compiler_get_type_handle(spvc_compiler compiler, spvc_type_id id) -{ - // Should only throw if an intentionally garbage ID is passed, but the IDs are not type-safe. - SPVC_BEGIN_SAFE_SCOPE - { - return static_cast(&compiler->compiler->get_type(id)); - } - SPVC_END_SAFE_SCOPE(compiler->context, nullptr) -} - -spvc_type_id spvc_type_get_base_type_id(spvc_type type) -{ - return type->self; -} - -static spvc_basetype convert_basetype(SPIRType::BaseType type) -{ - // For now the enums match up. - return static_cast(type); -} - -spvc_basetype spvc_type_get_basetype(spvc_type type) -{ - return convert_basetype(type->basetype); -} - -unsigned spvc_type_get_bit_width(spvc_type type) -{ - return type->width; -} - -unsigned spvc_type_get_vector_size(spvc_type type) -{ - return type->vecsize; -} - -unsigned spvc_type_get_columns(spvc_type type) -{ - return type->columns; -} - -unsigned spvc_type_get_num_array_dimensions(spvc_type type) -{ - return unsigned(type->array.size()); -} - -spvc_bool spvc_type_array_dimension_is_literal(spvc_type type, unsigned dimension) -{ - return type->array_size_literal[dimension] ? SPVC_TRUE : SPVC_FALSE; -} - -SpvId spvc_type_get_array_dimension(spvc_type type, unsigned dimension) -{ - return type->array[dimension]; -} - -unsigned spvc_type_get_num_member_types(spvc_type type) -{ - return unsigned(type->member_types.size()); -} - -spvc_type_id spvc_type_get_member_type(spvc_type type, unsigned index) -{ - return type->member_types[index]; -} - -SpvStorageClass spvc_type_get_storage_class(spvc_type type) -{ - return static_cast(type->storage); -} - -// Image type query. -spvc_type_id spvc_type_get_image_sampled_type(spvc_type type) -{ - return type->image.type; -} - -SpvDim spvc_type_get_image_dimension(spvc_type type) -{ - return static_cast(type->image.dim); -} - -spvc_bool spvc_type_get_image_is_depth(spvc_type type) -{ - return type->image.depth ? SPVC_TRUE : SPVC_FALSE; -} - -spvc_bool spvc_type_get_image_arrayed(spvc_type type) -{ - return type->image.arrayed ? SPVC_TRUE : SPVC_FALSE; -} - -spvc_bool spvc_type_get_image_multisampled(spvc_type type) -{ - return type->image.ms ? SPVC_TRUE : SPVC_FALSE; -} - -spvc_bool spvc_type_get_image_is_storage(spvc_type type) -{ - return type->image.sampled == 2 ? SPVC_TRUE : SPVC_FALSE; -} - -SpvImageFormat spvc_type_get_image_storage_format(spvc_type type) -{ - return static_cast(static_cast(type)->image.format); -} - -SpvAccessQualifier spvc_type_get_image_access_qualifier(spvc_type type) -{ - return static_cast(static_cast(type)->image.access); -} - -spvc_result spvc_compiler_get_declared_struct_size(spvc_compiler compiler, spvc_type struct_type, size_t *size) -{ - SPVC_BEGIN_SAFE_SCOPE - { - *size = compiler->compiler->get_declared_struct_size(*static_cast(struct_type)); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_get_declared_struct_size_runtime_array(spvc_compiler compiler, spvc_type struct_type, - size_t array_size, size_t *size) -{ - SPVC_BEGIN_SAFE_SCOPE - { - *size = compiler->compiler->get_declared_struct_size_runtime_array(*static_cast(struct_type), - array_size); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_get_declared_struct_member_size(spvc_compiler compiler, spvc_type struct_type, unsigned index, size_t *size) -{ - SPVC_BEGIN_SAFE_SCOPE - { - *size = compiler->compiler->get_declared_struct_member_size(*static_cast(struct_type), index); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_type_struct_member_offset(spvc_compiler compiler, spvc_type type, unsigned index, unsigned *offset) -{ - SPVC_BEGIN_SAFE_SCOPE - { - *offset = compiler->compiler->type_struct_member_offset(*static_cast(type), index); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_type_struct_member_array_stride(spvc_compiler compiler, spvc_type type, unsigned index, unsigned *stride) -{ - SPVC_BEGIN_SAFE_SCOPE - { - *stride = compiler->compiler->type_struct_member_array_stride(*static_cast(type), index); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_type_struct_member_matrix_stride(spvc_compiler compiler, spvc_type type, unsigned index, unsigned *stride) -{ - SPVC_BEGIN_SAFE_SCOPE - { - *stride = compiler->compiler->type_struct_member_matrix_stride(*static_cast(type), index); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_build_dummy_sampler_for_combined_images(spvc_compiler compiler, spvc_variable_id *id) -{ - SPVC_BEGIN_SAFE_SCOPE - { - *id = compiler->compiler->build_dummy_sampler_for_combined_images(); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_build_combined_image_samplers(spvc_compiler compiler) -{ - SPVC_BEGIN_SAFE_SCOPE - { - compiler->compiler->build_combined_image_samplers(); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_UNSUPPORTED_SPIRV) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_get_combined_image_samplers(spvc_compiler compiler, - const spvc_combined_image_sampler **samplers, - size_t *num_samplers) -{ - SPVC_BEGIN_SAFE_SCOPE - { - auto combined = compiler->compiler->get_combined_image_samplers(); - SmallVector translated; - translated.reserve(combined.size()); - for (auto &c : combined) - { - spvc_combined_image_sampler trans = { c.combined_id, c.image_id, c.sampler_id }; - translated.push_back(trans); - } - - auto ptr = spvc_allocate>(); - ptr->buffer = std::move(translated); - *samplers = ptr->buffer.data(); - *num_samplers = ptr->buffer.size(); - compiler->context->allocations.push_back(std::move(ptr)); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY) - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_get_specialization_constants(spvc_compiler compiler, - const spvc_specialization_constant **constants, - size_t *num_constants) -{ - SPVC_BEGIN_SAFE_SCOPE - { - auto spec_constants = compiler->compiler->get_specialization_constants(); - SmallVector translated; - translated.reserve(spec_constants.size()); - for (auto &c : spec_constants) - { - spvc_specialization_constant trans = { c.id, c.constant_id }; - translated.push_back(trans); - } - - auto ptr = spvc_allocate>(); - ptr->buffer = std::move(translated); - *constants = ptr->buffer.data(); - *num_constants = ptr->buffer.size(); - compiler->context->allocations.push_back(std::move(ptr)); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY) - return SPVC_SUCCESS; -} - -spvc_constant spvc_compiler_get_constant_handle(spvc_compiler compiler, spvc_variable_id id) -{ - SPVC_BEGIN_SAFE_SCOPE - { - return static_cast(&compiler->compiler->get_constant(id)); - } - SPVC_END_SAFE_SCOPE(compiler->context, nullptr) -} - -spvc_constant_id spvc_compiler_get_work_group_size_specialization_constants(spvc_compiler compiler, - spvc_specialization_constant *x, - spvc_specialization_constant *y, - spvc_specialization_constant *z) -{ - SpecializationConstant tmpx; - SpecializationConstant tmpy; - SpecializationConstant tmpz; - spvc_constant_id ret = compiler->compiler->get_work_group_size_specialization_constants(tmpx, tmpy, tmpz); - x->id = tmpx.id; - x->constant_id = tmpx.constant_id; - y->id = tmpy.id; - y->constant_id = tmpy.constant_id; - z->id = tmpz.id; - z->constant_id = tmpz.constant_id; - return ret; -} - -spvc_result spvc_compiler_get_active_buffer_ranges(spvc_compiler compiler, - spvc_variable_id id, - const spvc_buffer_range **ranges, - size_t *num_ranges) -{ - SPVC_BEGIN_SAFE_SCOPE - { - auto active_ranges = compiler->compiler->get_active_buffer_ranges(id); - SmallVector translated; - translated.reserve(active_ranges.size()); - for (auto &r : active_ranges) - { - spvc_buffer_range trans = { r.index, r.offset, r.range }; - translated.push_back(trans); - } - - auto ptr = spvc_allocate>(); - ptr->buffer = std::move(translated); - *ranges = ptr->buffer.data(); - *num_ranges = ptr->buffer.size(); - compiler->context->allocations.push_back(std::move(ptr)); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY) - return SPVC_SUCCESS; -} - -float spvc_constant_get_scalar_fp16(spvc_constant constant, unsigned column, unsigned row) -{ - return constant->scalar_f16(column, row); -} - -float spvc_constant_get_scalar_fp32(spvc_constant constant, unsigned column, unsigned row) -{ - return constant->scalar_f32(column, row); -} - -double spvc_constant_get_scalar_fp64(spvc_constant constant, unsigned column, unsigned row) -{ - return constant->scalar_f64(column, row); -} - -unsigned spvc_constant_get_scalar_u32(spvc_constant constant, unsigned column, unsigned row) -{ - return constant->scalar(column, row); -} - -int spvc_constant_get_scalar_i32(spvc_constant constant, unsigned column, unsigned row) -{ - return constant->scalar_i32(column, row); -} - -unsigned spvc_constant_get_scalar_u16(spvc_constant constant, unsigned column, unsigned row) -{ - return constant->scalar_u16(column, row); -} - -int spvc_constant_get_scalar_i16(spvc_constant constant, unsigned column, unsigned row) -{ - return constant->scalar_i16(column, row); -} - -unsigned spvc_constant_get_scalar_u8(spvc_constant constant, unsigned column, unsigned row) -{ - return constant->scalar_u8(column, row); -} - -int spvc_constant_get_scalar_i8(spvc_constant constant, unsigned column, unsigned row) -{ - return constant->scalar_i8(column, row); -} - -void spvc_constant_get_subconstants(spvc_constant constant, const spvc_constant_id **constituents, size_t *count) -{ - static_assert(sizeof(spvc_constant_id) == sizeof(constant->subconstants.front()), "ID size is not consistent."); - *constituents = reinterpret_cast(constant->subconstants.data()); - *count = constant->subconstants.size(); -} - -spvc_type_id spvc_constant_get_type(spvc_constant constant) -{ - return constant->constant_type; -} - -void spvc_constant_set_scalar_fp16(spvc_constant constant, unsigned column, unsigned row, unsigned short value) -{ - constant->m.c[column].r[row].u32 = value; -} - -void spvc_constant_set_scalar_fp32(spvc_constant constant, unsigned column, unsigned row, float value) -{ - constant->m.c[column].r[row].f32 = value; -} - -void spvc_constant_set_scalar_fp64(spvc_constant constant, unsigned column, unsigned row, double value) -{ - constant->m.c[column].r[row].f64 = value; -} - -void spvc_constant_set_scalar_u32(spvc_constant constant, unsigned column, unsigned row, unsigned value) -{ - constant->m.c[column].r[row].u32 = value; -} - -void spvc_constant_set_scalar_i32(spvc_constant constant, unsigned column, unsigned row, int value) -{ - constant->m.c[column].r[row].i32 = value; -} - -void spvc_constant_set_scalar_u16(spvc_constant constant, unsigned column, unsigned row, unsigned short value) -{ - constant->m.c[column].r[row].u32 = uint32_t(value); -} - -void spvc_constant_set_scalar_i16(spvc_constant constant, unsigned column, unsigned row, signed short value) -{ - constant->m.c[column].r[row].u32 = uint32_t(value); -} - -void spvc_constant_set_scalar_u8(spvc_constant constant, unsigned column, unsigned row, unsigned char value) -{ - constant->m.c[column].r[row].u32 = uint32_t(value); -} - -void spvc_constant_set_scalar_i8(spvc_constant constant, unsigned column, unsigned row, signed char value) -{ - constant->m.c[column].r[row].u32 = uint32_t(value); -} - -spvc_bool spvc_compiler_get_binary_offset_for_decoration(spvc_compiler compiler, spvc_variable_id id, - SpvDecoration decoration, - unsigned *word_offset) -{ - uint32_t off = 0; - bool ret = compiler->compiler->get_binary_offset_for_decoration(id, static_cast(decoration), off); - if (ret) - { - *word_offset = off; - return SPVC_TRUE; - } - else - return SPVC_FALSE; -} - -spvc_bool spvc_compiler_buffer_is_hlsl_counter_buffer(spvc_compiler compiler, spvc_variable_id id) -{ - return compiler->compiler->buffer_is_hlsl_counter_buffer(id) ? SPVC_TRUE : SPVC_FALSE; -} - -spvc_bool spvc_compiler_buffer_get_hlsl_counter_buffer(spvc_compiler compiler, spvc_variable_id id, - spvc_variable_id *counter_id) -{ - uint32_t buffer; - bool ret = compiler->compiler->buffer_get_hlsl_counter_buffer(id, buffer); - if (ret) - { - *counter_id = buffer; - return SPVC_TRUE; - } - else - return SPVC_FALSE; -} - -spvc_result spvc_compiler_get_declared_capabilities(spvc_compiler compiler, const SpvCapability **capabilities, - size_t *num_capabilities) -{ - auto &caps = compiler->compiler->get_declared_capabilities(); - static_assert(sizeof(SpvCapability) == sizeof(spv::Capability), "Enum size mismatch."); - *capabilities = reinterpret_cast(caps.data()); - *num_capabilities = caps.size(); - return SPVC_SUCCESS; -} - -spvc_result spvc_compiler_get_declared_extensions(spvc_compiler compiler, const char ***extensions, - size_t *num_extensions) -{ - SPVC_BEGIN_SAFE_SCOPE - { - auto &exts = compiler->compiler->get_declared_extensions(); - SmallVector duped; - duped.reserve(exts.size()); - for (auto &ext : exts) - duped.push_back(compiler->context->allocate_name(ext)); - - auto ptr = spvc_allocate>(); - ptr->buffer = std::move(duped); - *extensions = ptr->buffer.data(); - *num_extensions = ptr->buffer.size(); - compiler->context->allocations.push_back(std::move(ptr)); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_OUT_OF_MEMORY) - return SPVC_SUCCESS; -} - -const char *spvc_compiler_get_remapped_declared_block_name(spvc_compiler compiler, spvc_variable_id id) -{ - SPVC_BEGIN_SAFE_SCOPE - { - auto name = compiler->compiler->get_remapped_declared_block_name(id); - return compiler->context->allocate_name(name); - } - SPVC_END_SAFE_SCOPE(compiler->context, nullptr) -} - -spvc_result spvc_compiler_get_buffer_block_decorations(spvc_compiler compiler, spvc_variable_id id, - const SpvDecoration **decorations, size_t *num_decorations) -{ - SPVC_BEGIN_SAFE_SCOPE - { - auto flags = compiler->compiler->get_buffer_block_flags(id); - auto bitset = spvc_allocate>(); - - flags.for_each_bit([&](uint32_t bit) { bitset->buffer.push_back(static_cast(bit)); }); - - *decorations = bitset->buffer.data(); - *num_decorations = bitset->buffer.size(); - compiler->context->allocations.push_back(std::move(bitset)); - } - SPVC_END_SAFE_SCOPE(compiler->context, SPVC_ERROR_INVALID_ARGUMENT) - return SPVC_SUCCESS; -} - -unsigned spvc_msl_get_aux_buffer_struct_version(void) -{ - return SPVC_MSL_AUX_BUFFER_STRUCT_VERSION; -} - -void spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute *attr) -{ -#if SPIRV_CROSS_C_API_MSL - // Crude, but works. - MSLShaderInterfaceVariable attr_default; - attr->location = attr_default.location; - attr->format = static_cast(attr_default.format); - attr->builtin = static_cast(attr_default.builtin); -#else - memset(attr, 0, sizeof(*attr)); -#endif -} - -void spvc_msl_shader_interface_var_init(spvc_msl_shader_interface_var *var) -{ -#if SPIRV_CROSS_C_API_MSL - MSLShaderInterfaceVariable var_default; - var->location = var_default.location; - var->format = static_cast(var_default.format); - var->builtin = static_cast(var_default.builtin); - var->vecsize = var_default.vecsize; -#else - memset(var, 0, sizeof(*var)); -#endif -} - -void spvc_msl_shader_input_init(spvc_msl_shader_input *input) -{ - spvc_msl_shader_interface_var_init(input); -} - -void spvc_msl_shader_interface_var_init_2(spvc_msl_shader_interface_var_2 *var) -{ -#if SPIRV_CROSS_C_API_MSL - MSLShaderInterfaceVariable var_default; - var->location = var_default.location; - var->format = static_cast(var_default.format); - var->builtin = static_cast(var_default.builtin); - var->vecsize = var_default.vecsize; - var->rate = static_cast(var_default.rate); -#else - memset(var, 0, sizeof(*var)); -#endif -} - -void spvc_msl_resource_binding_init(spvc_msl_resource_binding *binding) -{ -#if SPIRV_CROSS_C_API_MSL - MSLResourceBinding binding_default; - binding->desc_set = binding_default.desc_set; - binding->binding = binding_default.binding; - binding->msl_buffer = binding_default.msl_buffer; - binding->msl_texture = binding_default.msl_texture; - binding->msl_sampler = binding_default.msl_sampler; - binding->stage = static_cast(binding_default.stage); -#else - memset(binding, 0, sizeof(*binding)); -#endif -} - -void spvc_hlsl_resource_binding_init(spvc_hlsl_resource_binding *binding) -{ -#if SPIRV_CROSS_C_API_HLSL - HLSLResourceBinding binding_default; - binding->desc_set = binding_default.desc_set; - binding->binding = binding_default.binding; - binding->cbv.register_binding = binding_default.cbv.register_binding; - binding->cbv.register_space = binding_default.cbv.register_space; - binding->srv.register_binding = binding_default.srv.register_binding; - binding->srv.register_space = binding_default.srv.register_space; - binding->uav.register_binding = binding_default.uav.register_binding; - binding->uav.register_space = binding_default.uav.register_space; - binding->sampler.register_binding = binding_default.sampler.register_binding; - binding->sampler.register_space = binding_default.sampler.register_space; - binding->stage = static_cast(binding_default.stage); -#else - memset(binding, 0, sizeof(*binding)); -#endif -} - -void spvc_msl_constexpr_sampler_init(spvc_msl_constexpr_sampler *sampler) -{ -#if SPIRV_CROSS_C_API_MSL - MSLConstexprSampler defaults; - sampler->anisotropy_enable = defaults.anisotropy_enable ? SPVC_TRUE : SPVC_FALSE; - sampler->border_color = static_cast(defaults.border_color); - sampler->compare_enable = defaults.compare_enable ? SPVC_TRUE : SPVC_FALSE; - sampler->coord = static_cast(defaults.coord); - sampler->compare_func = static_cast(defaults.compare_func); - sampler->lod_clamp_enable = defaults.lod_clamp_enable ? SPVC_TRUE : SPVC_FALSE; - sampler->lod_clamp_max = defaults.lod_clamp_max; - sampler->lod_clamp_min = defaults.lod_clamp_min; - sampler->mag_filter = static_cast(defaults.mag_filter); - sampler->min_filter = static_cast(defaults.min_filter); - sampler->mip_filter = static_cast(defaults.mip_filter); - sampler->max_anisotropy = defaults.max_anisotropy; - sampler->s_address = static_cast(defaults.s_address); - sampler->t_address = static_cast(defaults.t_address); - sampler->r_address = static_cast(defaults.r_address); -#else - memset(sampler, 0, sizeof(*sampler)); -#endif -} - -void spvc_msl_sampler_ycbcr_conversion_init(spvc_msl_sampler_ycbcr_conversion *conv) -{ -#if SPIRV_CROSS_C_API_MSL - MSLConstexprSampler defaults; - conv->planes = defaults.planes; - conv->resolution = static_cast(defaults.resolution); - conv->chroma_filter = static_cast(defaults.chroma_filter); - conv->x_chroma_offset = static_cast(defaults.x_chroma_offset); - conv->y_chroma_offset = static_cast(defaults.y_chroma_offset); - for (int i = 0; i < 4; i++) - conv->swizzle[i] = static_cast(defaults.swizzle[i]); - conv->ycbcr_model = static_cast(defaults.ycbcr_model); - conv->ycbcr_range = static_cast(defaults.ycbcr_range); -#else - memset(conv, 0, sizeof(*conv)); -#endif -} - -unsigned spvc_compiler_get_current_id_bound(spvc_compiler compiler) -{ - return compiler->compiler->get_current_id_bound(); -} - -void spvc_get_version(unsigned *major, unsigned *minor, unsigned *patch) -{ - *major = SPVC_C_API_VERSION_MAJOR; - *minor = SPVC_C_API_VERSION_MINOR; - *patch = SPVC_C_API_VERSION_PATCH; -} - -const char *spvc_get_commit_revision_and_timestamp(void) -{ -#ifdef HAVE_SPIRV_CROSS_GIT_VERSION - return SPIRV_CROSS_GIT_REVISION; -#else - return ""; -#endif -} - -#ifdef _MSC_VER -#pragma warning(pop) -#endif diff --git a/src/libraries/spirv_cross/spirv_cross_c.h b/src/libraries/spirv_cross/spirv_cross_c.h deleted file mode 100644 index dd9884f5d..000000000 --- a/src/libraries/spirv_cross/spirv_cross_c.h +++ /dev/null @@ -1,1097 +0,0 @@ -/* - * Copyright 2019-2021 Hans-Kristian Arntzen - * SPDX-License-Identifier: Apache-2.0 OR MIT - * - * 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. - */ - -/* - * At your option, you may choose to accept this material under either: - * 1. The Apache License, Version 2.0, found at , or - * 2. The MIT License, found at . - */ - -#ifndef SPIRV_CROSS_C_API_H -#define SPIRV_CROSS_C_API_H - -#include -#include "spirv.h" - -/* - * C89-compatible wrapper for SPIRV-Cross' API. - * Documentation here is sparse unless the behavior does not map 1:1 with C++ API. - * It is recommended to look at the canonical C++ API for more detailed information. - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Bumped if ABI or API breaks backwards compatibility. */ -#define SPVC_C_API_VERSION_MAJOR 0 -/* Bumped if APIs or enumerations are added in a backwards compatible way. */ -#define SPVC_C_API_VERSION_MINOR 58 -/* Bumped if internal implementation details change. */ -#define SPVC_C_API_VERSION_PATCH 0 - -#if !defined(SPVC_PUBLIC_API) -#if defined(SPVC_EXPORT_SYMBOLS) -/* Exports symbols. Standard C calling convention is used. */ -#if defined(__GNUC__) -#define SPVC_PUBLIC_API __attribute__((visibility("default"))) -#elif defined(_MSC_VER) -#define SPVC_PUBLIC_API __declspec(dllexport) -#else -#define SPVC_PUBLIC_API -#endif -#else -#define SPVC_PUBLIC_API -#endif -#endif - -/* - * Gets the SPVC_C_API_VERSION_* used to build this library. - * Can be used to check for ABI mismatch if so-versioning did not catch it. - */ -SPVC_PUBLIC_API void spvc_get_version(unsigned *major, unsigned *minor, unsigned *patch); - -/* Gets a human readable version string to identify which commit a particular binary was created from. */ -SPVC_PUBLIC_API const char *spvc_get_commit_revision_and_timestamp(void); - -/* These types are opaque to the user. */ -typedef struct spvc_context_s *spvc_context; -typedef struct spvc_parsed_ir_s *spvc_parsed_ir; -typedef struct spvc_compiler_s *spvc_compiler; -typedef struct spvc_compiler_options_s *spvc_compiler_options; -typedef struct spvc_resources_s *spvc_resources; -struct spvc_type_s; -typedef const struct spvc_type_s *spvc_type; -typedef struct spvc_constant_s *spvc_constant; -struct spvc_set_s; -typedef const struct spvc_set_s *spvc_set; - -/* - * Shallow typedefs. All SPIR-V IDs are plain 32-bit numbers, but this helps communicate which data is used. - * Maps to a SPIRType. - */ -typedef SpvId spvc_type_id; -/* Maps to a SPIRVariable. */ -typedef SpvId spvc_variable_id; -/* Maps to a SPIRConstant. */ -typedef SpvId spvc_constant_id; - -/* See C++ API. */ -typedef struct spvc_reflected_resource -{ - spvc_variable_id id; - spvc_type_id base_type_id; - spvc_type_id type_id; - const char *name; -} spvc_reflected_resource; - -typedef struct spvc_reflected_builtin_resource -{ - SpvBuiltIn builtin; - spvc_type_id value_type_id; - spvc_reflected_resource resource; -} spvc_reflected_builtin_resource; - -/* See C++ API. */ -typedef struct spvc_entry_point -{ - SpvExecutionModel execution_model; - const char *name; -} spvc_entry_point; - -/* See C++ API. */ -typedef struct spvc_combined_image_sampler -{ - spvc_variable_id combined_id; - spvc_variable_id image_id; - spvc_variable_id sampler_id; -} spvc_combined_image_sampler; - -/* See C++ API. */ -typedef struct spvc_specialization_constant -{ - spvc_constant_id id; - unsigned constant_id; -} spvc_specialization_constant; - -/* See C++ API. */ -typedef struct spvc_buffer_range -{ - unsigned index; - size_t offset; - size_t range; -} spvc_buffer_range; - -/* See C++ API. */ -typedef struct spvc_hlsl_root_constants -{ - unsigned start; - unsigned end; - unsigned binding; - unsigned space; -} spvc_hlsl_root_constants; - -/* See C++ API. */ -typedef struct spvc_hlsl_vertex_attribute_remap -{ - unsigned location; - const char *semantic; -} spvc_hlsl_vertex_attribute_remap; - -/* - * Be compatible with non-C99 compilers, which do not have stdbool. - * Only recent MSVC compilers supports this for example, and ideally SPIRV-Cross should be linkable - * from a wide range of compilers in its C wrapper. - */ -typedef unsigned char spvc_bool; -#define SPVC_TRUE ((spvc_bool)1) -#define SPVC_FALSE ((spvc_bool)0) - -typedef enum spvc_result -{ - /* Success. */ - SPVC_SUCCESS = 0, - - /* The SPIR-V is invalid. Should have been caught by validation ideally. */ - SPVC_ERROR_INVALID_SPIRV = -1, - - /* The SPIR-V might be valid or invalid, but SPIRV-Cross currently cannot correctly translate this to your target language. */ - SPVC_ERROR_UNSUPPORTED_SPIRV = -2, - - /* If for some reason we hit this, new or malloc failed. */ - SPVC_ERROR_OUT_OF_MEMORY = -3, - - /* Invalid API argument. */ - SPVC_ERROR_INVALID_ARGUMENT = -4, - - SPVC_ERROR_INT_MAX = 0x7fffffff -} spvc_result; - -typedef enum spvc_capture_mode -{ - /* The Parsed IR payload will be copied, and the handle can be reused to create other compiler instances. */ - SPVC_CAPTURE_MODE_COPY = 0, - - /* - * The payload will now be owned by the compiler. - * parsed_ir should now be considered a dead blob and must not be used further. - * This is optimal for performance and should be the go-to option. - */ - SPVC_CAPTURE_MODE_TAKE_OWNERSHIP = 1, - - SPVC_CAPTURE_MODE_INT_MAX = 0x7fffffff -} spvc_capture_mode; - -typedef enum spvc_backend -{ - /* This backend can only perform reflection, no compiler options are supported. Maps to spirv_cross::Compiler. */ - SPVC_BACKEND_NONE = 0, - SPVC_BACKEND_GLSL = 1, /* spirv_cross::CompilerGLSL */ - SPVC_BACKEND_HLSL = 2, /* CompilerHLSL */ - SPVC_BACKEND_MSL = 3, /* CompilerMSL */ - SPVC_BACKEND_CPP = 4, /* CompilerCPP */ - SPVC_BACKEND_JSON = 5, /* CompilerReflection w/ JSON backend */ - SPVC_BACKEND_INT_MAX = 0x7fffffff -} spvc_backend; - -/* Maps to C++ API. */ -typedef enum spvc_resource_type -{ - SPVC_RESOURCE_TYPE_UNKNOWN = 0, - SPVC_RESOURCE_TYPE_UNIFORM_BUFFER = 1, - SPVC_RESOURCE_TYPE_STORAGE_BUFFER = 2, - SPVC_RESOURCE_TYPE_STAGE_INPUT = 3, - SPVC_RESOURCE_TYPE_STAGE_OUTPUT = 4, - SPVC_RESOURCE_TYPE_SUBPASS_INPUT = 5, - SPVC_RESOURCE_TYPE_STORAGE_IMAGE = 6, - SPVC_RESOURCE_TYPE_SAMPLED_IMAGE = 7, - SPVC_RESOURCE_TYPE_ATOMIC_COUNTER = 8, - SPVC_RESOURCE_TYPE_PUSH_CONSTANT = 9, - SPVC_RESOURCE_TYPE_SEPARATE_IMAGE = 10, - SPVC_RESOURCE_TYPE_SEPARATE_SAMPLERS = 11, - SPVC_RESOURCE_TYPE_ACCELERATION_STRUCTURE = 12, - SPVC_RESOURCE_TYPE_RAY_QUERY = 13, - SPVC_RESOURCE_TYPE_SHADER_RECORD_BUFFER = 14, - SPVC_RESOURCE_TYPE_INT_MAX = 0x7fffffff -} spvc_resource_type; - -typedef enum spvc_builtin_resource_type -{ - SPVC_BUILTIN_RESOURCE_TYPE_UNKNOWN = 0, - SPVC_BUILTIN_RESOURCE_TYPE_STAGE_INPUT = 1, - SPVC_BUILTIN_RESOURCE_TYPE_STAGE_OUTPUT = 2, - SPVC_BUILTIN_RESOURCE_TYPE_INT_MAX = 0x7fffffff -} spvc_builtin_resource_type; - -/* Maps to spirv_cross::SPIRType::BaseType. */ -typedef enum spvc_basetype -{ - SPVC_BASETYPE_UNKNOWN = 0, - SPVC_BASETYPE_VOID = 1, - SPVC_BASETYPE_BOOLEAN = 2, - SPVC_BASETYPE_INT8 = 3, - SPVC_BASETYPE_UINT8 = 4, - SPVC_BASETYPE_INT16 = 5, - SPVC_BASETYPE_UINT16 = 6, - SPVC_BASETYPE_INT32 = 7, - SPVC_BASETYPE_UINT32 = 8, - SPVC_BASETYPE_INT64 = 9, - SPVC_BASETYPE_UINT64 = 10, - SPVC_BASETYPE_ATOMIC_COUNTER = 11, - SPVC_BASETYPE_FP16 = 12, - SPVC_BASETYPE_FP32 = 13, - SPVC_BASETYPE_FP64 = 14, - SPVC_BASETYPE_STRUCT = 15, - SPVC_BASETYPE_IMAGE = 16, - SPVC_BASETYPE_SAMPLED_IMAGE = 17, - SPVC_BASETYPE_SAMPLER = 18, - SPVC_BASETYPE_ACCELERATION_STRUCTURE = 19, - - SPVC_BASETYPE_INT_MAX = 0x7fffffff -} spvc_basetype; - -#define SPVC_COMPILER_OPTION_COMMON_BIT 0x1000000 -#define SPVC_COMPILER_OPTION_GLSL_BIT 0x2000000 -#define SPVC_COMPILER_OPTION_HLSL_BIT 0x4000000 -#define SPVC_COMPILER_OPTION_MSL_BIT 0x8000000 -#define SPVC_COMPILER_OPTION_LANG_BITS 0x0f000000 -#define SPVC_COMPILER_OPTION_ENUM_BITS 0xffffff - -#define SPVC_MAKE_MSL_VERSION(major, minor, patch) ((major) * 10000 + (minor) * 100 + (patch)) - -/* Maps to C++ API. */ -typedef enum spvc_msl_platform -{ - SPVC_MSL_PLATFORM_IOS = 0, - SPVC_MSL_PLATFORM_MACOS = 1, - SPVC_MSL_PLATFORM_MAX_INT = 0x7fffffff -} spvc_msl_platform; - -/* Maps to C++ API. */ -typedef enum spvc_msl_index_type -{ - SPVC_MSL_INDEX_TYPE_NONE = 0, - SPVC_MSL_INDEX_TYPE_UINT16 = 1, - SPVC_MSL_INDEX_TYPE_UINT32 = 2, - SPVC_MSL_INDEX_TYPE_MAX_INT = 0x7fffffff -} spvc_msl_index_type; - -/* Maps to C++ API. */ -typedef enum spvc_msl_shader_variable_format -{ - SPVC_MSL_SHADER_VARIABLE_FORMAT_OTHER = 0, - SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT8 = 1, - SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT16 = 2, - SPVC_MSL_SHADER_VARIABLE_FORMAT_ANY16 = 3, - SPVC_MSL_SHADER_VARIABLE_FORMAT_ANY32 = 4, - - /* Deprecated names. */ - SPVC_MSL_VERTEX_FORMAT_OTHER = SPVC_MSL_SHADER_VARIABLE_FORMAT_OTHER, - SPVC_MSL_VERTEX_FORMAT_UINT8 = SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT8, - SPVC_MSL_VERTEX_FORMAT_UINT16 = SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT16, - SPVC_MSL_SHADER_INPUT_FORMAT_OTHER = SPVC_MSL_SHADER_VARIABLE_FORMAT_OTHER, - SPVC_MSL_SHADER_INPUT_FORMAT_UINT8 = SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT8, - SPVC_MSL_SHADER_INPUT_FORMAT_UINT16 = SPVC_MSL_SHADER_VARIABLE_FORMAT_UINT16, - SPVC_MSL_SHADER_INPUT_FORMAT_ANY16 = SPVC_MSL_SHADER_VARIABLE_FORMAT_ANY16, - SPVC_MSL_SHADER_INPUT_FORMAT_ANY32 = SPVC_MSL_SHADER_VARIABLE_FORMAT_ANY32, - - - SPVC_MSL_SHADER_INPUT_FORMAT_INT_MAX = 0x7fffffff -} spvc_msl_shader_variable_format, spvc_msl_shader_input_format, spvc_msl_vertex_format; - -/* Maps to C++ API. Deprecated; use spvc_msl_shader_interface_var. */ -typedef struct spvc_msl_vertex_attribute -{ - unsigned location; - - /* Obsolete, do not use. Only lingers on for ABI compatibility. */ - unsigned msl_buffer; - /* Obsolete, do not use. Only lingers on for ABI compatibility. */ - unsigned msl_offset; - /* Obsolete, do not use. Only lingers on for ABI compatibility. */ - unsigned msl_stride; - /* Obsolete, do not use. Only lingers on for ABI compatibility. */ - spvc_bool per_instance; - - spvc_msl_vertex_format format; - SpvBuiltIn builtin; -} spvc_msl_vertex_attribute; - -/* - * Initializes the vertex attribute struct. - */ -SPVC_PUBLIC_API void spvc_msl_vertex_attribute_init(spvc_msl_vertex_attribute *attr); - -/* Maps to C++ API. Deprecated; use spvc_msl_shader_interface_var_2. */ -typedef struct spvc_msl_shader_interface_var -{ - unsigned location; - spvc_msl_vertex_format format; - SpvBuiltIn builtin; - unsigned vecsize; -} spvc_msl_shader_interface_var, spvc_msl_shader_input; - -/* - * Initializes the shader input struct. - * Deprecated. Use spvc_msl_shader_interface_var_init_2(). - */ -SPVC_PUBLIC_API void spvc_msl_shader_interface_var_init(spvc_msl_shader_interface_var *var); -/* - * Deprecated. Use spvc_msl_shader_interface_var_init_2(). - */ -SPVC_PUBLIC_API void spvc_msl_shader_input_init(spvc_msl_shader_input *input); - -/* Maps to C++ API. */ -typedef enum spvc_msl_shader_variable_rate -{ - SPVC_MSL_SHADER_VARIABLE_RATE_PER_VERTEX = 0, - SPVC_MSL_SHADER_VARIABLE_RATE_PER_PRIMITIVE = 1, - SPVC_MSL_SHADER_VARIABLE_RATE_PER_PATCH = 2, - - SPVC_MSL_SHADER_VARIABLE_RATE_INT_MAX = 0x7fffffff, -} spvc_msl_shader_variable_rate; - -/* Maps to C++ API. */ -typedef struct spvc_msl_shader_interface_var_2 -{ - unsigned location; - spvc_msl_shader_variable_format format; - SpvBuiltIn builtin; - unsigned vecsize; - spvc_msl_shader_variable_rate rate; -} spvc_msl_shader_interface_var_2; - -/* - * Initializes the shader interface variable struct. - */ -SPVC_PUBLIC_API void spvc_msl_shader_interface_var_init_2(spvc_msl_shader_interface_var_2 *var); - -/* Maps to C++ API. */ -typedef struct spvc_msl_resource_binding -{ - SpvExecutionModel stage; - unsigned desc_set; - unsigned binding; - unsigned msl_buffer; - unsigned msl_texture; - unsigned msl_sampler; -} spvc_msl_resource_binding; - -/* - * Initializes the resource binding struct. - * The defaults are non-zero. - */ -SPVC_PUBLIC_API void spvc_msl_resource_binding_init(spvc_msl_resource_binding *binding); - -#define SPVC_MSL_PUSH_CONSTANT_DESC_SET (~(0u)) -#define SPVC_MSL_PUSH_CONSTANT_BINDING (0) -#define SPVC_MSL_SWIZZLE_BUFFER_BINDING (~(1u)) -#define SPVC_MSL_BUFFER_SIZE_BUFFER_BINDING (~(2u)) -#define SPVC_MSL_ARGUMENT_BUFFER_BINDING (~(3u)) - -/* Obsolete. Sticks around for backwards compatibility. */ -#define SPVC_MSL_AUX_BUFFER_STRUCT_VERSION 1 - -/* Runtime check for incompatibility. Obsolete. */ -SPVC_PUBLIC_API unsigned spvc_msl_get_aux_buffer_struct_version(void); - -/* Maps to C++ API. */ -typedef enum spvc_msl_sampler_coord -{ - SPVC_MSL_SAMPLER_COORD_NORMALIZED = 0, - SPVC_MSL_SAMPLER_COORD_PIXEL = 1, - SPVC_MSL_SAMPLER_INT_MAX = 0x7fffffff -} spvc_msl_sampler_coord; - -/* Maps to C++ API. */ -typedef enum spvc_msl_sampler_filter -{ - SPVC_MSL_SAMPLER_FILTER_NEAREST = 0, - SPVC_MSL_SAMPLER_FILTER_LINEAR = 1, - SPVC_MSL_SAMPLER_FILTER_INT_MAX = 0x7fffffff -} spvc_msl_sampler_filter; - -/* Maps to C++ API. */ -typedef enum spvc_msl_sampler_mip_filter -{ - SPVC_MSL_SAMPLER_MIP_FILTER_NONE = 0, - SPVC_MSL_SAMPLER_MIP_FILTER_NEAREST = 1, - SPVC_MSL_SAMPLER_MIP_FILTER_LINEAR = 2, - SPVC_MSL_SAMPLER_MIP_FILTER_INT_MAX = 0x7fffffff -} spvc_msl_sampler_mip_filter; - -/* Maps to C++ API. */ -typedef enum spvc_msl_sampler_address -{ - SPVC_MSL_SAMPLER_ADDRESS_CLAMP_TO_ZERO = 0, - SPVC_MSL_SAMPLER_ADDRESS_CLAMP_TO_EDGE = 1, - SPVC_MSL_SAMPLER_ADDRESS_CLAMP_TO_BORDER = 2, - SPVC_MSL_SAMPLER_ADDRESS_REPEAT = 3, - SPVC_MSL_SAMPLER_ADDRESS_MIRRORED_REPEAT = 4, - SPVC_MSL_SAMPLER_ADDRESS_INT_MAX = 0x7fffffff -} spvc_msl_sampler_address; - -/* Maps to C++ API. */ -typedef enum spvc_msl_sampler_compare_func -{ - SPVC_MSL_SAMPLER_COMPARE_FUNC_NEVER = 0, - SPVC_MSL_SAMPLER_COMPARE_FUNC_LESS = 1, - SPVC_MSL_SAMPLER_COMPARE_FUNC_LESS_EQUAL = 2, - SPVC_MSL_SAMPLER_COMPARE_FUNC_GREATER = 3, - SPVC_MSL_SAMPLER_COMPARE_FUNC_GREATER_EQUAL = 4, - SPVC_MSL_SAMPLER_COMPARE_FUNC_EQUAL = 5, - SPVC_MSL_SAMPLER_COMPARE_FUNC_NOT_EQUAL = 6, - SPVC_MSL_SAMPLER_COMPARE_FUNC_ALWAYS = 7, - SPVC_MSL_SAMPLER_COMPARE_FUNC_INT_MAX = 0x7fffffff -} spvc_msl_sampler_compare_func; - -/* Maps to C++ API. */ -typedef enum spvc_msl_sampler_border_color -{ - SPVC_MSL_SAMPLER_BORDER_COLOR_TRANSPARENT_BLACK = 0, - SPVC_MSL_SAMPLER_BORDER_COLOR_OPAQUE_BLACK = 1, - SPVC_MSL_SAMPLER_BORDER_COLOR_OPAQUE_WHITE = 2, - SPVC_MSL_SAMPLER_BORDER_COLOR_INT_MAX = 0x7fffffff -} spvc_msl_sampler_border_color; - -/* Maps to C++ API. */ -typedef enum spvc_msl_format_resolution -{ - SPVC_MSL_FORMAT_RESOLUTION_444 = 0, - SPVC_MSL_FORMAT_RESOLUTION_422, - SPVC_MSL_FORMAT_RESOLUTION_420, - SPVC_MSL_FORMAT_RESOLUTION_INT_MAX = 0x7fffffff -} spvc_msl_format_resolution; - -/* Maps to C++ API. */ -typedef enum spvc_msl_chroma_location -{ - SPVC_MSL_CHROMA_LOCATION_COSITED_EVEN = 0, - SPVC_MSL_CHROMA_LOCATION_MIDPOINT, - SPVC_MSL_CHROMA_LOCATION_INT_MAX = 0x7fffffff -} spvc_msl_chroma_location; - -/* Maps to C++ API. */ -typedef enum spvc_msl_component_swizzle -{ - SPVC_MSL_COMPONENT_SWIZZLE_IDENTITY = 0, - SPVC_MSL_COMPONENT_SWIZZLE_ZERO, - SPVC_MSL_COMPONENT_SWIZZLE_ONE, - SPVC_MSL_COMPONENT_SWIZZLE_R, - SPVC_MSL_COMPONENT_SWIZZLE_G, - SPVC_MSL_COMPONENT_SWIZZLE_B, - SPVC_MSL_COMPONENT_SWIZZLE_A, - SPVC_MSL_COMPONENT_SWIZZLE_INT_MAX = 0x7fffffff -} spvc_msl_component_swizzle; - -/* Maps to C++ API. */ -typedef enum spvc_msl_sampler_ycbcr_model_conversion -{ - SPVC_MSL_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY = 0, - SPVC_MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_IDENTITY, - SPVC_MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_709, - SPVC_MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_601, - SPVC_MSL_SAMPLER_YCBCR_MODEL_CONVERSION_YCBCR_BT_2020, - SPVC_MSL_SAMPLER_YCBCR_MODEL_CONVERSION_INT_MAX = 0x7fffffff -} spvc_msl_sampler_ycbcr_model_conversion; - -/* Maps to C+ API. */ -typedef enum spvc_msl_sampler_ycbcr_range -{ - SPVC_MSL_SAMPLER_YCBCR_RANGE_ITU_FULL = 0, - SPVC_MSL_SAMPLER_YCBCR_RANGE_ITU_NARROW, - SPVC_MSL_SAMPLER_YCBCR_RANGE_INT_MAX = 0x7fffffff -} spvc_msl_sampler_ycbcr_range; - -/* Maps to C++ API. */ -typedef struct spvc_msl_constexpr_sampler -{ - spvc_msl_sampler_coord coord; - spvc_msl_sampler_filter min_filter; - spvc_msl_sampler_filter mag_filter; - spvc_msl_sampler_mip_filter mip_filter; - spvc_msl_sampler_address s_address; - spvc_msl_sampler_address t_address; - spvc_msl_sampler_address r_address; - spvc_msl_sampler_compare_func compare_func; - spvc_msl_sampler_border_color border_color; - float lod_clamp_min; - float lod_clamp_max; - int max_anisotropy; - - spvc_bool compare_enable; - spvc_bool lod_clamp_enable; - spvc_bool anisotropy_enable; -} spvc_msl_constexpr_sampler; - -/* - * Initializes the constexpr sampler struct. - * The defaults are non-zero. - */ -SPVC_PUBLIC_API void spvc_msl_constexpr_sampler_init(spvc_msl_constexpr_sampler *sampler); - -/* Maps to the sampler Y'CbCr conversion-related portions of MSLConstexprSampler. See C++ API for defaults and details. */ -typedef struct spvc_msl_sampler_ycbcr_conversion -{ - unsigned planes; - spvc_msl_format_resolution resolution; - spvc_msl_sampler_filter chroma_filter; - spvc_msl_chroma_location x_chroma_offset; - spvc_msl_chroma_location y_chroma_offset; - spvc_msl_component_swizzle swizzle[4]; - spvc_msl_sampler_ycbcr_model_conversion ycbcr_model; - spvc_msl_sampler_ycbcr_range ycbcr_range; - unsigned bpc; -} spvc_msl_sampler_ycbcr_conversion; - -/* - * Initializes the constexpr sampler struct. - * The defaults are non-zero. - */ -SPVC_PUBLIC_API void spvc_msl_sampler_ycbcr_conversion_init(spvc_msl_sampler_ycbcr_conversion *conv); - -/* Maps to C++ API. */ -typedef enum spvc_hlsl_binding_flag_bits -{ - SPVC_HLSL_BINDING_AUTO_NONE_BIT = 0, - SPVC_HLSL_BINDING_AUTO_PUSH_CONSTANT_BIT = 1 << 0, - SPVC_HLSL_BINDING_AUTO_CBV_BIT = 1 << 1, - SPVC_HLSL_BINDING_AUTO_SRV_BIT = 1 << 2, - SPVC_HLSL_BINDING_AUTO_UAV_BIT = 1 << 3, - SPVC_HLSL_BINDING_AUTO_SAMPLER_BIT = 1 << 4, - SPVC_HLSL_BINDING_AUTO_ALL = 0x7fffffff -} spvc_hlsl_binding_flag_bits; -typedef unsigned spvc_hlsl_binding_flags; - -#define SPVC_HLSL_PUSH_CONSTANT_DESC_SET (~(0u)) -#define SPVC_HLSL_PUSH_CONSTANT_BINDING (0) - -/* Maps to C++ API. */ -typedef struct spvc_hlsl_resource_binding_mapping -{ - unsigned register_space; - unsigned register_binding; -} spvc_hlsl_resource_binding_mapping; - -typedef struct spvc_hlsl_resource_binding -{ - SpvExecutionModel stage; - unsigned desc_set; - unsigned binding; - - spvc_hlsl_resource_binding_mapping cbv, uav, srv, sampler; -} spvc_hlsl_resource_binding; - -/* - * Initializes the resource binding struct. - * The defaults are non-zero. - */ -SPVC_PUBLIC_API void spvc_hlsl_resource_binding_init(spvc_hlsl_resource_binding *binding); - -/* Maps to the various spirv_cross::Compiler*::Option structures. See C++ API for defaults and details. */ -typedef enum spvc_compiler_option -{ - SPVC_COMPILER_OPTION_UNKNOWN = 0, - - SPVC_COMPILER_OPTION_FORCE_TEMPORARY = 1 | SPVC_COMPILER_OPTION_COMMON_BIT, - SPVC_COMPILER_OPTION_FLATTEN_MULTIDIMENSIONAL_ARRAYS = 2 | SPVC_COMPILER_OPTION_COMMON_BIT, - SPVC_COMPILER_OPTION_FIXUP_DEPTH_CONVENTION = 3 | SPVC_COMPILER_OPTION_COMMON_BIT, - SPVC_COMPILER_OPTION_FLIP_VERTEX_Y = 4 | SPVC_COMPILER_OPTION_COMMON_BIT, - - SPVC_COMPILER_OPTION_GLSL_SUPPORT_NONZERO_BASE_INSTANCE = 5 | SPVC_COMPILER_OPTION_GLSL_BIT, - SPVC_COMPILER_OPTION_GLSL_SEPARATE_SHADER_OBJECTS = 6 | SPVC_COMPILER_OPTION_GLSL_BIT, - SPVC_COMPILER_OPTION_GLSL_ENABLE_420PACK_EXTENSION = 7 | SPVC_COMPILER_OPTION_GLSL_BIT, - SPVC_COMPILER_OPTION_GLSL_VERSION = 8 | SPVC_COMPILER_OPTION_GLSL_BIT, - SPVC_COMPILER_OPTION_GLSL_ES = 9 | SPVC_COMPILER_OPTION_GLSL_BIT, - SPVC_COMPILER_OPTION_GLSL_VULKAN_SEMANTICS = 10 | SPVC_COMPILER_OPTION_GLSL_BIT, - SPVC_COMPILER_OPTION_GLSL_ES_DEFAULT_FLOAT_PRECISION_HIGHP = 11 | SPVC_COMPILER_OPTION_GLSL_BIT, - SPVC_COMPILER_OPTION_GLSL_ES_DEFAULT_INT_PRECISION_HIGHP = 12 | SPVC_COMPILER_OPTION_GLSL_BIT, - - SPVC_COMPILER_OPTION_HLSL_SHADER_MODEL = 13 | SPVC_COMPILER_OPTION_HLSL_BIT, - SPVC_COMPILER_OPTION_HLSL_POINT_SIZE_COMPAT = 14 | SPVC_COMPILER_OPTION_HLSL_BIT, - SPVC_COMPILER_OPTION_HLSL_POINT_COORD_COMPAT = 15 | SPVC_COMPILER_OPTION_HLSL_BIT, - SPVC_COMPILER_OPTION_HLSL_SUPPORT_NONZERO_BASE_VERTEX_BASE_INSTANCE = 16 | SPVC_COMPILER_OPTION_HLSL_BIT, - - SPVC_COMPILER_OPTION_MSL_VERSION = 17 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_TEXEL_BUFFER_TEXTURE_WIDTH = 18 | SPVC_COMPILER_OPTION_MSL_BIT, - - /* Obsolete, use SWIZZLE_BUFFER_INDEX instead. */ - SPVC_COMPILER_OPTION_MSL_AUX_BUFFER_INDEX = 19 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_SWIZZLE_BUFFER_INDEX = 19 | SPVC_COMPILER_OPTION_MSL_BIT, - - SPVC_COMPILER_OPTION_MSL_INDIRECT_PARAMS_BUFFER_INDEX = 20 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_SHADER_OUTPUT_BUFFER_INDEX = 21 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_SHADER_PATCH_OUTPUT_BUFFER_INDEX = 22 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_SHADER_TESS_FACTOR_OUTPUT_BUFFER_INDEX = 23 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_SHADER_INPUT_WORKGROUP_INDEX = 24 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_ENABLE_POINT_SIZE_BUILTIN = 25 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_DISABLE_RASTERIZATION = 26 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_CAPTURE_OUTPUT_TO_BUFFER = 27 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_SWIZZLE_TEXTURE_SAMPLES = 28 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_PAD_FRAGMENT_OUTPUT_COMPONENTS = 29 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_TESS_DOMAIN_ORIGIN_LOWER_LEFT = 30 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_PLATFORM = 31 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS = 32 | SPVC_COMPILER_OPTION_MSL_BIT, - - SPVC_COMPILER_OPTION_GLSL_EMIT_PUSH_CONSTANT_AS_UNIFORM_BUFFER = 33 | SPVC_COMPILER_OPTION_GLSL_BIT, - - SPVC_COMPILER_OPTION_MSL_TEXTURE_BUFFER_NATIVE = 34 | SPVC_COMPILER_OPTION_MSL_BIT, - - SPVC_COMPILER_OPTION_GLSL_EMIT_UNIFORM_BUFFER_AS_PLAIN_UNIFORMS = 35 | SPVC_COMPILER_OPTION_GLSL_BIT, - - SPVC_COMPILER_OPTION_MSL_BUFFER_SIZE_BUFFER_INDEX = 36 | SPVC_COMPILER_OPTION_MSL_BIT, - - SPVC_COMPILER_OPTION_EMIT_LINE_DIRECTIVES = 37 | SPVC_COMPILER_OPTION_COMMON_BIT, - - SPVC_COMPILER_OPTION_MSL_MULTIVIEW = 38 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_VIEW_MASK_BUFFER_INDEX = 39 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_DEVICE_INDEX = 40 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_VIEW_INDEX_FROM_DEVICE_INDEX = 41 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_DISPATCH_BASE = 42 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_DYNAMIC_OFFSETS_BUFFER_INDEX = 43 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_TEXTURE_1D_AS_2D = 44 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_ENABLE_BASE_INDEX_ZERO = 45 | SPVC_COMPILER_OPTION_MSL_BIT, - - /* Obsolete. Use MSL_FRAMEBUFFER_FETCH_SUBPASS instead. */ - SPVC_COMPILER_OPTION_MSL_IOS_FRAMEBUFFER_FETCH_SUBPASS = 46 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_FRAMEBUFFER_FETCH_SUBPASS = 46 | SPVC_COMPILER_OPTION_MSL_BIT, - - SPVC_COMPILER_OPTION_MSL_INVARIANT_FP_MATH = 47 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_EMULATE_CUBEMAP_ARRAY = 48 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_ENABLE_DECORATION_BINDING = 49 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_FORCE_ACTIVE_ARGUMENT_BUFFER_RESOURCES = 50 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_FORCE_NATIVE_ARRAYS = 51 | SPVC_COMPILER_OPTION_MSL_BIT, - - SPVC_COMPILER_OPTION_ENABLE_STORAGE_IMAGE_QUALIFIER_DEDUCTION = 52 | SPVC_COMPILER_OPTION_COMMON_BIT, - - SPVC_COMPILER_OPTION_HLSL_FORCE_STORAGE_BUFFER_AS_UAV = 53 | SPVC_COMPILER_OPTION_HLSL_BIT, - - SPVC_COMPILER_OPTION_FORCE_ZERO_INITIALIZED_VARIABLES = 54 | SPVC_COMPILER_OPTION_COMMON_BIT, - - SPVC_COMPILER_OPTION_HLSL_NONWRITABLE_UAV_TEXTURE_AS_SRV = 55 | SPVC_COMPILER_OPTION_HLSL_BIT, - - SPVC_COMPILER_OPTION_MSL_ENABLE_FRAG_OUTPUT_MASK = 56 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_ENABLE_FRAG_DEPTH_BUILTIN = 57 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_ENABLE_FRAG_STENCIL_REF_BUILTIN = 58 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_ENABLE_CLIP_DISTANCE_USER_VARYING = 59 | SPVC_COMPILER_OPTION_MSL_BIT, - - SPVC_COMPILER_OPTION_HLSL_ENABLE_16BIT_TYPES = 60 | SPVC_COMPILER_OPTION_HLSL_BIT, - - SPVC_COMPILER_OPTION_MSL_MULTI_PATCH_WORKGROUP = 61 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_SHADER_INPUT_BUFFER_INDEX = 62 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_SHADER_INDEX_BUFFER_INDEX = 63 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_VERTEX_FOR_TESSELLATION = 64 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_VERTEX_INDEX_TYPE = 65 | SPVC_COMPILER_OPTION_MSL_BIT, - - SPVC_COMPILER_OPTION_GLSL_FORCE_FLATTENED_IO_BLOCKS = 66 | SPVC_COMPILER_OPTION_GLSL_BIT, - - SPVC_COMPILER_OPTION_MSL_MULTIVIEW_LAYERED_RENDERING = 67 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_ARRAYED_SUBPASS_INPUT = 68 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_R32UI_LINEAR_TEXTURE_ALIGNMENT = 69 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_R32UI_ALIGNMENT_CONSTANT_ID = 70 | SPVC_COMPILER_OPTION_MSL_BIT, - - SPVC_COMPILER_OPTION_HLSL_FLATTEN_MATRIX_VERTEX_INPUT_SEMANTICS = 71 | SPVC_COMPILER_OPTION_HLSL_BIT, - - SPVC_COMPILER_OPTION_MSL_IOS_USE_SIMDGROUP_FUNCTIONS = 72 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_EMULATE_SUBGROUPS = 73 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_FIXED_SUBGROUP_SIZE = 74 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_FORCE_SAMPLE_RATE_SHADING = 75 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_IOS_SUPPORT_BASE_VERTEX_INSTANCE = 76 | SPVC_COMPILER_OPTION_MSL_BIT, - - SPVC_COMPILER_OPTION_GLSL_OVR_MULTIVIEW_VIEW_COUNT = 77 | SPVC_COMPILER_OPTION_GLSL_BIT, - - SPVC_COMPILER_OPTION_RELAX_NAN_CHECKS = 78 | SPVC_COMPILER_OPTION_COMMON_BIT, - - SPVC_COMPILER_OPTION_MSL_RAW_BUFFER_TESE_INPUT = 79 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_SHADER_PATCH_INPUT_BUFFER_INDEX = 80 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_MANUAL_HELPER_INVOCATION_UPDATES = 81 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_CHECK_DISCARDED_FRAG_STORES = 82 | SPVC_COMPILER_OPTION_MSL_BIT, - - SPVC_COMPILER_OPTION_GLSL_ENABLE_ROW_MAJOR_LOAD_WORKAROUND = 83 | SPVC_COMPILER_OPTION_GLSL_BIT, - - SPVC_COMPILER_OPTION_MSL_ARGUMENT_BUFFERS_TIER = 84 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_SAMPLE_DREF_LOD_ARRAY_AS_GRAD = 85 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_READWRITE_TEXTURE_FENCES = 86 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_REPLACE_RECURSIVE_INPUTS = 87 | SPVC_COMPILER_OPTION_MSL_BIT, - SPVC_COMPILER_OPTION_MSL_AGX_MANUAL_CUBE_GRAD_FIXUP = 88 | SPVC_COMPILER_OPTION_MSL_BIT, - - SPVC_COMPILER_OPTION_INT_MAX = 0x7fffffff -} spvc_compiler_option; - -/* - * Context is the highest-level API construct. - * The context owns all memory allocations made by its child object hierarchy, including various non-opaque structs and strings. - * This means that the API user only has to care about one "destroy" call ever when using the C API. - * All pointers handed out by the APIs are only valid as long as the context - * is alive and spvc_context_release_allocations has not been called. - */ -SPVC_PUBLIC_API spvc_result spvc_context_create(spvc_context *context); - -/* Frees all memory allocations and objects associated with the context and its child objects. */ -SPVC_PUBLIC_API void spvc_context_destroy(spvc_context context); - -/* Frees all memory allocations and objects associated with the context and its child objects, but keeps the context alive. */ -SPVC_PUBLIC_API void spvc_context_release_allocations(spvc_context context); - -/* Get the string for the last error which was logged. */ -SPVC_PUBLIC_API const char *spvc_context_get_last_error_string(spvc_context context); - -/* Get notified in a callback when an error triggers. Useful for debugging. */ -typedef void (*spvc_error_callback)(void *userdata, const char *error); -SPVC_PUBLIC_API void spvc_context_set_error_callback(spvc_context context, spvc_error_callback cb, void *userdata); - -/* SPIR-V parsing interface. Maps to Parser which then creates a ParsedIR, and that IR is extracted into the handle. */ -SPVC_PUBLIC_API spvc_result spvc_context_parse_spirv(spvc_context context, const SpvId *spirv, size_t word_count, - spvc_parsed_ir *parsed_ir); - -/* - * Create a compiler backend. Capture mode controls if we construct by copy or move semantics. - * It is always recommended to use SPVC_CAPTURE_MODE_TAKE_OWNERSHIP if you only intend to cross-compile the IR once. - */ -SPVC_PUBLIC_API spvc_result spvc_context_create_compiler(spvc_context context, spvc_backend backend, - spvc_parsed_ir parsed_ir, spvc_capture_mode mode, - spvc_compiler *compiler); - -/* Maps directly to C++ API. */ -SPVC_PUBLIC_API unsigned spvc_compiler_get_current_id_bound(spvc_compiler compiler); - -/* Create compiler options, which will initialize defaults. */ -SPVC_PUBLIC_API spvc_result spvc_compiler_create_compiler_options(spvc_compiler compiler, - spvc_compiler_options *options); -/* Override options. Will return error if e.g. MSL options are used for the HLSL backend, etc. */ -SPVC_PUBLIC_API spvc_result spvc_compiler_options_set_bool(spvc_compiler_options options, - spvc_compiler_option option, spvc_bool value); -SPVC_PUBLIC_API spvc_result spvc_compiler_options_set_uint(spvc_compiler_options options, - spvc_compiler_option option, unsigned value); -/* Set compiler options. */ -SPVC_PUBLIC_API spvc_result spvc_compiler_install_compiler_options(spvc_compiler compiler, - spvc_compiler_options options); - -/* Compile IR into a string. *source is owned by the context, and caller must not free it themselves. */ -SPVC_PUBLIC_API spvc_result spvc_compiler_compile(spvc_compiler compiler, const char **source); - -/* Maps to C++ API. */ -SPVC_PUBLIC_API spvc_result spvc_compiler_add_header_line(spvc_compiler compiler, const char *line); -SPVC_PUBLIC_API spvc_result spvc_compiler_require_extension(spvc_compiler compiler, const char *ext); -SPVC_PUBLIC_API size_t spvc_compiler_get_num_required_extensions(spvc_compiler compiler); -SPVC_PUBLIC_API const char *spvc_compiler_get_required_extension(spvc_compiler compiler, size_t index); -SPVC_PUBLIC_API spvc_result spvc_compiler_flatten_buffer_block(spvc_compiler compiler, spvc_variable_id id); - -SPVC_PUBLIC_API spvc_bool spvc_compiler_variable_is_depth_or_compare(spvc_compiler compiler, spvc_variable_id id); - -SPVC_PUBLIC_API spvc_result spvc_compiler_mask_stage_output_by_location(spvc_compiler compiler, - unsigned location, unsigned component); -SPVC_PUBLIC_API spvc_result spvc_compiler_mask_stage_output_by_builtin(spvc_compiler compiler, SpvBuiltIn builtin); - -/* - * HLSL specifics. - * Maps to C++ API. - */ -SPVC_PUBLIC_API spvc_result spvc_compiler_hlsl_set_root_constants_layout(spvc_compiler compiler, - const spvc_hlsl_root_constants *constant_info, - size_t count); -SPVC_PUBLIC_API spvc_result spvc_compiler_hlsl_add_vertex_attribute_remap(spvc_compiler compiler, - const spvc_hlsl_vertex_attribute_remap *remap, - size_t remaps); -SPVC_PUBLIC_API spvc_variable_id spvc_compiler_hlsl_remap_num_workgroups_builtin(spvc_compiler compiler); - -SPVC_PUBLIC_API spvc_result spvc_compiler_hlsl_set_resource_binding_flags(spvc_compiler compiler, - spvc_hlsl_binding_flags flags); - -SPVC_PUBLIC_API spvc_result spvc_compiler_hlsl_add_resource_binding(spvc_compiler compiler, - const spvc_hlsl_resource_binding *binding); -SPVC_PUBLIC_API spvc_bool spvc_compiler_hlsl_is_resource_used(spvc_compiler compiler, - SpvExecutionModel model, - unsigned set, - unsigned binding); - -/* - * MSL specifics. - * Maps to C++ API. - */ -SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_rasterization_disabled(spvc_compiler compiler); - -/* Obsolete. Renamed to needs_swizzle_buffer. */ -SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_aux_buffer(spvc_compiler compiler); -SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_swizzle_buffer(spvc_compiler compiler); -SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_buffer_size_buffer(spvc_compiler compiler); - -SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_output_buffer(spvc_compiler compiler); -SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_patch_output_buffer(spvc_compiler compiler); -SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_needs_input_threadgroup_mem(spvc_compiler compiler); -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_vertex_attribute(spvc_compiler compiler, - const spvc_msl_vertex_attribute *attrs); -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_resource_binding(spvc_compiler compiler, - const spvc_msl_resource_binding *binding); -/* Deprecated; use spvc_compiler_msl_add_shader_input_2(). */ -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_input(spvc_compiler compiler, - const spvc_msl_shader_interface_var *input); -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_input_2(spvc_compiler compiler, - const spvc_msl_shader_interface_var_2 *input); -/* Deprecated; use spvc_compiler_msl_add_shader_output_2(). */ -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_output(spvc_compiler compiler, - const spvc_msl_shader_interface_var *output); -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_shader_output_2(spvc_compiler compiler, - const spvc_msl_shader_interface_var_2 *output); -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_discrete_descriptor_set(spvc_compiler compiler, unsigned desc_set); -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_set_argument_buffer_device_address_space(spvc_compiler compiler, unsigned desc_set, spvc_bool device_address); - -/* Obsolete, use is_shader_input_used. */ -SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_vertex_attribute_used(spvc_compiler compiler, unsigned location); -SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_shader_input_used(spvc_compiler compiler, unsigned location); -SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_shader_output_used(spvc_compiler compiler, unsigned location); - -SPVC_PUBLIC_API spvc_bool spvc_compiler_msl_is_resource_used(spvc_compiler compiler, - SpvExecutionModel model, - unsigned set, - unsigned binding); -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_remap_constexpr_sampler(spvc_compiler compiler, spvc_variable_id id, const spvc_msl_constexpr_sampler *sampler); -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_remap_constexpr_sampler_by_binding(spvc_compiler compiler, unsigned desc_set, unsigned binding, const spvc_msl_constexpr_sampler *sampler); -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_remap_constexpr_sampler_ycbcr(spvc_compiler compiler, spvc_variable_id id, const spvc_msl_constexpr_sampler *sampler, const spvc_msl_sampler_ycbcr_conversion *conv); -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_remap_constexpr_sampler_by_binding_ycbcr(spvc_compiler compiler, unsigned desc_set, unsigned binding, const spvc_msl_constexpr_sampler *sampler, const spvc_msl_sampler_ycbcr_conversion *conv); -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_set_fragment_output_components(spvc_compiler compiler, unsigned location, unsigned components); - -SPVC_PUBLIC_API unsigned spvc_compiler_msl_get_automatic_resource_binding(spvc_compiler compiler, spvc_variable_id id); -SPVC_PUBLIC_API unsigned spvc_compiler_msl_get_automatic_resource_binding_secondary(spvc_compiler compiler, spvc_variable_id id); - -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_dynamic_buffer(spvc_compiler compiler, unsigned desc_set, unsigned binding, unsigned index); - -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_add_inline_uniform_block(spvc_compiler compiler, unsigned desc_set, unsigned binding); - -SPVC_PUBLIC_API spvc_result spvc_compiler_msl_set_combined_sampler_suffix(spvc_compiler compiler, const char *suffix); -SPVC_PUBLIC_API const char *spvc_compiler_msl_get_combined_sampler_suffix(spvc_compiler compiler); - -/* - * Reflect resources. - * Maps almost 1:1 to C++ API. - */ -SPVC_PUBLIC_API spvc_result spvc_compiler_get_active_interface_variables(spvc_compiler compiler, spvc_set *set); -SPVC_PUBLIC_API spvc_result spvc_compiler_set_enabled_interface_variables(spvc_compiler compiler, spvc_set set); -SPVC_PUBLIC_API spvc_result spvc_compiler_create_shader_resources(spvc_compiler compiler, spvc_resources *resources); -SPVC_PUBLIC_API spvc_result spvc_compiler_create_shader_resources_for_active_variables(spvc_compiler compiler, - spvc_resources *resources, - spvc_set active); -SPVC_PUBLIC_API spvc_result spvc_resources_get_resource_list_for_type(spvc_resources resources, spvc_resource_type type, - const spvc_reflected_resource **resource_list, - size_t *resource_size); - -SPVC_PUBLIC_API spvc_result spvc_resources_get_builtin_resource_list_for_type( - spvc_resources resources, spvc_builtin_resource_type type, - const spvc_reflected_builtin_resource **resource_list, - size_t *resource_size); - -/* - * Decorations. - * Maps to C++ API. - */ -SPVC_PUBLIC_API void spvc_compiler_set_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration, - unsigned argument); -SPVC_PUBLIC_API void spvc_compiler_set_decoration_string(spvc_compiler compiler, SpvId id, SpvDecoration decoration, - const char *argument); -SPVC_PUBLIC_API void spvc_compiler_set_name(spvc_compiler compiler, SpvId id, const char *argument); -SPVC_PUBLIC_API void spvc_compiler_set_member_decoration(spvc_compiler compiler, spvc_type_id id, unsigned member_index, - SpvDecoration decoration, unsigned argument); -SPVC_PUBLIC_API void spvc_compiler_set_member_decoration_string(spvc_compiler compiler, spvc_type_id id, - unsigned member_index, SpvDecoration decoration, - const char *argument); -SPVC_PUBLIC_API void spvc_compiler_set_member_name(spvc_compiler compiler, spvc_type_id id, unsigned member_index, - const char *argument); -SPVC_PUBLIC_API void spvc_compiler_unset_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration); -SPVC_PUBLIC_API void spvc_compiler_unset_member_decoration(spvc_compiler compiler, spvc_type_id id, - unsigned member_index, SpvDecoration decoration); - -SPVC_PUBLIC_API spvc_bool spvc_compiler_has_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration); -SPVC_PUBLIC_API spvc_bool spvc_compiler_has_member_decoration(spvc_compiler compiler, spvc_type_id id, - unsigned member_index, SpvDecoration decoration); -SPVC_PUBLIC_API const char *spvc_compiler_get_name(spvc_compiler compiler, SpvId id); -SPVC_PUBLIC_API unsigned spvc_compiler_get_decoration(spvc_compiler compiler, SpvId id, SpvDecoration decoration); -SPVC_PUBLIC_API const char *spvc_compiler_get_decoration_string(spvc_compiler compiler, SpvId id, - SpvDecoration decoration); -SPVC_PUBLIC_API unsigned spvc_compiler_get_member_decoration(spvc_compiler compiler, spvc_type_id id, - unsigned member_index, SpvDecoration decoration); -SPVC_PUBLIC_API const char *spvc_compiler_get_member_decoration_string(spvc_compiler compiler, spvc_type_id id, - unsigned member_index, SpvDecoration decoration); -SPVC_PUBLIC_API const char *spvc_compiler_get_member_name(spvc_compiler compiler, spvc_type_id id, unsigned member_index); - -/* - * Entry points. - * Maps to C++ API. - */ -SPVC_PUBLIC_API spvc_result spvc_compiler_get_entry_points(spvc_compiler compiler, - const spvc_entry_point **entry_points, - size_t *num_entry_points); -SPVC_PUBLIC_API spvc_result spvc_compiler_set_entry_point(spvc_compiler compiler, const char *name, - SpvExecutionModel model); -SPVC_PUBLIC_API spvc_result spvc_compiler_rename_entry_point(spvc_compiler compiler, const char *old_name, - const char *new_name, SpvExecutionModel model); -SPVC_PUBLIC_API const char *spvc_compiler_get_cleansed_entry_point_name(spvc_compiler compiler, const char *name, - SpvExecutionModel model); -SPVC_PUBLIC_API void spvc_compiler_set_execution_mode(spvc_compiler compiler, SpvExecutionMode mode); -SPVC_PUBLIC_API void spvc_compiler_unset_execution_mode(spvc_compiler compiler, SpvExecutionMode mode); -SPVC_PUBLIC_API void spvc_compiler_set_execution_mode_with_arguments(spvc_compiler compiler, SpvExecutionMode mode, - unsigned arg0, unsigned arg1, unsigned arg2); -SPVC_PUBLIC_API spvc_result spvc_compiler_get_execution_modes(spvc_compiler compiler, const SpvExecutionMode **modes, - size_t *num_modes); -SPVC_PUBLIC_API unsigned spvc_compiler_get_execution_mode_argument(spvc_compiler compiler, SpvExecutionMode mode); -SPVC_PUBLIC_API unsigned spvc_compiler_get_execution_mode_argument_by_index(spvc_compiler compiler, - SpvExecutionMode mode, unsigned index); -SPVC_PUBLIC_API SpvExecutionModel spvc_compiler_get_execution_model(spvc_compiler compiler); -SPVC_PUBLIC_API void spvc_compiler_update_active_builtins(spvc_compiler compiler); -SPVC_PUBLIC_API spvc_bool spvc_compiler_has_active_builtin(spvc_compiler compiler, SpvBuiltIn builtin, SpvStorageClass storage); - -/* - * Type query interface. - * Maps to C++ API, except it's read-only. - */ -SPVC_PUBLIC_API spvc_type spvc_compiler_get_type_handle(spvc_compiler compiler, spvc_type_id id); - -/* Pulls out SPIRType::self. This effectively gives the type ID without array or pointer qualifiers. - * This is necessary when reflecting decoration/name information on members of a struct, - * which are placed in the base type, not the qualified type. - * This is similar to spvc_reflected_resource::base_type_id. */ -SPVC_PUBLIC_API spvc_type_id spvc_type_get_base_type_id(spvc_type type); - -SPVC_PUBLIC_API spvc_basetype spvc_type_get_basetype(spvc_type type); -SPVC_PUBLIC_API unsigned spvc_type_get_bit_width(spvc_type type); -SPVC_PUBLIC_API unsigned spvc_type_get_vector_size(spvc_type type); -SPVC_PUBLIC_API unsigned spvc_type_get_columns(spvc_type type); -SPVC_PUBLIC_API unsigned spvc_type_get_num_array_dimensions(spvc_type type); -SPVC_PUBLIC_API spvc_bool spvc_type_array_dimension_is_literal(spvc_type type, unsigned dimension); -SPVC_PUBLIC_API SpvId spvc_type_get_array_dimension(spvc_type type, unsigned dimension); -SPVC_PUBLIC_API unsigned spvc_type_get_num_member_types(spvc_type type); -SPVC_PUBLIC_API spvc_type_id spvc_type_get_member_type(spvc_type type, unsigned index); -SPVC_PUBLIC_API SpvStorageClass spvc_type_get_storage_class(spvc_type type); - -/* Image type query. */ -SPVC_PUBLIC_API spvc_type_id spvc_type_get_image_sampled_type(spvc_type type); -SPVC_PUBLIC_API SpvDim spvc_type_get_image_dimension(spvc_type type); -SPVC_PUBLIC_API spvc_bool spvc_type_get_image_is_depth(spvc_type type); -SPVC_PUBLIC_API spvc_bool spvc_type_get_image_arrayed(spvc_type type); -SPVC_PUBLIC_API spvc_bool spvc_type_get_image_multisampled(spvc_type type); -SPVC_PUBLIC_API spvc_bool spvc_type_get_image_is_storage(spvc_type type); -SPVC_PUBLIC_API SpvImageFormat spvc_type_get_image_storage_format(spvc_type type); -SPVC_PUBLIC_API SpvAccessQualifier spvc_type_get_image_access_qualifier(spvc_type type); - -/* - * Buffer layout query. - * Maps to C++ API. - */ -SPVC_PUBLIC_API spvc_result spvc_compiler_get_declared_struct_size(spvc_compiler compiler, spvc_type struct_type, size_t *size); -SPVC_PUBLIC_API spvc_result spvc_compiler_get_declared_struct_size_runtime_array(spvc_compiler compiler, - spvc_type struct_type, size_t array_size, size_t *size); -SPVC_PUBLIC_API spvc_result spvc_compiler_get_declared_struct_member_size(spvc_compiler compiler, spvc_type type, unsigned index, size_t *size); - -SPVC_PUBLIC_API spvc_result spvc_compiler_type_struct_member_offset(spvc_compiler compiler, - spvc_type type, unsigned index, unsigned *offset); -SPVC_PUBLIC_API spvc_result spvc_compiler_type_struct_member_array_stride(spvc_compiler compiler, - spvc_type type, unsigned index, unsigned *stride); -SPVC_PUBLIC_API spvc_result spvc_compiler_type_struct_member_matrix_stride(spvc_compiler compiler, - spvc_type type, unsigned index, unsigned *stride); - -/* - * Workaround helper functions. - * Maps to C++ API. - */ -SPVC_PUBLIC_API spvc_result spvc_compiler_build_dummy_sampler_for_combined_images(spvc_compiler compiler, spvc_variable_id *id); -SPVC_PUBLIC_API spvc_result spvc_compiler_build_combined_image_samplers(spvc_compiler compiler); -SPVC_PUBLIC_API spvc_result spvc_compiler_get_combined_image_samplers(spvc_compiler compiler, - const spvc_combined_image_sampler **samplers, - size_t *num_samplers); - -/* - * Constants - * Maps to C++ API. - */ -SPVC_PUBLIC_API spvc_result spvc_compiler_get_specialization_constants(spvc_compiler compiler, - const spvc_specialization_constant **constants, - size_t *num_constants); -SPVC_PUBLIC_API spvc_constant spvc_compiler_get_constant_handle(spvc_compiler compiler, - spvc_constant_id id); - -SPVC_PUBLIC_API spvc_constant_id spvc_compiler_get_work_group_size_specialization_constants(spvc_compiler compiler, - spvc_specialization_constant *x, - spvc_specialization_constant *y, - spvc_specialization_constant *z); - -/* - * Buffer ranges - * Maps to C++ API. - */ -SPVC_PUBLIC_API spvc_result spvc_compiler_get_active_buffer_ranges(spvc_compiler compiler, - spvc_variable_id id, - const spvc_buffer_range **ranges, - size_t *num_ranges); - -/* - * No stdint.h until C99, sigh :( - * For smaller types, the result is sign or zero-extended as appropriate. - * Maps to C++ API. - * TODO: The SPIRConstant query interface and modification interface is not quite complete. - */ -SPVC_PUBLIC_API float spvc_constant_get_scalar_fp16(spvc_constant constant, unsigned column, unsigned row); -SPVC_PUBLIC_API float spvc_constant_get_scalar_fp32(spvc_constant constant, unsigned column, unsigned row); -SPVC_PUBLIC_API double spvc_constant_get_scalar_fp64(spvc_constant constant, unsigned column, unsigned row); -SPVC_PUBLIC_API unsigned spvc_constant_get_scalar_u32(spvc_constant constant, unsigned column, unsigned row); -SPVC_PUBLIC_API int spvc_constant_get_scalar_i32(spvc_constant constant, unsigned column, unsigned row); -SPVC_PUBLIC_API unsigned spvc_constant_get_scalar_u16(spvc_constant constant, unsigned column, unsigned row); -SPVC_PUBLIC_API int spvc_constant_get_scalar_i16(spvc_constant constant, unsigned column, unsigned row); -SPVC_PUBLIC_API unsigned spvc_constant_get_scalar_u8(spvc_constant constant, unsigned column, unsigned row); -SPVC_PUBLIC_API int spvc_constant_get_scalar_i8(spvc_constant constant, unsigned column, unsigned row); -SPVC_PUBLIC_API void spvc_constant_get_subconstants(spvc_constant constant, const spvc_constant_id **constituents, size_t *count); -SPVC_PUBLIC_API spvc_type_id spvc_constant_get_type(spvc_constant constant); - -/* - * C implementation of the C++ api. - */ -SPVC_PUBLIC_API void spvc_constant_set_scalar_fp16(spvc_constant constant, unsigned column, unsigned row, unsigned short value); -SPVC_PUBLIC_API void spvc_constant_set_scalar_fp32(spvc_constant constant, unsigned column, unsigned row, float value); -SPVC_PUBLIC_API void spvc_constant_set_scalar_fp64(spvc_constant constant, unsigned column, unsigned row, double value); -SPVC_PUBLIC_API void spvc_constant_set_scalar_u32(spvc_constant constant, unsigned column, unsigned row, unsigned value); -SPVC_PUBLIC_API void spvc_constant_set_scalar_i32(spvc_constant constant, unsigned column, unsigned row, int value); -SPVC_PUBLIC_API void spvc_constant_set_scalar_u16(spvc_constant constant, unsigned column, unsigned row, unsigned short value); -SPVC_PUBLIC_API void spvc_constant_set_scalar_i16(spvc_constant constant, unsigned column, unsigned row, signed short value); -SPVC_PUBLIC_API void spvc_constant_set_scalar_u8(spvc_constant constant, unsigned column, unsigned row, unsigned char value); -SPVC_PUBLIC_API void spvc_constant_set_scalar_i8(spvc_constant constant, unsigned column, unsigned row, signed char value); - -/* - * Misc reflection - * Maps to C++ API. - */ -SPVC_PUBLIC_API spvc_bool spvc_compiler_get_binary_offset_for_decoration(spvc_compiler compiler, - spvc_variable_id id, - SpvDecoration decoration, - unsigned *word_offset); - -SPVC_PUBLIC_API spvc_bool spvc_compiler_buffer_is_hlsl_counter_buffer(spvc_compiler compiler, spvc_variable_id id); -SPVC_PUBLIC_API spvc_bool spvc_compiler_buffer_get_hlsl_counter_buffer(spvc_compiler compiler, spvc_variable_id id, - spvc_variable_id *counter_id); - -SPVC_PUBLIC_API spvc_result spvc_compiler_get_declared_capabilities(spvc_compiler compiler, - const SpvCapability **capabilities, - size_t *num_capabilities); -SPVC_PUBLIC_API spvc_result spvc_compiler_get_declared_extensions(spvc_compiler compiler, const char ***extensions, - size_t *num_extensions); - -SPVC_PUBLIC_API const char *spvc_compiler_get_remapped_declared_block_name(spvc_compiler compiler, spvc_variable_id id); -SPVC_PUBLIC_API spvc_result spvc_compiler_get_buffer_block_decorations(spvc_compiler compiler, spvc_variable_id id, - const SpvDecoration **decorations, - size_t *num_decorations); - -#ifdef __cplusplus -} -#endif -#endif From 904ab47d1fc52d34dbc2c6c1efef3554d6c0fb0d Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sun, 7 Jan 2024 21:22:43 -0400 Subject: [PATCH 17/29] Fix cmake project --- CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c679fecb..34729c171 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1753,8 +1753,6 @@ set(LOVE_SRC_3P_SPIRV_CROSS src/libraries/spirv_cross/spirv_common.hpp src/libraries/spirv_cross/spirv_cpp.cpp src/libraries/spirv_cross/spirv_cpp.hpp - src/libraries/spirv_cross/spirv_cross_c.cpp - src/libraries/spirv_cross/spirv_cross_c.h src/libraries/spirv_cross/spirv_cross_containers.hpp src/libraries/spirv_cross/spirv_cross_error_handling.hpp src/libraries/spirv_cross/spirv_cross_parsed_ir.cpp @@ -1773,7 +1771,6 @@ set(LOVE_SRC_3P_SPIRV_CROSS src/libraries/spirv_cross/spirv_parser.hpp src/libraries/spirv_cross/spirv_reflect.cpp src/libraries/spirv_cross/spirv_reflect.hpp - src/libraries/spirv_cross/spirv.h src/libraries/spirv_cross/spirv.hpp ) From c6b3d136af8416aeee61b42a56c4b48caf47e315 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sun, 7 Jan 2024 21:26:10 -0400 Subject: [PATCH 18/29] iOS: update deployment target newer glslang versions require newer C++ features than the old target supported. --- platform/xcode/liblove.xcodeproj/project.pbxproj | 6 +++--- platform/xcode/love.xcodeproj/project.pbxproj | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index c67adf2fd..91b27a55a 100644 --- a/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/platform/xcode/liblove.xcodeproj/project.pbxproj @@ -5513,7 +5513,7 @@ "\"$(SRCROOT)/../../src/modules\"", "\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"", ); - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LIBRARY_SEARCH_PATHS = ""; MACOSX_DEPLOYMENT_TARGET = 10.13; ONLY_ACTIVE_ARCH = NO; @@ -5579,7 +5579,7 @@ "\"$(SRCROOT)/../../src/modules\"", "\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"", ); - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LIBRARY_SEARCH_PATHS = ""; MACOSX_DEPLOYMENT_TARGET = 10.13; ONLY_ACTIVE_ARCH = YES; @@ -5717,7 +5717,7 @@ "\"$(SRCROOT)/../../src/modules\"", "\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"", ); - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LIBRARY_SEARCH_PATHS = ""; LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.13; diff --git a/platform/xcode/love.xcodeproj/project.pbxproj b/platform/xcode/love.xcodeproj/project.pbxproj index 00d46f5b2..baa028198 100644 --- a/platform/xcode/love.xcodeproj/project.pbxproj +++ b/platform/xcode/love.xcodeproj/project.pbxproj @@ -562,7 +562,7 @@ "\"$(SRCROOT)/../../src/modules\"", ); INFOPLIST_FILE = "love-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks"; MACOSX_DEPLOYMENT_TARGET = 10.13; ONLY_ACTIVE_ARCH = YES; @@ -637,7 +637,7 @@ "\"$(SRCROOT)/../../src/modules\"", ); INFOPLIST_FILE = "love-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks"; LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.13; @@ -871,7 +871,7 @@ "\"$(SRCROOT)/../../src/modules\"", ); INFOPLIST_FILE = "love-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks"; LLVM_LTO = YES; MACOSX_DEPLOYMENT_TARGET = 10.13; From ddbf64d3b7b412d5f514d21378fa7592268930a0 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sun, 7 Jan 2024 21:40:14 -0400 Subject: [PATCH 19/29] Linux: build using C++17? --- platform/unix/configure.ac | 4 +-- platform/unix/cpp14.m4 | 52 +++++++++++++++++++------------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/platform/unix/configure.ac b/platform/unix/configure.ac index b04c5a1ec..52b778fb0 100644 --- a/platform/unix/configure.ac +++ b/platform/unix/configure.ac @@ -26,8 +26,8 @@ includes= AC_DEFUN([LOVE_MSG_ERROR], [AC_MSG_ERROR([LÖVE needs "$1"[,] please install "$1" with development files and try again])]) -# C++14 support in cpp14.m4 -ACLOVE_CPP14_TEST +# C++17 support in cpp14.m4 +ACLOVE_CPP17_TEST # Add -fvisibility=hidden and -fvisibility-inlines-hidden CFLAGS="-fvisibility=hidden $CFLAGS" diff --git a/platform/unix/cpp14.m4 b/platform/unix/cpp14.m4 index 42a884ecd..2b11023ea 100644 --- a/platform/unix/cpp14.m4 +++ b/platform/unix/cpp14.m4 @@ -22,47 +22,47 @@ AC_DEFUN([ACLOVE_GET_CLANG_VERSION], [ AC_COMPUTE_INT(aclove_clang_version_patch, __clang_patchlevel__,, aclove_clang_version_found="no") ]) -AC_DEFUN([ACLOVE_CPP14_TEST_FLAG], [ - aclove_cpp14_test_cxx14name="no" - ACLOVE_CXX_FLAG_TEST([-std=c++14], aclove_cpp14_test_cxx14name="c++14", []) - AS_VAR_IF([aclove_cpp14_test_cxx14name], [no], - [AC_MSG_ERROR([LÖVE needs a C++ compiler with C++14 support])], - [CXXFLAGS="$CXXFLAGS -std=$aclove_cpp14_test_cxx14name"]) +AC_DEFUN([ACLOVE_CPP17_TEST_FLAG], [ + aclove_cpp17_test_cxx17name="no" + ACLOVE_CXX_FLAG_TEST([-std=c++17], aclove_cpp17_test_cxx14name="c++17", []) + AS_VAR_IF([aclove_cpp17_test_cxx17name], [no], + [AC_MSG_ERROR([LÖVE needs a C++ compiler with C++17 support])], + [CXXFLAGS="$CXXFLAGS -std=$aclove_cpp17_test_cxx17name"]) ]) -AC_DEFUN([ACLOVE_CPP14_CHECK_VERSION], [ dnl compiler, targetmajor, targetminor, on-failure - aclove_cpp14_check_version_status="no" +AC_DEFUN([ACLOVE_CPP17_CHECK_VERSION], [ dnl compiler, targetmajor, targetminor, on-failure + aclove_cpp17_check_version_status="no" AC_MSG_CHECKING([whether $1 version is at least $2.$3]) - AS_IF([test "$aclove_[]$1[]_version_major" -gt $2], aclove_cpp14_check_version_status="yes") - AS_IF([test "$aclove_[]$1[]_version_major" -eq $2 && test "$aclove_[]$1[]_version_minor" -ge $3], aclove_cpp14_check_version_status="yes") - AC_MSG_RESULT([$aclove_cpp14_check_version_status]) - AS_VAR_IF([aclove_cpp14_check_version_status], [no], + AS_IF([test "$aclove_[]$1[]_version_major" -gt $2], aclove_cpp17_check_version_status="yes") + AS_IF([test "$aclove_[]$1[]_version_major" -eq $2 && test "$aclove_[]$1[]_version_minor" -ge $3], aclove_cpp17_check_version_status="yes") + AC_MSG_RESULT([$aclove_cpp17_check_version_status]) + AS_VAR_IF([aclove_cpp17_check_version_status], [no], [$4]) ]) -AC_DEFUN([ACLOVE_CPP14_TEST_VERSION_GCC], [ - ACLOVE_CPP14_CHECK_VERSION([gcc], 4, 9, - [AC_MSG_ERROR([LÖVE needs a GCC version of at least 4.9])]) +AC_DEFUN([ACLOVE_CPP17_TEST_VERSION_GCC], [ + ACLOVE_CPP17_CHECK_VERSION([gcc], 9, 0, + [AC_MSG_ERROR([LÖVE needs a GCC version of at least 9.0])]) ]) -AC_DEFUN([ACLOVE_CPP14_TEST_VERSION_CLANG], [ - ACLOVE_CPP14_CHECK_VERSION([clang], 3, 4, - [AC_MSG_ERROR([LÖVE needs a clang version of at least 3.4])]) +AC_DEFUN([ACLOVE_CPP17_TEST_VERSION_CLANG], [ + ACLOVE_CPP17_CHECK_VERSION([clang], 5, 0, + [AC_MSG_ERROR([LÖVE needs a clang version of at least 5.0])]) ]) -AC_DEFUN([ACLOVE_CPP14_TEST], [ - ACLOVE_CPP14_TEST_FLAG +AC_DEFUN([ACLOVE_CPP17_TEST], [ + ACLOVE_CPP17_TEST_FLAG ACLOVE_GET_GCC_VERSION ACLOVE_GET_CLANG_VERSION # Since clang also sets gcc headers, check clang after - aclove_cpp14_test_compiler="unknown" - AS_VAR_IF([aclove_gcc_version_found], [yes], aclove_cpp14_test_compiler="gcc") - AS_VAR_IF([aclove_clang_version_found], [yes], aclove_cpp14_test_compiler="clang") + aclove_cpp17_test_compiler="unknown" + AS_VAR_IF([aclove_gcc_version_found], [yes], aclove_cpp17_test_compiler="gcc") + AS_VAR_IF([aclove_clang_version_found], [yes], aclove_cpp17_test_compiler="clang") - AS_CASE([$aclove_cpp14_test_compiler], - [gcc], [ACLOVE_CPP14_TEST_VERSION_GCC], - [clang], [ACLOVE_CPP14_TEST_VERSION_CLANG], + AS_CASE([$aclove_cpp17_test_compiler], + [gcc], [ACLOVE_CPP17_TEST_VERSION_GCC], + [clang], [ACLOVE_CPP17_TEST_VERSION_CLANG], [AC_MSG_WARN([Could not determine compiler version])]) ]) From 715858a670824ba7eab537b565d95bd08a13ac0d Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sun, 7 Jan 2024 21:46:51 -0400 Subject: [PATCH 20/29] Fix typo --- platform/unix/cpp14.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/unix/cpp14.m4 b/platform/unix/cpp14.m4 index 2b11023ea..7f5f3a5b0 100644 --- a/platform/unix/cpp14.m4 +++ b/platform/unix/cpp14.m4 @@ -24,7 +24,7 @@ AC_DEFUN([ACLOVE_GET_CLANG_VERSION], [ AC_DEFUN([ACLOVE_CPP17_TEST_FLAG], [ aclove_cpp17_test_cxx17name="no" - ACLOVE_CXX_FLAG_TEST([-std=c++17], aclove_cpp17_test_cxx14name="c++17", []) + ACLOVE_CXX_FLAG_TEST([-std=c++17], aclove_cpp17_test_cxx17name="c++17", []) AS_VAR_IF([aclove_cpp17_test_cxx17name], [no], [AC_MSG_ERROR([LÖVE needs a C++ compiler with C++17 support])], [CXXFLAGS="$CXXFLAGS -std=$aclove_cpp17_test_cxx17name"]) From 95fdc1c899f612fd3e404693fe4334a7dd3da61f Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sun, 7 Jan 2024 21:58:29 -0400 Subject: [PATCH 21/29] Linux: don't try to build web glslang files --- platform/unix/exclude | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/unix/exclude b/platform/unix/exclude index 95b2573eb..083619d50 100644 --- a/platform/unix/exclude +++ b/platform/unix/exclude @@ -1,3 +1,4 @@ \./libraries/luasocket/libluasocket/wsocket.* \./love\.cpp \./libraries/glslang/glslang/OSDependent/Windows +\./libraries/glslang/glslang/OSDependent/Web From ecd9b007aa06dc988ed3f5de19c128e143ba73f4 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sun, 7 Jan 2024 22:00:50 -0400 Subject: [PATCH 22/29] Fix building vulkan Shader.cpp --- src/modules/graphics/vulkan/Shader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/modules/graphics/vulkan/Shader.cpp b/src/modules/graphics/vulkan/Shader.cpp index c21e7f12f..364ab6f0b 100644 --- a/src/modules/graphics/vulkan/Shader.cpp +++ b/src/modules/graphics/vulkan/Shader.cpp @@ -26,6 +26,7 @@ #include "libraries/glslang/glslang/Public/ResourceLimits.h" #include "libraries/glslang/SPIRV/GlslangToSpv.h" +#include namespace love { From 6feedc8222e8e741ba047e921af90bcf57a23cda Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Mon, 8 Jan 2024 21:09:40 -0400 Subject: [PATCH 23/29] Add love.window.getPointer, returns a SDL_Window* as lightuserdata. --- src/modules/window/Window.h | 2 +- src/modules/window/sdl/Window.cpp | 2 +- src/modules/window/sdl/Window.h | 2 +- src/modules/window/wrap_Window.cpp | 7 +++++++ 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/modules/window/Window.h b/src/modules/window/Window.h index 9676dd455..3a53cba79 100644 --- a/src/modules/window/Window.h +++ b/src/modules/window/Window.h @@ -217,7 +217,7 @@ class Window : public Module virtual double fromPixels(double x) const = 0; virtual void fromPixels(double px, double py, double &wx, double &wy) const = 0; - virtual const void *getHandle() const = 0; + virtual void *getHandle() const = 0; virtual bool showMessageBox(const std::string &title, const std::string &message, MessageBoxType type, bool attachtowindow) = 0; virtual int showMessageBox(const MessageBoxData &data) = 0; diff --git a/src/modules/window/sdl/Window.cpp b/src/modules/window/sdl/Window.cpp index 5205bcd7e..fa8be97d0 100644 --- a/src/modules/window/sdl/Window.cpp +++ b/src/modules/window/sdl/Window.cpp @@ -1405,7 +1405,7 @@ void Window::fromPixels(double px, double py, double &wx, double &wy) const wy = py / scale; } -const void *Window::getHandle() const +void *Window::getHandle() const { return window; } diff --git a/src/modules/window/sdl/Window.h b/src/modules/window/sdl/Window.h index d97dbd38a..fd006958a 100644 --- a/src/modules/window/sdl/Window.h +++ b/src/modules/window/sdl/Window.h @@ -123,7 +123,7 @@ class Window final : public love::window::Window double fromPixels(double x) const override; void fromPixels(double px, double py, double &wx, double &wy) const override; - const void *getHandle() const override; + void *getHandle() const override; bool showMessageBox(const std::string &title, const std::string &message, MessageBoxType type, bool attachtowindow) override; int showMessageBox(const MessageBoxData &data) override; diff --git a/src/modules/window/wrap_Window.cpp b/src/modules/window/wrap_Window.cpp index 60aea2993..cc1bd3bd1 100644 --- a/src/modules/window/wrap_Window.cpp +++ b/src/modules/window/wrap_Window.cpp @@ -647,6 +647,12 @@ int w_requestAttention(lua_State *L) return 0; } +int w_getPointer(lua_State *L) +{ + lua_pushlightuserdata(L, instance()->getHandle()); + return 1; +} + static const luaL_Reg functions[] = { { "getDisplayCount", w_getDisplayCount }, @@ -688,6 +694,7 @@ static const luaL_Reg functions[] = { "isMinimized", w_isMinimized }, { "showMessageBox", w_showMessageBox }, { "requestAttention", w_requestAttention }, + { "getPointer", w_getPointer }, { 0, 0 } }; From 3e8345280fd7891a037b0806a2a3a254708d0e9b Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Mon, 8 Jan 2024 22:13:47 -0400 Subject: [PATCH 24/29] Move default texel and shader storage buffers to high level code. --- src/modules/graphics/Graphics.cpp | 60 ++++++++++++++++++++++++ src/modules/graphics/Graphics.h | 4 ++ src/modules/graphics/opengl/Graphics.cpp | 38 --------------- src/modules/graphics/opengl/Graphics.h | 3 -- src/modules/graphics/opengl/OpenGL.h | 12 ----- src/modules/graphics/opengl/Shader.cpp | 43 +++++++---------- 6 files changed, 81 insertions(+), 79 deletions(-) diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 44b196a44..0cf3eb139 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -589,6 +589,55 @@ Texture *Graphics::getDefaultTexture(TextureType type, DataBaseType dataType) return tex; } +Buffer *Graphics::getDefaultTexelBuffer(DataBaseType dataType) +{ + Buffer *buffer = defaultTexelBuffers[dataType]; + if (buffer != nullptr) + return buffer; + + Buffer::Settings settings(BUFFERUSAGEFLAG_TEXEL, BUFFERDATAUSAGE_STATIC); + settings.zeroInitialize = true; + settings.debugName = "default_texelbuffer_"; + + DataFormat format = DATAFORMAT_FLOAT; + switch (dataType) + { + case DATA_BASETYPE_FLOAT: + default: + format = DATAFORMAT_FLOAT; + settings.debugName += "float"; + break; + case DATA_BASETYPE_INT: + format = DATAFORMAT_INT32; + settings.debugName += "int"; + break; + case DATA_BASETYPE_UINT: + format = DATAFORMAT_UINT32; + settings.debugName += "uint"; + break; + } + + buffer = newBuffer(settings, format, nullptr, sizeof(float), 1); + + defaultTexelBuffers[dataType] = buffer; + + return buffer; +} + +Buffer *Graphics::getDefaultStorageBuffer() +{ + if (defaultStorageBuffer != nullptr) + return defaultStorageBuffer; + + Buffer::Settings settings(BUFFERUSAGEFLAG_SHADER_STORAGE, BUFFERDATAUSAGE_STATIC); + settings.zeroInitialize = true; + settings.debugName = "default_storagebuffer"; + + defaultStorageBuffer = newBuffer(settings, DATAFORMAT_FLOAT, nullptr, Buffer::SHADER_STORAGE_BUFFER_MAX_STRIDE, 0); + + return defaultStorageBuffer; +} + void Graphics::releaseDefaultResources() { for (int type = 0; type < TEXTURE_MAX_ENUM; type++) @@ -600,6 +649,17 @@ void Graphics::releaseDefaultResources() defaultTextures[type][dataType] = nullptr; } } + + for (int dataType = 0; dataType < DATA_BASETYPE_MAX_ENUM; dataType++) + { + if (defaultTexelBuffers[dataType]) + defaultTexelBuffers[dataType]->release(); + defaultTexelBuffers[dataType] = nullptr; + } + + if (defaultStorageBuffer) + defaultStorageBuffer->release(); + defaultStorageBuffer = nullptr; } Texture *Graphics::getTextureOrDefaultForActiveShader(Texture *tex) diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index 4a2c92b9c..1968da453 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -488,6 +488,8 @@ class Graphics : public Module bool validateShader(bool gles, const std::vector &stages, const Shader::CompileOptions &options, std::string &err); Texture *getDefaultTexture(TextureType type, DataBaseType dataType); + Buffer *getDefaultTexelBuffer(DataBaseType dataType); + Buffer *getDefaultStorageBuffer(); Texture *getTextureOrDefaultForActiveShader(Texture *tex); /** @@ -1111,6 +1113,8 @@ class Graphics : public Module int calculateEllipsePoints(float rx, float ry) const; Texture *defaultTextures[TEXTURE_MAX_ENUM][DATA_BASETYPE_MAX_ENUM]; + Buffer *defaultTexelBuffers[DATA_BASETYPE_MAX_ENUM]; + Buffer *defaultStorageBuffer; std::vector scratchBuffer; diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index f6ff52205..9013ee808 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -112,7 +112,6 @@ Graphics::Graphics() , requestedBackbufferMSAA(0) , bufferMapMemory(nullptr) , bufferMapMemorySize(2 * 1024 * 1024) - , defaultBuffers() , pixelFormatUsage() { gl = OpenGL(); @@ -384,43 +383,6 @@ bool Graphics::setMode(void */*context*/, int width, int height, int pixelwidth, batchedDrawState.indexBuffer = CreateStreamBuffer(BUFFERUSAGE_INDEX, sizeof(uint16) * LOVE_UINT16_MAX); } - // TODO: one buffer each for float, int, uint - if (capabilities.features[FEATURE_TEXEL_BUFFER] && defaultBuffers[BUFFERUSAGE_TEXEL].get() == nullptr) - { - Buffer::Settings settings(BUFFERUSAGEFLAG_TEXEL, BUFFERDATAUSAGE_STATIC); - std::vector format = {{"", DATAFORMAT_FLOAT_VEC4, 0}}; - - const float texel[] = {0.0f, 0.0f, 0.0f, 1.0f}; - - auto buffer = newBuffer(settings, format, texel, sizeof(texel), 1); - defaultBuffers[BUFFERUSAGE_TEXEL].set(buffer, Acquire::NORETAIN); - } - - if (capabilities.features[FEATURE_GLSL4] && defaultBuffers[BUFFERUSAGE_SHADER_STORAGE].get() == nullptr) - { - Buffer::Settings settings(BUFFERUSAGEFLAG_SHADER_STORAGE, BUFFERDATAUSAGE_STATIC); - std::vector format = {{"", DATAFORMAT_FLOAT, 0}}; - - std::vector data; - data.resize(Buffer::SHADER_STORAGE_BUFFER_MAX_STRIDE / 4); - - auto buffer = newBuffer(settings, format, data.data(), data.size() * sizeof(float), data.size()); - defaultBuffers[BUFFERUSAGE_SHADER_STORAGE].set(buffer, Acquire::NORETAIN); - } - - // Load default resources before other Volatile. - for (int i = 0; i < BUFFERUSAGE_MAX_ENUM; i++) - { - if (defaultBuffers[i].get()) - ((Buffer *) defaultBuffers[i].get())->loadVolatile(); - } - - if (defaultBuffers[BUFFERUSAGE_TEXEL].get()) - gl.setDefaultTexelBuffer((GLuint) defaultBuffers[BUFFERUSAGE_TEXEL]->getTexelBufferHandle()); - - if (defaultBuffers[BUFFERUSAGE_SHADER_STORAGE].get()) - gl.setDefaultStorageBuffer((GLuint) defaultBuffers[BUFFERUSAGE_SHADER_STORAGE]->getHandle()); - // Reload all volatile objects. if (!Volatile::loadAll()) ::printf("Could not reload all volatile objects.\n"); diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 7e064420e..cb39c1e81 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -173,9 +173,6 @@ class Graphics final : public love::graphics::Graphics char *bufferMapMemory; size_t bufferMapMemorySize; - // Only needed for buffer types that can be bound to shaders. - StrongRef defaultBuffers[BUFFERUSAGE_MAX_ENUM]; - // [non-readable, readable] uint32 pixelFormatUsage[PIXELFORMAT_MAX_ENUM][2]; diff --git a/src/modules/graphics/opengl/OpenGL.h b/src/modules/graphics/opengl/OpenGL.h index 32f2bf8c1..6aa6a5337 100644 --- a/src/modules/graphics/opengl/OpenGL.h +++ b/src/modules/graphics/opengl/OpenGL.h @@ -330,15 +330,6 @@ class OpenGL **/ GLuint getDefaultFBO() const; - /** - * Gets the texture ID for love's default texel buffer. - **/ - GLuint getDefaultTexelBuffer() const { return state.defaultTexelBuffer; } - void setDefaultTexelBuffer(GLuint tex) { state.defaultTexelBuffer = tex; } - - GLuint getDefaultStorageBuffer() const { return state.defaultStorageBuffer; } - void setDefaultStorageBuffer(GLuint buf) { state.defaultStorageBuffer = buf; } - /** * Helper for setting the active texture unit. * @@ -544,9 +535,6 @@ class OpenGL GLuint boundFramebuffers[2]; - GLuint defaultTexelBuffer; - GLuint defaultStorageBuffer; - } state; }; // OpenGL diff --git a/src/modules/graphics/opengl/Shader.cpp b/src/modules/graphics/opengl/Shader.cpp index e99642d99..d1fd38209 100644 --- a/src/modules/graphics/opengl/Shader.cpp +++ b/src/modules/graphics/opengl/Shader.cpp @@ -149,17 +149,8 @@ void Shader::mapActiveUniforms() TextureUnit unit; unit.type = u.textureType; unit.active = true; - - if (u.baseType == UNIFORM_TEXELBUFFER) - { - unit.isTexelBuffer = true; - unit.texture = gl.getDefaultTexelBuffer(); - } - else - { - unit.isTexelBuffer = false; - unit.texture = 0; // Handled below. - } + unit.texture = 0; // Handled below. + unit.isTexelBuffer = u.baseType == UNIFORM_TEXELBUFFER; for (int i = 0; i < u.count; i++) textureUnits.push_back(unit); @@ -414,7 +405,7 @@ void Shader::mapActiveUniforms() BufferBinding binding; binding.bindingindex = u.ints[0]; - binding.buffer = gl.getDefaultStorageBuffer(); + binding.buffer = 0; if (binding.bindingindex >= 0) { @@ -867,13 +858,23 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe for (int i = 0; i < count; i++) { love::graphics::Buffer *buffer = buffers[i]; + bool isdefault = buffer != nullptr; if (buffer != nullptr) { if (!validateBuffer(info, buffer, internalUpdate)) continue; - buffer->retain(); } + else + { + auto gfx = Module::getInstance(Module::M_GRAPHICS); + if (texelbinding) + buffer = gfx->getDefaultTexelBuffer(info->dataBaseType); + else + buffer = gfx->getDefaultStorageBuffer(); + } + + buffer->retain(); if (info->buffers[i] != nullptr) info->buffers[i]->release(); @@ -882,12 +883,7 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe if (texelbinding) { - GLuint gltex = 0; - if (buffer != nullptr) - gltex = (GLuint) buffer->getTexelBufferHandle(); - else - gltex = gl.getDefaultTexelBuffer(); - + GLuint gltex = (GLuint) buffer->getTexelBufferHandle(); int texunit = info->ints[i]; if (shaderactive) @@ -898,14 +894,9 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe } else if (storagebinding) { + GLuint glbuffer = (GLuint)buffer->getHandle(); int bindingindex = info->ints[i]; - GLuint glbuffer = 0; - if (buffer != nullptr) - glbuffer = (GLuint) buffer->getHandle(); - else - glbuffer = gl.getDefaultStorageBuffer(); - if (shaderactive) gl.bindIndexedBuffer(glbuffer, BUFFERUSAGE_SHADER_STORAGE, bindingindex); @@ -915,7 +906,7 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe activeStorageBufferBindings[activeindex.first].buffer = glbuffer; if (activeindex.second >= 0) - activeWritableStorageBuffers[activeindex.second] = buffer; + activeWritableStorageBuffers[activeindex.second] = isdefault ? nullptr : buffer; } } } From 8bf04df6e15b5200adebf8bc67f86ad5396b4b22 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Mon, 8 Jan 2024 22:31:06 -0400 Subject: [PATCH 25/29] Fix uninitialized pointers leading to crashes --- src/modules/graphics/Graphics.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 0cf3eb139..d22da3338 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -198,6 +198,8 @@ Graphics::Graphics() , fanIndexBuffer(nullptr) , capabilities() , defaultTextures() + , defaultTexelBuffers() + , defaultStorageBuffer(nullptr) , cachedShaderStages() { transformStack.reserve(16); From fb002ee59b574a82c316faec4dbbfa024044cff1 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Tue, 9 Jan 2024 21:10:20 -0400 Subject: [PATCH 26/29] opengl: fixes for default storage buffer bindings. --- src/modules/graphics/opengl/Shader.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/modules/graphics/opengl/Shader.cpp b/src/modules/graphics/opengl/Shader.cpp index d1fd38209..16b7def3d 100644 --- a/src/modules/graphics/opengl/Shader.cpp +++ b/src/modules/graphics/opengl/Shader.cpp @@ -787,6 +787,7 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex for (int i = 0; i < count; i++) { love::graphics::Texture *tex = textures[i]; + bool isdefault = tex == nullptr; if (tex != nullptr) { @@ -813,11 +814,19 @@ void Shader::sendTextures(const UniformInfo *info, love::graphics::Texture **tex int bindingindex = info->ints[i]; auto &binding = storageTextureBindings[bindingindex]; - binding.texture = tex; - binding.gltexture = gltex; + if (isdefault && (info->access & ACCESS_WRITE) != 0) + { + binding.texture = nullptr; + binding.gltexture = 0; + } + else + { + binding.texture = tex; + binding.gltexture = gltex; - if (shaderactive) - glBindImageTexture(bindingindex, binding.gltexture, 0, GL_TRUE, 0, binding.access, binding.internalFormat); + if (shaderactive) + glBindImageTexture(bindingindex, binding.gltexture, 0, GL_TRUE, 0, binding.access, binding.internalFormat); + } } else { @@ -858,7 +867,7 @@ void Shader::sendBuffers(const UniformInfo *info, love::graphics::Buffer **buffe for (int i = 0; i < count; i++) { love::graphics::Buffer *buffer = buffers[i]; - bool isdefault = buffer != nullptr; + bool isdefault = buffer == nullptr; if (buffer != nullptr) { From 7ff6f74a92e53f0256b2bf42b0165281ebc9f002 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Tue, 9 Jan 2024 21:11:04 -0400 Subject: [PATCH 27/29] metal: improve shader resource binding code. --- src/modules/graphics/metal/Graphics.mm | 2 +- src/modules/graphics/metal/Shader.mm | 102 +++++++++++++++---------- 2 files changed, 62 insertions(+), 42 deletions(-) diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index 98dfd1c24..518cdbe8f 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -1063,7 +1063,7 @@ static bool isClampOne(SamplerState::WrapMode w) if ((b.access & Shader::ACCESS_WRITE) != 0 && texture == nil) allWritableVariablesSet = false; } - + if (sampindex != LOVE_UINT8_MAX) setSampler(encoder, bindings, sampindex, samplertex); } diff --git a/src/modules/graphics/metal/Shader.mm b/src/modules/graphics/metal/Shader.mm index 2984ed1b6..c6457527f 100644 --- a/src/modules/graphics/metal/Shader.mm +++ b/src/modules/graphics/metal/Shader.mm @@ -390,20 +390,24 @@ static EShLanguage getGLSLangStage(ShaderStageType stage) case spv::Dim2D: u.textureType = basetype.image.arrayed ? TEXTURE_2D_ARRAY : TEXTURE_2D; u.textures = new love::graphics::Texture*[u.count]; + memset(u.textures, 0, sizeof(love::graphics::Texture *) * u.count); break; case spv::Dim3D: u.textureType = TEXTURE_VOLUME; u.textures = new love::graphics::Texture*[u.count]; + memset(u.textures, 0, sizeof(love::graphics::Texture *) * u.count); break; case spv::DimCube: if (basetype.image.arrayed) throw love::Exception("Cubemap Arrays are not currently supported."); u.textureType = TEXTURE_CUBE; u.textures = new love::graphics::Texture*[u.count]; + memset(u.textures, 0, sizeof(love::graphics::Texture *) * u.count); break; case spv::DimBuffer: u.baseType = UNIFORM_TEXELBUFFER; u.buffers = new love::graphics::Buffer*[u.count]; + memset(u.buffers, 0, sizeof(love::graphics::Buffer *) * u.count); break; default: // TODO: error? continue? @@ -415,33 +419,6 @@ static EShLanguage getGLSLangStage(ShaderStageType stage) for (int i = 0; i < u.count; i++) u.ints[i] = -1; // Initialized below, after compiling. - if (u.baseType == UNIFORM_SAMPLER) - { - auto tex = Graphics::getInstance()->getDefaultTexture(u.textureType, u.dataBaseType); - for (int i = 0; i < u.count; i++) - { - tex->retain(); - u.textures[i] = tex; - } - } - else if (u.baseType == UNIFORM_TEXELBUFFER) - { - for (int i = 0; i < u.count; i++) - u.buffers[i] = nullptr; // TODO - } - else if (u.baseType == UNIFORM_STORAGETEXTURE) - { - Texture *tex = nullptr; - if ((u.access & ACCESS_WRITE) == 0) - tex = Graphics::getInstance()->getDefaultTexture(u.textureType, u.dataBaseType); - for (int i = 0; i < u.count; i++) - { - if (tex) - tex->retain(); - u.textures[i] = tex; - } - } - uniforms[u.name] = u; BuiltinUniform builtin; @@ -571,7 +548,7 @@ static EShLanguage getGLSLangStage(ShaderStageType stage) for (int i = 0; i < u.count; i++) { u.ints[i] = -1; // Initialized below, after compiling. - u.buffers[i] = nullptr; // TODO + u.buffers[i] = nullptr; } uniforms[u.name] = u; @@ -668,7 +645,11 @@ static EShLanguage getGLSLangStage(ShaderStageType stage) uint32 samplerbinding = msl.get_automatic_msl_resource_binding_secondary(resource.id); if (texturebinding == (uint32)-1) + { + // No valid binding, the uniform was likely optimized out because it's not used. + uniforms.erase(resource.name); return; + } for (int i = 0; i < u.count; i++) { @@ -678,15 +659,8 @@ static EShLanguage getGLSLangStage(ShaderStageType stage) TextureBinding b = {}; b.access = u.access; - if (u.baseType == UNIFORM_TEXELBUFFER) + if (u.baseType == UNIFORM_SAMPLER) { - // TODO - } - else - { - b.texture = getMTLTexture(u.textures[i]); - b.samplerTexture = u.textures[i]; - BuiltinUniform builtin = BUILTIN_MAX_ENUM; if (getConstant(u.name.c_str(), builtin) && builtin == BUILTIN_TEXTURE_MAIN) b.isMainTexture = true; @@ -726,7 +700,11 @@ static EShLanguage getGLSLangStage(ShaderStageType stage) uint32 bufferbinding = msl.get_automatic_msl_resource_binding(resource.id); if (bufferbinding == (uint32)-1) + { + // No valid binding, the uniform was likely optimized out because it's not used. + uniforms.erase(resource.name); continue; + } for (int i = 0; i < u.count; i++) { @@ -752,6 +730,25 @@ static EShLanguage getGLSLangStage(ShaderStageType stage) } } + // Initialize default resource bindings. + for (auto &kvp : uniforms) + { + UniformInfo &info = kvp.second; + switch (info.baseType) + { + case UNIFORM_SAMPLER: + case UNIFORM_STORAGETEXTURE: + sendTextures(&info, info.textures, info.count); + break; + case UNIFORM_TEXELBUFFER: + case UNIFORM_STORAGEBUFFER: + sendBuffers(&info, info.buffers, info.count); + break; + default: + break; + } + } + firstVertexBufferBinding = metalBufferIndices[SHADERSTAGE_VERTEX]; } @@ -878,6 +875,7 @@ static EShLanguage getGLSLangStage(ShaderStageType stage) for (int i = 0; i < count; i++) { love::graphics::Texture *tex = textures[i]; + bool isdefault = tex == nullptr; if (tex != nullptr) { @@ -897,8 +895,17 @@ static EShLanguage getGLSLangStage(ShaderStageType stage) info->textures[i] = tex; - textureBindings[info->ints[i]].texture = getMTLTexture(tex); - textureBindings[info->ints[i]].samplerTexture = tex; + auto &binding = textureBindings[info->ints[i]]; + if (isdefault && (binding.access & ACCESS_WRITE) != 0) + { + binding.texture = nil; + binding.samplerTexture = nullptr; + } + else + { + binding.texture = getMTLTexture(tex); + binding.samplerTexture = tex; + } } }} @@ -919,14 +926,24 @@ static EShLanguage getGLSLangStage(ShaderStageType stage) for (int i = 0; i < count; i++) { love::graphics::Buffer *buffer = buffers[i]; + bool isdefault = buffer == nullptr; if (buffer != nullptr) { if (!validateBuffer(info, buffer, false)) continue; - buffer->retain(); + } + else + { + auto gfx = Graphics::getInstance(); + if (texelbinding) + buffer = gfx->getDefaultTexelBuffer(info->dataBaseType); + else + buffer = gfx->getDefaultStorageBuffer(); } + buffer->retain(); + if (info->buffers[i] != nullptr) info->buffers[i]->release(); @@ -938,8 +955,11 @@ static EShLanguage getGLSLangStage(ShaderStageType stage) } else if (storagebinding) { - // TODO - bufferBindings[info->ints[i]].buffer = getMTLBuffer(buffer); + auto &binding = bufferBindings[info->ints[i]]; + if (isdefault && (binding.access & ACCESS_WRITE) != 0) + binding.buffer = nil; + else + binding.buffer = getMTLBuffer(buffer); } } } From bf6a6f123743080f15be1da3f8450066f9cfda85 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Tue, 9 Jan 2024 21:29:54 -0400 Subject: [PATCH 28/29] metal: error when generated SPIR-V shader IR can't be parsed --- src/modules/graphics/metal/Shader.mm | 405 ++++++++++++++------------- 1 file changed, 205 insertions(+), 200 deletions(-) diff --git a/src/modules/graphics/metal/Shader.mm b/src/modules/graphics/metal/Shader.mm index c6457527f..c421c2330 100644 --- a/src/modules/graphics/metal/Shader.mm +++ b/src/modules/graphics/metal/Shader.mm @@ -30,6 +30,7 @@ #include "libraries/spirv_cross/spirv_reflect.hpp" #include +#include namespace love { @@ -456,278 +457,282 @@ static EShLanguage getGLSLangStage(ShaderStageType stage) std::string msgs = logger.getAllMessages(); // printf("spirv length: %ld, messages:\n%s\n", spirv.size(), msgs.c_str()); +// printf("GLSL INPUT SOURCE:\n\n%s\n\n", pixel->getSource().c_str()); + + std::unique_ptr mslpointer; + try { -// printf("GLSL INPUT SOURCE:\n\n%s\n\n", pixel->getSource().c_str()); + mslpointer.reset(new CompilerMSL(std::move(spirv))); + } + catch (std::exception &e) + { + throw love::Exception("Error parsing SPIR-V shader source: %s", e.what()); + } - CompilerMSL msl(std::move(spirv)); + auto &msl = *mslpointer; - auto interfacevars = msl.get_active_interface_variables(); + auto interfacevars = msl.get_active_interface_variables(); - msl.set_enabled_interface_variables(interfacevars); + msl.set_enabled_interface_variables(interfacevars); - ShaderResources resources = msl.get_shader_resources(); + ShaderResources resources = msl.get_shader_resources(); - for (const auto &resource : resources.storage_images) - { - addImage(msl, resource, UNIFORM_STORAGETEXTURE); - } + for (const auto &resource : resources.storage_images) + { + addImage(msl, resource, UNIFORM_STORAGETEXTURE); + } - for (const auto &resource : resources.sampled_images) - { - addImage(msl, resource, UNIFORM_SAMPLER); - } + for (const auto &resource : resources.sampled_images) + { + addImage(msl, resource, UNIFORM_SAMPLER); + } - for (const auto &resource : resources.uniform_buffers) - { - MSLResourceBinding binding; - binding.stage = msl.get_execution_model(); - binding.binding = msl.get_decoration(resource.id, spv::DecorationBinding); - binding.desc_set = msl.get_decoration(resource.id, spv::DecorationDescriptorSet); + for (const auto &resource : resources.uniform_buffers) + { + MSLResourceBinding binding; + binding.stage = msl.get_execution_model(); + binding.binding = msl.get_decoration(resource.id, spv::DecorationBinding); + binding.desc_set = msl.get_decoration(resource.id, spv::DecorationDescriptorSet); - if (resource.name == "gl_DefaultUniformBlock") - { - binding.msl_buffer = getUniformBufferBinding(); - msl.add_msl_resource_binding(binding); + if (resource.name == "gl_DefaultUniformBlock") + { + binding.msl_buffer = getUniformBufferBinding(); + msl.add_msl_resource_binding(binding); - const SPIRType &type = msl.get_type(resource.base_type_id); - size_t size = msl.get_declared_struct_size(type); + const SPIRType &type = msl.get_type(resource.base_type_id); + size_t size = msl.get_declared_struct_size(type); - if (localUniformBufferSize != 0) - { - if (localUniformBufferSize != size) - throw love::Exception("Local uniform buffer size mismatch"); - continue; - } + if (localUniformBufferSize != 0) + { + if (localUniformBufferSize != size) + throw love::Exception("Local uniform buffer size mismatch"); + continue; + } - localUniformStagingData = new uint8[size]; - localUniformBufferData = new uint8[size]; - localUniformBufferSize = size; + localUniformStagingData = new uint8[size]; + localUniformBufferData = new uint8[size]; + localUniformBufferSize = size; - memset(localUniformStagingData, 0, size); - memset(localUniformBufferData, 0, size); + memset(localUniformStagingData, 0, size); + memset(localUniformBufferData, 0, size); - std::string basename(""); - buildLocalUniforms(msl, type, 0, basename); - } - else - { - binding.msl_buffer = metalBufferIndices[stageindex]++; - msl.add_msl_resource_binding(binding); - } + std::string basename(""); + buildLocalUniforms(msl, type, 0, basename); } - - for (const auto &resource : resources.storage_buffers) + else { - MSLResourceBinding binding; - binding.stage = msl.get_execution_model(); - binding.binding = msl.get_decoration(resource.id, spv::DecorationBinding); - binding.desc_set = msl.get_decoration(resource.id, spv::DecorationDescriptorSet); binding.msl_buffer = metalBufferIndices[stageindex]++; msl.add_msl_resource_binding(binding); + } + } - auto it = uniforms.find(resource.name); - if (it != uniforms.end()) - continue; + for (const auto &resource : resources.storage_buffers) + { + MSLResourceBinding binding; + binding.stage = msl.get_execution_model(); + binding.binding = msl.get_decoration(resource.id, spv::DecorationBinding); + binding.desc_set = msl.get_decoration(resource.id, spv::DecorationDescriptorSet); + binding.msl_buffer = metalBufferIndices[stageindex]++; + msl.add_msl_resource_binding(binding); + + auto it = uniforms.find(resource.name); + if (it != uniforms.end()) + continue; - const SPIRType &type = msl.get_type(resource.type_id); + const SPIRType &type = msl.get_type(resource.type_id); - UniformInfo u = {}; - u.baseType = UNIFORM_STORAGEBUFFER; - u.components = 1; - u.name = resource.name; - u.count = type.array.empty() ? 1 : type.array[0]; + UniformInfo u = {}; + u.baseType = UNIFORM_STORAGEBUFFER; + u.components = 1; + u.name = resource.name; + u.count = type.array.empty() ? 1 : type.array[0]; - if (!fillUniformReflectionData(u)) - continue; + if (!fillUniformReflectionData(u)) + continue; - u.buffers = new love::graphics::Buffer*[u.count]; - u.dataSize = sizeof(int) * u.count; - u.data = malloc(u.dataSize); + u.buffers = new love::graphics::Buffer*[u.count]; + u.dataSize = sizeof(int) * u.count; + u.data = malloc(u.dataSize); - for (int i = 0; i < u.count; i++) - { - u.ints[i] = -1; // Initialized below, after compiling. - u.buffers[i] = nullptr; - } - - uniforms[u.name] = u; + for (int i = 0; i < u.count; i++) + { + u.ints[i] = -1; // Initialized below, after compiling. + u.buffers[i] = nullptr; } - if (stageindex == SHADERSTAGE_VERTEX) + uniforms[u.name] = u; + } + + if (stageindex == SHADERSTAGE_VERTEX) + { + int nextattributeindex = ATTRIB_MAX_ENUM; + + for (const auto &var : interfacevars) { - int nextattributeindex = ATTRIB_MAX_ENUM; + spv::StorageClass storage = msl.get_storage_class(var); + const std::string &name = msl.get_name(var); - for (const auto &var : interfacevars) + if (storage == spv::StorageClassInput) { - spv::StorageClass storage = msl.get_storage_class(var); - const std::string &name = msl.get_name(var); - - if (storage == spv::StorageClassInput) - { - int index = 0; + int index = 0; - BuiltinVertexAttribute builtinattribute; - if (graphics::getConstant(name.c_str(), builtinattribute)) - index = (int) builtinattribute; - else - index = nextattributeindex++; + BuiltinVertexAttribute builtinattribute; + if (graphics::getConstant(name.c_str(), builtinattribute)) + index = (int) builtinattribute; + else + index = nextattributeindex++; - msl.set_decoration(var, spv::DecorationLocation, index); - attributes[name] = msl.get_decoration(var, spv::DecorationLocation); - } + msl.set_decoration(var, spv::DecorationLocation, index); + attributes[name] = msl.get_decoration(var, spv::DecorationLocation); } + } - for (const auto &varying : resources.stage_outputs) - { -// printf("vertex shader output %s: %d\n", inp.name.c_str(), msl.get_decoration(inp.id, spv::DecorationLocation)); - varyings[varying.name] = nextVaryingLocation; - msl.set_decoration(varying.id, spv::DecorationLocation, nextVaryingLocation++); - } + for (const auto &varying : resources.stage_outputs) + { +// printf("vertex shader output %s: %d\n", inp.name.c_str(), msl.get_decoration(inp.id, spv::DecorationLocation)); + varyings[varying.name] = nextVaryingLocation; + msl.set_decoration(varying.id, spv::DecorationLocation, nextVaryingLocation++); } - else if (stageindex == SHADERSTAGE_PIXEL) + } + else if (stageindex == SHADERSTAGE_PIXEL) + { + for (const auto &varying : resources.stage_inputs) { - for (const auto &varying : resources.stage_inputs) - { - const auto it = varyings.find(varying.name); - if (it != varyings.end()) - msl.set_decoration(varying.id, spv::DecorationLocation, it->second); - } + const auto it = varyings.find(varying.name); + if (it != varyings.end()) + msl.set_decoration(varying.id, spv::DecorationLocation, it->second); } + } - CompilerMSL::Options options; - options.set_msl_version(2, 1); - options.texture_buffer_native = true; + CompilerMSL::Options options; + options.set_msl_version(2, 1); + options.texture_buffer_native = true; #ifdef LOVE_IOS - options.platform = CompilerMSL::Options::iOS; + options.platform = CompilerMSL::Options::iOS; #else - options.platform = CompilerMSL::Options::macOS; + options.platform = CompilerMSL::Options::macOS; #endif - msl.set_msl_options(options); + msl.set_msl_options(options); - std::string source = msl.compile(); -// printf("// MSL SOURCE for stage %d:\n\n%s\n\n", stageindex, source.c_str()); + std::string source = msl.compile(); +// printf("// MSL SOURCE for stage %d:\n\n%s\n\n", stageindex, source.c_str()); - NSString *nssource = [[NSString alloc] initWithBytes:source.c_str() - length:source.length() - encoding:NSUTF8StringEncoding]; + NSString *nssource = [[NSString alloc] initWithBytes:source.c_str() + length:source.length() + encoding:NSUTF8StringEncoding]; - MTLCompileOptions *opts = [MTLCompileOptions new]; + MTLCompileOptions *opts = [MTLCompileOptions new]; - // Silences warning. We already only use metal on these OS versions. - if (@available(macOS 10.14, iOS 12.0, *)) - opts.languageVersion = MTLLanguageVersion2_1; + // Silences warning. We already only use metal on these OS versions. + if (@available(macOS 10.14, iOS 12.0, *)) + opts.languageVersion = MTLLanguageVersion2_1; - NSError *err = nil; - id library = [device newLibraryWithSource:nssource options:opts error:&err]; - if (library == nil && err != nil) - { - NSLog(@"errors: %@", err); - throw love::Exception("Error compiling converted Metal shader code"); - } + NSError *err = nil; + id library = [device newLibraryWithSource:nssource options:opts error:&err]; + if (library == nil && err != nil) + { + NSLog(@"errors: %@", err); + throw love::Exception("Error compiling converted Metal shader code"); + } - functions[stageindex] = [library newFunctionWithName:library.functionNames[0]]; + functions[stageindex] = [library newFunctionWithName:library.functionNames[0]]; - std::string debugname = getShaderStageDebugName((ShaderStageType)stageindex); - if (!debugname.empty()) - functions[stageindex].label = @(debugname.c_str()); + std::string debugname = getShaderStageDebugName((ShaderStageType)stageindex); + if (!debugname.empty()) + functions[stageindex].label = @(debugname.c_str()); - auto setTextureBinding = [this](CompilerMSL &msl, int stageindex, const spirv_cross::Resource &resource) -> void - { - auto it = uniforms.find(resource.name); - if (it == uniforms.end()) - return; + auto setTextureBinding = [this](CompilerMSL &msl, int stageindex, const spirv_cross::Resource &resource) -> void + { + auto it = uniforms.find(resource.name); + if (it == uniforms.end()) + return; - UniformInfo &u = it->second; + UniformInfo &u = it->second; - uint32 texturebinding = msl.get_automatic_msl_resource_binding(resource.id); - uint32 samplerbinding = msl.get_automatic_msl_resource_binding_secondary(resource.id); + uint32 texturebinding = msl.get_automatic_msl_resource_binding(resource.id); + uint32 samplerbinding = msl.get_automatic_msl_resource_binding_secondary(resource.id); - if (texturebinding == (uint32)-1) - { - // No valid binding, the uniform was likely optimized out because it's not used. - uniforms.erase(resource.name); - return; - } + if (texturebinding == (uint32)-1) + { + // No valid binding, the uniform was likely optimized out because it's not used. + uniforms.erase(resource.name); + return; + } - for (int i = 0; i < u.count; i++) + for (int i = 0; i < u.count; i++) + { + if (u.ints[i] == -1) { - if (u.ints[i] == -1) + u.ints[i] = (int)textureBindings.size(); + TextureBinding b = {}; + b.access = u.access; + + if (u.baseType == UNIFORM_SAMPLER) { - u.ints[i] = (int)textureBindings.size(); - TextureBinding b = {}; - b.access = u.access; - - if (u.baseType == UNIFORM_SAMPLER) - { - BuiltinUniform builtin = BUILTIN_MAX_ENUM; - if (getConstant(u.name.c_str(), builtin) && builtin == BUILTIN_TEXTURE_MAIN) - b.isMainTexture = true; - } - - for (uint8 &stagebinding : b.textureStages) - stagebinding = LOVE_UINT8_MAX; - for (uint8 &stagebinding : b.samplerStages) - stagebinding = LOVE_UINT8_MAX; - - textureBindings.push_back(b); + BuiltinUniform builtin = BUILTIN_MAX_ENUM; + if (getConstant(u.name.c_str(), builtin) && builtin == BUILTIN_TEXTURE_MAIN) + b.isMainTexture = true; } - auto &b = textureBindings[u.ints[i]]; - b.textureStages[stageindex] = (uint8) texturebinding; - b.samplerStages[stageindex] = (uint8) samplerbinding; + for (uint8 &stagebinding : b.textureStages) + stagebinding = LOVE_UINT8_MAX; + for (uint8 &stagebinding : b.samplerStages) + stagebinding = LOVE_UINT8_MAX; + + textureBindings.push_back(b); } - }; - for (const auto &resource : resources.sampled_images) - { - setTextureBinding(msl, stageindex, resource); + auto &b = textureBindings[u.ints[i]]; + b.textureStages[stageindex] = (uint8) texturebinding; + b.samplerStages[stageindex] = (uint8) samplerbinding; } + }; - for (const auto &resource : resources.storage_images) - { - setTextureBinding(msl, stageindex, resource); - } + for (const auto &resource : resources.sampled_images) + { + setTextureBinding(msl, stageindex, resource); + } - for (const auto &resource : resources.storage_buffers) - { - auto it = uniforms.find(resource.name); - if (it == uniforms.end()) - continue; + for (const auto &resource : resources.storage_images) + { + setTextureBinding(msl, stageindex, resource); + } - UniformInfo &u = it->second; + for (const auto &resource : resources.storage_buffers) + { + auto it = uniforms.find(resource.name); + if (it == uniforms.end()) + continue; - uint32 bufferbinding = msl.get_automatic_msl_resource_binding(resource.id); - if (bufferbinding == (uint32)-1) - { - // No valid binding, the uniform was likely optimized out because it's not used. - uniforms.erase(resource.name); - continue; - } + UniformInfo &u = it->second; - for (int i = 0; i < u.count; i++) - { - if (u.ints[i] == -1) - { - u.ints[i] = (int)bufferBindings.size(); - BufferBinding b = {}; - b.access = u.access; + uint32 bufferbinding = msl.get_automatic_msl_resource_binding(resource.id); + if (bufferbinding == (uint32)-1) + { + // No valid binding, the uniform was likely optimized out because it's not used. + uniforms.erase(resource.name); + continue; + } - for (uint8 &stagebinding : b.stages) - stagebinding = LOVE_UINT8_MAX; + for (int i = 0; i < u.count; i++) + { + if (u.ints[i] == -1) + { + u.ints[i] = (int)bufferBindings.size(); + BufferBinding b = {}; + b.access = u.access; - bufferBindings.push_back(b); - } + for (uint8 &stagebinding : b.stages) + stagebinding = LOVE_UINT8_MAX; - bufferBindings[u.ints[i]].stages[stageindex] = (uint8) bufferbinding; + bufferBindings.push_back(b); } + + bufferBindings[u.ints[i]].stages[stageindex] = (uint8) bufferbinding; } } - catch (std::exception &e) - { - printf("Error parsing SPIR-V shader source: %s\n", e.what()); - } } // Initialize default resource bindings. From 50b18d1ac7f61fb3da5bf8a53e643ddabe1df786 Mon Sep 17 00:00:00 2001 From: Sasha Szpakowski Date: Sat, 13 Jan 2024 18:06:37 -0400 Subject: [PATCH 29/29] Add love.mouse.getGlobalPosition. Useful for custom window dragging. --- src/modules/mouse/Mouse.h | 5 +--- src/modules/mouse/sdl/Mouse.cpp | 46 ++++++++++++++++++-------------- src/modules/mouse/sdl/Mouse.h | 5 +--- src/modules/mouse/wrap_Mouse.cpp | 32 +++++++++++++++++----- 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/src/modules/mouse/Mouse.h b/src/modules/mouse/Mouse.h index d57c49406..9b37b7f2f 100644 --- a/src/modules/mouse/Mouse.h +++ b/src/modules/mouse/Mouse.h @@ -53,12 +53,9 @@ class Mouse : public Module virtual bool isCursorSupported() const = 0; - virtual double getX() const = 0; - virtual double getY() const = 0; virtual void getPosition(double &x, double &y) const = 0; - virtual void setX(double x) = 0; - virtual void setY(double y) = 0; virtual void setPosition(double x, double y) = 0; + virtual void getGlobalPosition(double &x, double &y, int &displayindex) const = 0; virtual void setVisible(bool visible) = 0; virtual bool isDown(const std::vector &buttons) const = 0; virtual bool isVisible() const = 0; diff --git a/src/modules/mouse/sdl/Mouse.cpp b/src/modules/mouse/sdl/Mouse.cpp index 8ff555ea2..c2a3e53a4 100644 --- a/src/modules/mouse/sdl/Mouse.cpp +++ b/src/modules/mouse/sdl/Mouse.cpp @@ -124,20 +124,6 @@ bool Mouse::isCursorSupported() const return SDL_GetDefaultCursor() != nullptr; } -double Mouse::getX() const -{ - double x, y; - getPosition(x, y); - return x; -} - -double Mouse::getY() const -{ - double x, y; - getPosition(x, y); - return y; -} - void Mouse::getPosition(double &x, double &y) const { int mx, my; @@ -173,14 +159,34 @@ void Mouse::setPosition(double x, double y) SDL_PumpEvents(); } -void Mouse::setX(double x) +void Mouse::getGlobalPosition(double &x, double &y, int &displayindex) const { - setPosition(x, getY()); -} + int globalx, globaly; + SDL_GetGlobalMouseState(&globalx, &globaly); -void Mouse::setY(double y) -{ - setPosition(getX(), y); + int mx = globalx; + int my = globaly; + + int displaycount = SDL_GetNumVideoDisplays(); + + for (displayindex = 0; displayindex < displaycount; displayindex++) + { + SDL_Rect rect = {}; + SDL_GetDisplayBounds(displayindex, &rect); + + mx -= rect.x; + my -= rect.y; + + SDL_Point p = { globalx, globaly }; + if (SDL_PointInRect(&p, &rect)) + break; + } + + if (displayindex >= displaycount) + displayindex = 0; + + x = (double)mx; + y = (double)my; } void Mouse::setVisible(bool visible) diff --git a/src/modules/mouse/sdl/Mouse.h b/src/modules/mouse/sdl/Mouse.h index abab2d61b..b859c4c52 100644 --- a/src/modules/mouse/sdl/Mouse.h +++ b/src/modules/mouse/sdl/Mouse.h @@ -55,12 +55,9 @@ class Mouse : public love::mouse::Mouse bool isCursorSupported() const override; - double getX() const override; - double getY() const override; void getPosition(double &x, double &y) const override; - void setX(double x) override; - void setY(double y) override; void setPosition(double x, double y) override; + void getGlobalPosition(double &x, double &y, int &displayindex) const override; void setVisible(bool visible) override; bool isDown(const std::vector &buttons) const override; bool isVisible() const override; diff --git a/src/modules/mouse/wrap_Mouse.cpp b/src/modules/mouse/wrap_Mouse.cpp index 999be9969..2dd8233a7 100644 --- a/src/modules/mouse/wrap_Mouse.cpp +++ b/src/modules/mouse/wrap_Mouse.cpp @@ -100,13 +100,17 @@ int w_isCursorSupported(lua_State *L) int w_getX(lua_State *L) { - lua_pushnumber(L, instance()->getX()); + double x, y; + instance()->getPosition(x, y); + lua_pushnumber(L, x); return 1; } int w_getY(lua_State *L) { - lua_pushnumber(L, instance()->getY()); + double x, y; + instance()->getPosition(x, y); + lua_pushnumber(L, y); return 1; } @@ -121,15 +125,19 @@ int w_getPosition(lua_State *L) int w_setX(lua_State *L) { - double x = luaL_checknumber(L, 1); - instance()->setX(x); + double x, y; + instance()->getPosition(x, y); + x = luaL_checknumber(L, 1); + instance()->setPosition(x, y); return 0; } int w_setY(lua_State *L) { - double y = luaL_checknumber(L, 1); - instance()->setY(y); + double x, y; + instance()->getPosition(x, y); + y = luaL_checknumber(L, 1); + instance()->setPosition(x, y); return 0; } @@ -141,6 +149,17 @@ int w_setPosition(lua_State *L) return 0; } +int w_getGlobalPosition(lua_State *L) +{ + double x, y; + int displayindex; + instance()->getGlobalPosition(x, y, displayindex); + lua_pushnumber(L, x); + lua_pushnumber(L, y); + lua_pushinteger(L, displayindex + 1); + return 3; +} + int w_isDown(lua_State *L) { bool istable = lua_istable(L, 1); @@ -220,6 +239,7 @@ static const luaL_Reg functions[] = { "setX", w_setX }, { "setY", w_setY }, { "setPosition", w_setPosition }, + { "getGlobalPosition", w_getGlobalPosition }, { "isDown", w_isDown }, { "setVisible", w_setVisible }, { "isVisible", w_isVisible },