From 4dcd123805a1d8d101fa2f6f8fa955c1b9d7f05a Mon Sep 17 00:00:00 2001 From: "adam.b" Date: Thu, 8 Mar 2018 16:45:15 +0000 Subject: [PATCH] [Vulkan] SPIRV simplified reflection ( work in progress ) Reflection plugged under the pipeline. Implemented: - Parsing SPIRV code - Providing VkDescriptorSetLayoutCreateInfo data based on the shader content - Uniform objects are matched dynamically so no need to hardcode the layouts anymore. Shader modules are not able to created the descriptor set layout on its own. Only when attached to the pipeline, the DS layouts are created before creating pipeline layout. Change-Id: Id615bd9fbf937ca2e8f1f6c0ff54d1d36f13fd0a --- dali/graphics/file.list | 2 + dali/graphics/vulkan/generated/spv-shaders-gen.cpp | 54 +- dali/graphics/vulkan/generated/spv-shaders-gen.h | 5 +- dali/graphics/vulkan/shaders/basic-shader.vert | 1 - .../vulkan/shaders/experimental-shader.vert | 37 + dali/graphics/vulkan/spirv/spirv.h | 1018 ++++++++++++++++++++ dali/graphics/vulkan/spirv/vulkan-spirv-opcode.h | 433 +++++++++ dali/graphics/vulkan/spirv/vulkan-spirv.cpp | 935 ++++++++++++++++++ dali/graphics/vulkan/spirv/vulkan-spirv.h | 174 ++++ dali/graphics/vulkan/vulkan-command-buffer.cpp | 13 +- dali/graphics/vulkan/vulkan-descriptor-set.cpp | 20 +- dali/graphics/vulkan/vulkan-descriptor-set.h | 4 +- .../graphics/vulkan/vulkan-graphics-controller.cpp | 19 +- dali/graphics/vulkan/vulkan-graphics.cpp | 6 +- dali/graphics/vulkan/vulkan-pipeline.cpp | 107 +- dali/graphics/vulkan/vulkan-pipeline.h | 14 + dali/graphics/vulkan/vulkan-shader.cpp | 45 +- dali/graphics/vulkan/vulkan-shader.h | 7 +- dali/graphics/vulkan/vulkan-standalone-test.cpp | 52 +- 19 files changed, 2804 insertions(+), 142 deletions(-) create mode 100644 dali/graphics/vulkan/shaders/experimental-shader.vert create mode 100644 dali/graphics/vulkan/spirv/spirv.h create mode 100644 dali/graphics/vulkan/spirv/vulkan-spirv-opcode.h create mode 100644 dali/graphics/vulkan/spirv/vulkan-spirv.cpp create mode 100644 dali/graphics/vulkan/spirv/vulkan-spirv.h diff --git a/dali/graphics/file.list b/dali/graphics/file.list index 0860f36..6ec3e20 100644 --- a/dali/graphics/file.list +++ b/dali/graphics/file.list @@ -17,6 +17,8 @@ graphics_src_files = \ $(graphics_src_dir)/vulkan/vulkan-graphics.cpp \ $(graphics_src_dir)/vulkan/vulkan-shader.cpp \ $(graphics_src_dir)/vulkan/vulkan-graphics-controller.cpp \ + $(graphics_src_dir)/vulkan/spirv/vulkan-spirv.cpp \ $(graphics_src_dir)/graphics-controller.cpp + diff --git a/dali/graphics/vulkan/generated/spv-shaders-gen.cpp b/dali/graphics/vulkan/generated/spv-shaders-gen.cpp index 7cb07c3..a6b8988 100644 --- a/dali/graphics/vulkan/generated/spv-shaders-gen.cpp +++ b/dali/graphics/vulkan/generated/spv-shaders-gen.cpp @@ -140,7 +140,7 @@ std::vector VSH_CODE = { }; std::vector FSH_CODE = { 0x03, 0x02, 0x23, 0x07, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, + 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x00, 0x47, 0x4c, 0x53, 0x4c, 0x2e, 0x73, 0x74, 0x64, 0x2e, 0x34, 0x35, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -153,23 +153,43 @@ std::vector FSH_CODE = { 0x05, 0x00, 0x05, 0x00, 0x09, 0x00, 0x00, 0x00, 0x6f, 0x75, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x74, 0x72, 0x69, 0x43, 0x6f, 0x6c, 0x6f, 0x72, - 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x05, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x75, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x09, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x04, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x21, 0x00, 0x03, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x00, 0x03, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x3b, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x47, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x13, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x03, 0x00, 0x06, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x17, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x19, 0x00, 0x09, 0x00, + 0x0d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x03, 0x00, + 0x0e, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, + 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x3b, 0x00, 0x04, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x04, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x04, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, + 0x2c, 0x00, 0x05, 0x00, 0x12, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x36, 0x00, 0x05, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x3d, 0x00, 0x04, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x0b, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x04, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x57, 0x00, 0x05, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x81, 0x00, 0x05, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x16, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0x3e, 0x00, 0x03, 0x00, 0x09, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0x00 }; #pragma GCC diagnostic pop diff --git a/dali/graphics/vulkan/generated/spv-shaders-gen.h b/dali/graphics/vulkan/generated/spv-shaders-gen.h index 90d6511..5a4709f 100644 --- a/dali/graphics/vulkan/generated/spv-shaders-gen.h +++ b/dali/graphics/vulkan/generated/spv-shaders-gen.h @@ -28,7 +28,6 @@ layout( location = 0 ) out vec4 triColor; void main() { gl_Position = clip * mvp * vec4( aPosition* size, 1.0 ); - //gl_Position = vec4( aPosition, 1.0 ); triColor = color; }*/ @@ -40,9 +39,11 @@ extern std::vector FSH_CODE; layout( location = 0 ) in vec4 triColor; layout( location = 0 ) out vec4 outColor; +layout( binding = 2 ) uniform sampler2D uTexture; + void main() { - outColor = triColor; + outColor = triColor + texture( uTexture, vec2(0.5, 0.5)); }*/ diff --git a/dali/graphics/vulkan/shaders/basic-shader.vert b/dali/graphics/vulkan/shaders/basic-shader.vert index d60999c..20ac3f7 100644 --- a/dali/graphics/vulkan/shaders/basic-shader.vert +++ b/dali/graphics/vulkan/shaders/basic-shader.vert @@ -19,6 +19,5 @@ layout( location = 0 ) out vec4 triColor; void main() { gl_Position = clip * mvp * vec4( aPosition* size, 1.0 ); - //gl_Position = vec4( aPosition, 1.0 ); triColor = color; } \ No newline at end of file diff --git a/dali/graphics/vulkan/shaders/experimental-shader.vert b/dali/graphics/vulkan/shaders/experimental-shader.vert new file mode 100644 index 0000000..9a091c3 --- /dev/null +++ b/dali/graphics/vulkan/shaders/experimental-shader.vert @@ -0,0 +1,37 @@ +#version 430 + +layout( location = 0 ) in vec3 aPosition; +layout( location = 1 ) in vec3 aSize; + +layout( set = 0, binding = 0, r32f ) uniform image2D myStorageImage; + +layout( set = 2, binding = 0, std140 ) uniform world +{ + mat4 mvp; + vec4 color; + vec3 size; +}; + +layout( set = 2, binding = 1 ) uniform samplerCube uTexture; + +layout( set = 2, binding = 2 ) uniform sampler2D uMask; +layout( set = 2, binding = 5, std140 ) uniform clipUniform +{ + mat4 clip; +}; + +layout( std430, set = 0, binding = 1 ) buffer myStorageBuffer +{ + mat4 myMat; + vec4 myVec; + vec4 bones[]; +}; + +layout( location = 0 ) out vec4 triColor; + +void main() +{ + gl_Position = clip * mvp * vec4( aPosition* size * aSize, 1.0 ); + //gl_Position = vec4( aPosition, 1.0 ); + triColor = color * texture( uTexture, aSize.xyz ) * texture( uMask, aSize.xy ); +} \ No newline at end of file diff --git a/dali/graphics/vulkan/spirv/spirv.h b/dali/graphics/vulkan/spirv/spirv.h new file mode 100644 index 0000000..d1f5792 --- /dev/null +++ b/dali/graphics/vulkan/spirv/spirv.h @@ -0,0 +1,1018 @@ +/* +** Copyright (c) 2014-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. +*/ + +/* +** 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 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'] +** +** 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 0x10200 +#define SPV_REVISION 3 + +static const unsigned int SpvMagicNumber = 0x07230203; +static const unsigned int SpvVersion = 0x00010200; +static const unsigned int SpvRevision = 3; +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, + SpvSourceLanguageMax = 0x7fffffff, +} SpvSourceLanguage; + +typedef enum SpvExecutionModel_ { + SpvExecutionModelVertex = 0, + SpvExecutionModelTessellationControl = 1, + SpvExecutionModelTessellationEvaluation = 2, + SpvExecutionModelGeometry = 3, + SpvExecutionModelFragment = 4, + SpvExecutionModelGLCompute = 5, + SpvExecutionModelKernel = 6, + SpvExecutionModelMax = 0x7fffffff, +} SpvExecutionModel; + +typedef enum SpvAddressingModel_ { + SpvAddressingModelLogical = 0, + SpvAddressingModelPhysical32 = 1, + SpvAddressingModelPhysical64 = 2, + SpvAddressingModelMax = 0x7fffffff, +} SpvAddressingModel; + +typedef enum SpvMemoryModel_ { + SpvMemoryModelSimple = 0, + SpvMemoryModelGLSL450 = 1, + SpvMemoryModelOpenCL = 2, + 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, + SpvExecutionModePostDepthCoverage = 4446, + SpvExecutionModeStencilRefReplacingEXT = 5027, + 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, + 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, + 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, + SpvImageOperandsMax = 0x7fffffff, +} SpvImageOperandsShift; + +typedef enum SpvImageOperandsMask_ { + SpvImageOperandsMaskNone = 0, + SpvImageOperandsBiasMask = 0x00000001, + SpvImageOperandsLodMask = 0x00000002, + SpvImageOperandsGradMask = 0x00000004, + SpvImageOperandsConstOffsetMask = 0x00000008, + SpvImageOperandsOffsetMask = 0x00000010, + SpvImageOperandsConstOffsetsMask = 0x00000020, + SpvImageOperandsSampleMask = 0x00000040, + SpvImageOperandsMinLodMask = 0x00000080, +} SpvImageOperandsMask; + +typedef enum SpvFPFastMathModeShift_ { + SpvFPFastMathModeNotNaNShift = 0, + SpvFPFastMathModeNotInfShift = 1, + SpvFPFastMathModeNSZShift = 2, + SpvFPFastMathModeAllowRecipShift = 3, + SpvFPFastMathModeFastShift = 4, + SpvFPFastMathModeMax = 0x7fffffff, +} SpvFPFastMathModeShift; + +typedef enum SpvFPFastMathModeMask_ { + SpvFPFastMathModeMaskNone = 0, + SpvFPFastMathModeNotNaNMask = 0x00000001, + SpvFPFastMathModeNotInfMask = 0x00000002, + SpvFPFastMathModeNSZMask = 0x00000004, + SpvFPFastMathModeAllowRecipMask = 0x00000008, + SpvFPFastMathModeFastMask = 0x00000010, +} SpvFPFastMathModeMask; + +typedef enum SpvFPRoundingMode_ { + SpvFPRoundingModeRTE = 0, + SpvFPRoundingModeRTZ = 1, + SpvFPRoundingModeRTP = 2, + SpvFPRoundingModeRTN = 3, + SpvFPRoundingModeMax = 0x7fffffff, +} SpvFPRoundingMode; + +typedef enum SpvLinkageType_ { + SpvLinkageTypeExport = 0, + SpvLinkageTypeImport = 1, + 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, + 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, + SpvDecorationExplicitInterpAMD = 4999, + SpvDecorationOverrideCoverageNV = 5248, + SpvDecorationPassthroughNV = 5250, + SpvDecorationViewportRelativeNV = 5252, + SpvDecorationSecondaryViewportRelativeNV = 5256, + 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, + SpvBuiltInSubgroupEqMaskKHR = 4416, + SpvBuiltInSubgroupGeMaskKHR = 4417, + SpvBuiltInSubgroupGtMaskKHR = 4418, + SpvBuiltInSubgroupLeMaskKHR = 4419, + SpvBuiltInSubgroupLtMaskKHR = 4420, + SpvBuiltInBaseVertex = 4424, + SpvBuiltInBaseInstance = 4425, + SpvBuiltInDrawIndex = 4426, + SpvBuiltInDeviceIndex = 4438, + SpvBuiltInViewIndex = 4440, + 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, + 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, + SpvLoopControlMax = 0x7fffffff, +} SpvLoopControlShift; + +typedef enum SpvLoopControlMask_ { + SpvLoopControlMaskNone = 0, + SpvLoopControlUnrollMask = 0x00000001, + SpvLoopControlDontUnrollMask = 0x00000002, + SpvLoopControlDependencyInfiniteMask = 0x00000004, + SpvLoopControlDependencyLengthMask = 0x00000008, +} SpvLoopControlMask; + +typedef enum SpvFunctionControlShift_ { + SpvFunctionControlInlineShift = 0, + SpvFunctionControlDontInlineShift = 1, + SpvFunctionControlPureShift = 2, + SpvFunctionControlConstShift = 3, + SpvFunctionControlMax = 0x7fffffff, +} SpvFunctionControlShift; + +typedef enum SpvFunctionControlMask_ { + SpvFunctionControlMaskNone = 0, + SpvFunctionControlInlineMask = 0x00000001, + SpvFunctionControlDontInlineMask = 0x00000002, + SpvFunctionControlPureMask = 0x00000004, + SpvFunctionControlConstMask = 0x00000008, +} SpvFunctionControlMask; + +typedef enum SpvMemorySemanticsShift_ { + SpvMemorySemanticsAcquireShift = 1, + SpvMemorySemanticsReleaseShift = 2, + SpvMemorySemanticsAcquireReleaseShift = 3, + SpvMemorySemanticsSequentiallyConsistentShift = 4, + SpvMemorySemanticsUniformMemoryShift = 6, + SpvMemorySemanticsSubgroupMemoryShift = 7, + SpvMemorySemanticsWorkgroupMemoryShift = 8, + SpvMemorySemanticsCrossWorkgroupMemoryShift = 9, + SpvMemorySemanticsAtomicCounterMemoryShift = 10, + SpvMemorySemanticsImageMemoryShift = 11, + 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, +} SpvMemorySemanticsMask; + +typedef enum SpvMemoryAccessShift_ { + SpvMemoryAccessVolatileShift = 0, + SpvMemoryAccessAlignedShift = 1, + SpvMemoryAccessNontemporalShift = 2, + SpvMemoryAccessMax = 0x7fffffff, +} SpvMemoryAccessShift; + +typedef enum SpvMemoryAccessMask_ { + SpvMemoryAccessMaskNone = 0, + SpvMemoryAccessVolatileMask = 0x00000001, + SpvMemoryAccessAlignedMask = 0x00000002, + SpvMemoryAccessNontemporalMask = 0x00000004, +} SpvMemoryAccessMask; + +typedef enum SpvScope_ { + SpvScopeCrossDevice = 0, + SpvScopeDevice = 1, + SpvScopeWorkgroup = 2, + SpvScopeSubgroup = 3, + SpvScopeInvocation = 4, + SpvScopeMax = 0x7fffffff, +} SpvScope; + +typedef enum SpvGroupOperation_ { + SpvGroupOperationReduce = 0, + SpvGroupOperationInclusiveScan = 1, + SpvGroupOperationExclusiveScan = 2, + 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, + SpvCapabilitySubgroupBallotKHR = 4423, + SpvCapabilityDrawParameters = 4427, + 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, + SpvCapabilityImageGatherBiasLodAMD = 5009, + SpvCapabilityFragmentMaskAMD = 5010, + SpvCapabilityStencilExportEXT = 5013, + SpvCapabilityImageReadWriteLodAMD = 5015, + SpvCapabilitySampleMaskOverrideCoverageNV = 5249, + SpvCapabilityGeometryShaderPassthroughNV = 5251, + SpvCapabilityShaderViewportIndexLayerEXT = 5254, + SpvCapabilityShaderViewportIndexLayerNV = 5254, + SpvCapabilityShaderViewportMaskNV = 5255, + SpvCapabilityShaderStereoViewNV = 5259, + SpvCapabilityPerViewAttributesNV = 5260, + SpvCapabilityFragmentFullyCoveredEXT = 5265, + SpvCapabilitySubgroupShuffleINTEL = 5568, + SpvCapabilitySubgroupBufferBlockIOINTEL = 5569, + SpvCapabilitySubgroupImageBlockIOINTEL = 5570, + SpvCapabilityMax = 0x7fffffff, +} SpvCapability; + +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, + SpvOpSubgroupBallotKHR = 4421, + SpvOpSubgroupFirstInvocationKHR = 4422, + SpvOpSubgroupAllKHR = 4428, + SpvOpSubgroupAnyKHR = 4429, + SpvOpSubgroupAllEqualKHR = 4430, + SpvOpSubgroupReadInvocationKHR = 4432, + SpvOpGroupIAddNonUniformAMD = 5000, + SpvOpGroupFAddNonUniformAMD = 5001, + SpvOpGroupFMinNonUniformAMD = 5002, + SpvOpGroupUMinNonUniformAMD = 5003, + SpvOpGroupSMinNonUniformAMD = 5004, + SpvOpGroupFMaxNonUniformAMD = 5005, + SpvOpGroupUMaxNonUniformAMD = 5006, + SpvOpGroupSMaxNonUniformAMD = 5007, + SpvOpFragmentMaskFetchAMD = 5011, + SpvOpFragmentFetchAMD = 5012, + SpvOpSubgroupShuffleINTEL = 5571, + SpvOpSubgroupShuffleDownINTEL = 5572, + SpvOpSubgroupShuffleUpINTEL = 5573, + SpvOpSubgroupShuffleXorINTEL = 5574, + SpvOpSubgroupBlockReadINTEL = 5575, + SpvOpSubgroupBlockWriteINTEL = 5576, + SpvOpSubgroupImageBlockReadINTEL = 5577, + SpvOpSubgroupImageBlockWriteINTEL = 5578, + SpvOpMax = 0x7fffffff, +} SpvOp; + +#endif // #ifndef spirv_H diff --git a/dali/graphics/vulkan/spirv/vulkan-spirv-opcode.h b/dali/graphics/vulkan/spirv/vulkan-spirv-opcode.h new file mode 100644 index 0000000..81cd2e0 --- /dev/null +++ b/dali/graphics/vulkan/spirv/vulkan-spirv-opcode.h @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef DALI_GRAPHICS_VULKAN_SPIRV_SPIRV_OPCODES_H +#define DALI_GRAPHICS_VULKAN_SPIRV_SPIRV_OPCODES_H + +namespace Dali +{ +namespace Graphics +{ +namespace Vulkan +{ +namespace SpirV +{ +struct SPIRVOpCode +{ + std::string name{"OpNull"}; + uint32_t code{static_cast( -1u )}; + bool hasResult{false}; + bool hasResultType{false}; + bool isType{false}; + bool isTrivial{false}; // trivial types do not reference to any other result + + /** Defines local data */ + struct LocalData + { + uint32_t* start{nullptr}; + uint32_t count{0u}; + uint32_t resultId{0u}; + int32_t resultType{-1}; + }; + + LocalData localData{}; + + bool operator!=( const SPIRVOpCode& opcode ) const + { + return opcode.code != code; + } + + bool operator==( const SPIRVOpCode& opcode ) const + { + return opcode.code == code; + } + + bool operator==( SpvOp op ) const + { + return ( code == static_cast(op) ); + } + + template + T GetParameter( uint32_t index ) const + { + return static_cast( *( localData.start + index + 1 ) ); + } + + uint32_t GetParameterU32( uint32_t index ) const + { + return GetParameter( index ); + } + + std::string GetParameterAsString( uint32_t index ) const + { + return reinterpret_cast( localData.start + index + 1 ); + } + + template + T operator[]( uint32_t index ) const + { + return GetParameter( index ); + } + + SPIRVOpCode() = default; + ~SPIRVOpCode() = default; +}; + +namespace +{ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlarger-than=" +/** + * List of all the SPIR-V opcodes + * OpCodes describing types: 19-39 + */ +static const SPIRVOpCode OP_CODE_ARRAY[] = {{"OpNop", 0, false, false, false}, + {"OpUndef", 1, true, true, false}, + {"OpSourceContinued", 2, false, false, false}, + {"OpSource", 3, false, false, false}, + {"OpSourceExtension", 4, false, false, false}, + {"OpName", 5, false, false, false}, + {"OpMemberName", 6, false, false, false}, + {"OpString", 7, true, false, false}, + {"OpLine", 8, false, false, false}, + {"OpExtension", 10, false, false, false}, + {"OpExtInstImport", 11, true, false, false}, + {"OpExtInst", 12, true, true, false}, + {"OpMemoryModel", 14, false, false, false}, + {"OpEntryPoint", 15, false, false, false}, + {"OpExecutionMode", 16, false, false, false}, + {"OpCapability", 17, false, false, false}, + {"OpTypeVoid", 19, true, false, true, true}, + {"OpTypeBool", 20, true, false, true, true}, + {"OpTypeInt", 21, true, false, true, true}, + {"OpTypeFloat", 22, true, false, true, true}, + {"OpTypeVector", 23, true, false, true}, + {"OpTypeMatrix", 24, true, false, true}, + {"OpTypeImage", 25, true, false, true}, + {"OpTypeSampler", 26, true, false, true}, + {"OpTypeSampledImage", 27, true, false, true}, + {"OpTypeArray", 28, true, false, true}, + {"OpTypeRuntimeArray", 29, true, false, true}, + {"OpTypeStruct", 30, true, false, true}, + {"OpTypeOpaque", 31, true, false, true}, + {"OpTypePointer", 32, true, false, true}, + {"OpTypeFunction", 33, true, false, true}, + {"OpTypeEvent", 34, true, false, true}, + {"OpTypeDeviceEvent", 35, true, false, true}, + {"OpTypeReserveId", 36, true, false, true}, + {"OpTypeQueue", 37, true, false, true}, + {"OpTypePipe", 38, true, false, true}, + {"OpTypeForwardPointer", 39, false, false, true}, + {"OpConstantTrue", 41, true, true, false}, + {"OpConstantFalse", 42, true, true, false}, + {"OpConstant", 43, true, true, false}, + {"OpConstantComposite", 44, true, true, false}, + {"OpConstantSampler", 45, true, true, false}, + {"OpConstantNull", 46, true, true, false}, + {"OpSpecConstantTrue", 48, true, true, false}, + {"OpSpecConstantFalse", 49, true, true, false}, + {"OpSpecConstant", 50, true, true, false}, + {"OpSpecConstantComposite", 51, true, true, false}, + {"OpSpecConstantOp", 52, true, true, false}, + {"OpFunction", 54, true, true, false}, + {"OpFunctionParameter", 55, true, true, false}, + {"OpFunctionEnd", 56, false, false, false}, + {"OpFunctionCall", 57, true, true, false}, + {"OpVariable", 59, true, true, false}, + {"OpImageTexelPointer", 60, true, true, false}, + {"OpLoad", 61, true, true, false}, + {"OpStore", 62, false, false, false}, + {"OpCopyMemory", 63, false, false, false}, + {"OpCopyMemorySized", 64, false, false, false}, + {"OpAccessChain", 65, true, true, false}, + {"OpInBoundsAccessChain", 66, true, true, false}, + {"OpPtrAccessChain", 67, true, true, false}, + {"OpArrayLength", 68, true, true, false}, + {"OpGenericPtrMemSemantics", 69, true, true, false}, + {"OpInBoundsPtrAccessChain", 70, true, true, false}, + {"OpDecorate", 71, false, false, false}, + {"OpMemberDecorate", 72, false, false, false}, + {"OpDecorationGroup", 73, true, false, false}, + {"OpGroupDecorate", 74, false, false, false}, + {"OpGroupMemberDecorate", 75, false, false, false}, + {"OpVectorExtractDynamic", 77, true, true, false}, + {"OpVectorInsertDynamic", 78, true, true, false}, + {"OpVectorShuffle", 79, true, true, false}, + {"OpCompositeConstruct", 80, true, true, false}, + {"OpCompositeExtract", 81, true, true, false}, + {"OpCompositeInsert", 82, true, true, false}, + {"OpCopyObject", 83, true, true, false}, + {"OpTranspose", 84, true, true, false}, + {"OpSampledImage", 86, true, true, false}, + {"OpImageSampleImplicitLod", 87, true, true, false}, + {"OpImageSampleExplicitLod", 88, true, true, false}, + {"OpImageSampleDrefImplicitLod", 89, true, true, false}, + {"OpImageSampleDrefExplicitLod", 90, true, true, false}, + {"OpImageSampleProjImplicitLod", 91, true, true, false}, + {"OpImageSampleProjExplicitLod", 92, true, true, false}, + {"OpImageSampleProjDrefImplicitLod", 93, true, true, false}, + {"OpImageSampleProjDrefExplicitLod", 94, true, true, false}, + {"OpImageFetch", 95, true, true, false}, + {"OpImageGather", 96, true, true, false}, + {"OpImageDrefGather", 97, true, true, false}, + {"OpImageRead", 98, true, true, false}, + {"OpImageWrite", 99, false, false, false}, + {"OpImage", 100, true, true, false}, + {"OpImageQueryFormat", 101, true, true, false}, + {"OpImageQueryOrder", 102, true, true, false}, + {"OpImageQuerySizeLod", 103, true, true, false}, + {"OpImageQuerySize", 104, true, true, false}, + {"OpImageQueryLod", 105, true, true, false}, + {"OpImageQueryLevels", 106, true, true, false}, + {"OpImageQuerySamples", 107, true, true, false}, + {"OpConvertFToU", 109, true, true, false}, + {"OpConvertFToS", 110, true, true, false}, + {"OpConvertSToF", 111, true, true, false}, + {"OpConvertUToF", 112, true, true, false}, + {"OpUConvert", 113, true, true, false}, + {"OpSConvert", 114, true, true, false}, + {"OpFConvert", 115, true, true, false}, + {"OpQuantizeToF16", 116, true, true, false}, + {"OpConvertPtrToU", 117, true, true, false}, + {"OpSatConvertSToU", 118, true, true, false}, + {"OpSatConvertUToS", 119, true, true, false}, + {"OpConvertUToPtr", 120, true, true, false}, + {"OpPtrCastToGeneric", 121, true, true, false}, + {"OpGenericCastToPtr", 122, true, true, false}, + {"OpGenericCastToPtrExplicit", 123, true, true, false}, + {"OpBitcast", 124, true, true, false}, + {"OpSNegate", 126, true, true, false}, + {"OpFNegate", 127, true, true, false}, + {"OpIAdd", 128, true, true, false}, + {"OpFAdd", 129, true, true, false}, + {"OpISub", 130, true, true, false}, + {"OpFSub", 131, true, true, false}, + {"OpIMul", 132, true, true, false}, + {"OpFMul", 133, true, true, false}, + {"OpUDiv", 134, true, true, false}, + {"OpSDiv", 135, true, true, false}, + {"OpFDiv", 136, true, true, false}, + {"OpUMod", 137, true, true, false}, + {"OpSRem", 138, true, true, false}, + {"OpSMod", 139, true, true, false}, + {"OpFRem", 140, true, true, false}, + {"OpFMod", 141, true, true, false}, + {"OpVectorTimesScalar", 142, true, true, false}, + {"OpMatrixTimesScalar", 143, true, true, false}, + {"OpVectorTimesMatrix", 144, true, true, false}, + {"OpMatrixTimesVector", 145, true, true, false}, + {"OpMatrixTimesMatrix", 146, true, true, false}, + {"OpOuterProduct", 147, true, true, false}, + {"OpDot", 148, true, true, false}, + {"OpIAddCarry", 149, true, true, false}, + {"OpISubBorrow", 150, true, true, false}, + {"OpUMulExtended", 151, true, true, false}, + {"OpSMulExtended", 152, true, true, false}, + {"OpAny", 154, true, true, false}, + {"OpAll", 155, true, true, false}, + {"OpIsNan", 156, true, true, false}, + {"OpIsInf", 157, true, true, false}, + {"OpIsFinite", 158, true, true, false}, + {"OpIsNormal", 159, true, true, false}, + {"OpSignBitSet", 160, true, true, false}, + {"OpLessOrGreater", 161, true, true, false}, + {"OpOrdered", 162, true, true, false}, + {"OpUnordered", 163, true, true, false}, + {"OpLogicalEqual", 164, true, true, false}, + {"OpLogicalNotEqual", 165, true, true, false}, + {"OpLogicalOr", 166, true, true, false}, + {"OpLogicalAnd", 167, true, true, false}, + {"OpLogicalNot", 168, true, true, false}, + {"OpSelect", 169, true, true, false}, + {"OpIEqual", 170, true, true, false}, + {"OpINotEqual", 171, true, true, false}, + {"OpUGreaterThan", 172, true, true, false}, + {"OpSGreaterThan", 173, true, true, false}, + {"OpUGreaterThanEqual", 174, true, true, false}, + {"OpSGreaterThanEqual", 175, true, true, false}, + {"OpULessThan", 176, true, true, false}, + {"OpSLessThan", 177, true, true, false}, + {"OpULessThanEqual", 178, true, true, false}, + {"OpSLessThanEqual", 179, true, true, false}, + {"OpFOrdEqual", 180, true, true, false}, + {"OpFUnordEqual", 181, true, true, false}, + {"OpFOrdNotEqual", 182, true, true, false}, + {"OpFUnordNotEqual", 183, true, true, false}, + {"OpFOrdLessThan", 184, true, true, false}, + {"OpFUnordLessThan", 185, true, true, false}, + {"OpFOrdGreaterThan", 186, true, true, false}, + {"OpFUnordGreaterThan", 187, true, true, false}, + {"OpFOrdLessThanEqual", 188, true, true, false}, + {"OpFUnordLessThanEqual", 189, true, true, false}, + {"OpFOrdGreaterThanEqual", 190, true, true, false}, + {"OpFUnordGreaterThanEqual", 191, true, true, false}, + {"OpShiftRightLogical", 194, true, true, false}, + {"OpShiftRightArithmetic", 195, true, true, false}, + {"OpShiftLeftLogical", 196, true, true, false}, + {"OpBitwiseOr", 197, true, true, false}, + {"OpBitwiseXor", 198, true, true, false}, + {"OpBitwiseAnd", 199, true, true, false}, + {"OpNot", 200, true, true, false}, + {"OpBitFieldInsert", 201, true, true, false}, + {"OpBitFieldSExtract", 202, true, true, false}, + {"OpBitFieldUExtract", 203, true, true, false}, + {"OpBitReverse", 204, true, true, false}, + {"OpBitCount", 205, true, true, false}, + {"OpDPdx", 207, true, true, false}, + {"OpDPdy", 208, true, true, false}, + {"OpFwidth", 209, true, true, false}, + {"OpDPdxFine", 210, true, true, false}, + {"OpDPdyFine", 211, true, true, false}, + {"OpFwidthFine", 212, true, true, false}, + {"OpDPdxCoarse", 213, true, true, false}, + {"OpDPdyCoarse", 214, true, true, false}, + {"OpFwidthCoarse", 215, true, true, false}, + {"OpEmitVertex", 218, false, false, false}, + {"OpEndPrimitive", 219, false, false, false}, + {"OpEmitStreamVertex", 220, false, false, false}, + {"OpEndStreamPrimitive", 221, false, false, false}, + {"OpControlBarrier", 224, false, false, false}, + {"OpMemoryBarrier", 225, false, false, false}, + {"OpAtomicLoad", 227, true, true, false}, + {"OpAtomicStore", 228, false, false, false}, + {"OpAtomicExchange", 229, true, true, false}, + {"OpAtomicCompareExchange", 230, true, true, false}, + {"OpAtomicCompareExchangeWeak", 231, true, true, false}, + {"OpAtomicIIncrement", 232, true, true, false}, + {"OpAtomicIDecrement", 233, true, true, false}, + {"OpAtomicIAdd", 234, true, true, false}, + {"OpAtomicISub", 235, true, true, false}, + {"OpAtomicSMin", 236, true, true, false}, + {"OpAtomicUMin", 237, true, true, false}, + {"OpAtomicSMax", 238, true, true, false}, + {"OpAtomicUMax", 239, true, true, false}, + {"OpAtomicAnd", 240, true, true, false}, + {"OpAtomicOr", 241, true, true, false}, + {"OpAtomicXor", 242, true, true, false}, + {"OpPhi", 245, true, true, false}, + {"OpLoopMerge", 246, false, false, false}, + {"OpSelectionMerge", 247, false, false, false}, + {"OpLabel", 248, true, false, false}, + {"OpBranch", 249, false, false, false}, + {"OpBranchConditional", 250, false, false, false}, + {"OpSwitch", 251, false, false, false}, + {"OpKill", 252, false, false, false}, + {"OpReturn", 253, false, false, false}, + {"OpReturnValue", 254, false, false, false}, + {"OpUnreachable", 255, false, false, false}, + {"OpLifetimeStart", 256, false, false, false}, + {"OpLifetimeStop", 257, false, false, false}, + {"OpGroupAsyncCopy", 259, true, true, false}, + {"OpGroupWaitEvents", 260, false, false, false}, + {"OpGroupAll", 261, true, true, false}, + {"OpGroupAny", 262, true, true, false}, + {"OpGroupBroadcast", 263, true, true, false}, + {"OpGroupIAdd", 264, true, true, false}, + {"OpGroupFAdd", 265, true, true, false}, + {"OpGroupFMin", 266, true, true, false}, + {"OpGroupUMin", 267, true, true, false}, + {"OpGroupSMin", 268, true, true, false}, + {"OpGroupFMax", 269, true, true, false}, + {"OpGroupUMax", 270, true, true, false}, + {"OpGroupSMax", 271, true, true, false}, + {"OpReadPipe", 274, true, true, false}, + {"OpWritePipe", 275, true, true, false}, + {"OpReservedReadPipe", 276, true, true, false}, + {"OpReservedWritePipe", 277, true, true, false}, + {"OpReserveReadPipePackets", 278, true, true, false}, + {"OpReserveWritePipePackets", 279, true, true, false}, + {"OpCommitReadPipe", 280, false, false, false}, + {"OpCommitWritePipe", 281, false, false, false}, + {"OpIsValidReserveId", 282, true, true, false}, + {"OpGetNumPipePackets", 283, true, true, false}, + {"OpGetMaxPipePackets", 284, true, true, false}, + {"OpGroupReserveReadPipePackets", 285, true, true, false}, + {"OpGroupReserveWritePipePackets", 286, true, true, false}, + {"OpGroupCommitReadPipe", 287, false, false, false}, + {"OpGroupCommitWritePipe", 288, false, false, false}, + {"OpEnqueueMarker", 291, true, true, false}, + {"OpEnqueueKernel", 292, true, true, false}, + {"OpGetKernelNDrangeSubGroupCount", 293, true, true, false}, + {"OpGetKernelNDrangeMaxSubGroupSize", 294, true, true, false}, + {"OpGetKernelWorkGroupSize", 295, true, true, false}, + {"OpGetKernelPreferredWorkGroupSizeMultiple", 296, true, true, false}, + {"OpRetainEvent", 297, false, false, false}, + {"OpReleaseEvent", 298, false, false, false}, + {"OpCreateUserEvent", 299, true, true, false}, + {"OpIsValidEvent", 300, true, true, false}, + {"OpSetUserEventStatus", 301, false, false, false}, + {"OpCaptureEventProfilingInfo", 302, false, false, false}, + {"OpGetDefaultQueue", 303, true, true, false}, + {"OpBuildNDRange", 304, true, true, false}, + {"OpImageSparseSampleImplicitLod", 305, true, true, false}, + {"OpImageSparseSampleExplicitLod", 306, true, true, false}, + {"OpImageSparseSampleDrefImplicitLod", 307, true, true, false}, + {"OpImageSparseSampleDrefExplicitLod", 308, true, true, false}, + {"OpImageSparseSampleProjImplicitLod", 309, true, true, false}, + {"OpImageSparseSampleProjExplicitLod", 310, true, true, false}, + {"OpImageSparseSampleProjDrefImplicitLod", 311, true, true, false}, + {"OpImageSparseSampleProjDrefExplicitLod", 312, true, true, false}, + {"OpImageSparseFetch", 313, true, true, false}, + {"OpImageSparseGather", 314, true, true, false}, + {"OpImageSparseDrefGather", 315, true, true, false}, + {"OpImageSparseTexelsResident", 316, true, true, false}, + {"OpNoLine", 317, false, false, false}, + {"OpAtomicFlagTestAndSet", 318, true, true, false}, + {"OpAtomicFlagClear", 319, false, false, false}, + {"OpImageSparseRead", 320, true, true, false}, + {"OpSizeOf", 321, true, true, false}, + {"OpTypePipeStorage", 322, true, false, false}, + {"OpConstantPipeStorage", 323, true, true, false}, + {"OpCreatePipeFromPipeStorage", 324, true, true, false}, + {"OpGetKernelLocalSizeForSubgroupCount", 325, true, true, false}, + {"OpGetKernelMaxNumSubgroups", 326, true, true, false}, + {"OpTypeNamedBarrier", 327, true, false, false}, + {"OpNamedBarrierInitialize", 328, true, true, false}, + {"OpMemoryNamedBarrier", 329, false, false, false}, + {"OpModuleProcessed", 330, false, false, false}, + {"OpExecutionModeId", 331, false, false, false}, + {"OpDecorateId", 332, false, false, false}, + {"OpSubgroupBallotKHR", 4421, true, true, false}, + {"OpSubgroupFirstInvocationKHR", 4422, true, true, false}, + {"OpSubgroupReadInvocationKHR", 4432, true, true, false}, + {"OpGroupIAddNonUniformAMD", 5000, true, true, false}, + {"OpGroupFAddNonUniformAMD", 5001, true, true, false}, + {"OpGroupFMinNonUniformAMD", 5002, true, true, false}, + {"OpGroupUMinNonUniformAMD", 5003, true, true, false}, + {"OpGroupSMinNonUniformAMD", 5004, true, true, false}, + {"OpGroupFMaxNonUniformAMD", 5005, true, true, false}, + {"OpGroupUMaxNonUniformAMD", 5006, true, true, false}, + {"OpGroupSMaxNonUniformAMD", 5007, true, true, false}}; +#pragma GCC diagnostic pop +static const SPIRVOpCode OP_CODE_NULL{}; +const SPIRVOpCode& FindOpCode( uint32_t code ) +{ + for( auto&& opcode : OP_CODE_ARRAY ) + { + if( opcode.code == code ) + return opcode; + } + return OP_CODE_NULL; +} + +} // namespace +} // namespace SpirV +} // namespace Vulkan +} // namespace Graphics +} // namespace Dali + +#endif //DALI_GRAPHICS_VULKAN_SPIRV_SPIRV_OPCODES_H diff --git a/dali/graphics/vulkan/spirv/vulkan-spirv.cpp b/dali/graphics/vulkan/spirv/vulkan-spirv.cpp new file mode 100644 index 0000000..54b4618 --- /dev/null +++ b/dali/graphics/vulkan/spirv/vulkan-spirv.cpp @@ -0,0 +1,935 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * 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. + * + */ + +#include +#include +#include + +#define debug( x ) std::cout << x << std::endl; + +namespace Dali +{ +namespace Graphics +{ +namespace Vulkan +{ +namespace SpirV +{ + +SPIRVShader::Impl& SPIRVShader::GetImplementation() const +{ + return *mImpl; +} + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wframe-larger-than=" +struct SPIRVShader::Impl +{ + /** + * 32bit word needed to identify SPIRV code + */ + static constexpr uint32_t MAGIC_NUMBER{0x07230203u}; + + /** + * SPIRV header binary structure + */ + struct Header + { + uint32_t magicNumber; + uint32_t versionNumber; // 0 | major | minor | 0 + uint32_t generatorMagicNumber; + uint32_t bound; + uint32_t reserved; + }; + + /** + * Stores OpTypePointer opcodes + */ + struct Pointer + { + SPIRVOpCode* opCode; + SPIRVOpCode* pointerType; + SpvStorageClass storageClass; + }; + + std::vector pointers{}; //@todo move to the local scope + + /** + * Stores OpName opcodes which refer to pointers + */ + struct PointerName + { + SPIRVOpCode* opName; + SPIRVOpCode* opRefId; + bool isMemberName{false}; + }; + + /** + * ResourceDescriptor contains details of resource binding + */ + struct ResourceDescriptor + { + Pointer* pointer; + + uint32_t descriptorSet{0u}; + uint32_t binding{0u}; + uint32_t location{0u}; + uint32_t alignment{0u}; + + vk::DescriptorType descriptorType{}; + std::string name{}; + }; + + /** + * Contains array of resources per storage type + */ + struct StorageContainer + { + using PtrNameArray = std::vector; + SpvStorageClass storageClass{SpvStorageClassMax}; + PtrNameArray resources{}; + }; + + SPIRVOpCode& FindByResultId( uint32_t resultId ) const + { + return *( opResults[resultId] ); + } + + /** + * Constructor + * @param pData + * @param size + * @param stages + */ + Impl( void* pData, std::size_t size, vk::ShaderStageFlags stages ) + { + data.resize( size ); + auto begin = reinterpret_cast( pData ); + auto end = begin + size; + std::copy( begin, end, data.begin() ); + shaderStages = stages; + } + + /** + * Constructor + * @tparam T + * @param buffer + * @param stages + */ + template + explicit Impl( std::vector buffer, vk::ShaderStageFlags stages ) + { + data.resize( ( buffer.size() * sizeof( buffer[0] ) ) / sizeof( uint32_t ) ); + auto begin = reinterpret_cast( &*buffer.begin() ); + auto end = reinterpret_cast( &*buffer.end() ); + std::copy( begin, end, data.begin() ); + shaderStages = stages; + } + + // Searches the references within OpVariable, OpConstant and OpFunction + const SPIRVOpCode& FindInstanceByType( uint32_t resultId ) const + { + // OpVariable + for( auto&& op : opResults ) + { + if( op ) + { + switch( op->code ) + { + // Variable, Constant + case SpvOpVariable: + case SpvOpConstant: + { + if( op->GetParameterU32( 0 ) == resultId ) + { + return *op; + } + break; + } + default: + { + break; + } + } + } + } + return OP_CODE_NULL; + } + + auto FindDecorationsForId( uint32_t id ) const + { + std::vector retval{}; + + for( auto&& op : opCodes ) + { + if( op.code == SpvOpDecorate && op.GetParameterU32( 0 ) == id ) + { + retval.push_back( &op ); + } + } + return retval; + } + + SPIRVOpCode& GetReferencedOpCode( const SPIRVOpCode& opCode, uint32_t refIndex ) const + { + return FindByResultId( opCode.GetParameterU32( refIndex ) ); + } + + + + auto GetDecorationsOpId( const SPIRVOpCode& resultOp ) + { + std::vector retval; + if( resultOp.hasResult ) + { + for( auto&& op : opCodes ) + { + if( op == SpvOpDecorate && op.GetParameterU32( 0 ) == resultOp.localData.resultId ) + { + retval.push_back( &op ); + } + } + } + return retval; + } + + bool CheckDecorationForOpId( const SPIRVOpCode& resultOp, SpvDecoration expectedDecoration ) + { + if( resultOp.hasResult ) + { + for( auto&& op : opCodes ) + { + if( op == SpvOpDecorate && op.GetParameterU32( 0 ) == resultOp.localData.resultId && + op.GetParameter( 1 ) == expectedDecoration ) + { + return true; + } + } + } + return false; + } + + bool Initialise() + { + // test if we have valid SPIRV header + auto iter = data.begin(); + if( !CheckHeader() ) + { + debug( "Not SPIRV!" ); + return false; + } + + debug( "SPIR-V detected" ); + std::advance( iter, 5u ); // skip header + + while( iter != data.end() ) + { + auto opword = *iter; + auto wordCount = ( ( opword >> 16 ) & 0xFFFF ); + auto opCode = ( (opword)&0xFFFF ); + + //debug( "wordCount: " << wordCount << " opcode: " << opCode ); + + auto& op = FindOpCode( opCode ); + + if( op != OP_CODE_NULL ) + { + uint32_t resultIndex{0}; + int resultIndexOffset = 1; + int32_t resultType{0u}; + + // make a copy + opCodes.emplace_back( op ); + auto& opcode = opCodes.back(); + opcode.localData.start = &*iter; + opcode.localData.count = wordCount; + + // update result type and index for non-void opcodes + if( op.hasResultType ) + { + resultIndexOffset++; + } + if( op.hasResult ) + { + if( op.hasResultType ) + { + resultType = static_cast(*( iter + 1 ) ); + } + resultIndex = *( iter + resultIndexOffset ); + opcode.localData.resultId = resultIndex; + opcode.localData.resultType = resultType; + if( opResults.size() <= opcode.localData.resultId ) + { + opResults.resize( opcode.localData.resultId + 1 ); + } + opResults[opcode.localData.resultId] = &opcode; + } + } + + // next instruction + std::advance( iter, wordCount ); + } + + for( auto&& opcode : opCodes ) + { + // OpTypePointer? Extract storage class and type it points to ( will be probably named ) + // - pointers usually are not named + // - objects they point at usually are named + // - pointers carry storage class qualifier + if( opcode == SpvOpTypePointer ) + { + auto storageClass = opcode.GetParameter( 1 ); // get storage class + auto refId = opcode.GetParameterU32( 2 ); // get type ref id + pointers.emplace_back( Pointer() = {&opcode, &FindByResultId( refId ), storageClass} ); + } + else if( opcode == SpvOpVariable ) + { + auto storageClass = opcode.GetParameter( 1 ); // get storage class + auto refId = opcode.GetParameterU32( 0 ); // get type ref id + pointers.emplace_back( Pointer() = {&opcode, &FindByResultId( refId ), storageClass} ); + } + else if( opcode == SpvOpName ) + { + auto refId = opcode.GetParameterU32( 0 ); // get type ref id + names.emplace_back( PointerName{} = {&opcode, &FindByResultId( refId ), false} ); + } + else if( opcode == SpvOpMemberName ) + { + auto refId = opcode.GetParameterU32( 0 ); // get type ref id + names.emplace_back( PointerName{} = {&opcode, &FindByResultId( refId ), true} ); + } + else if( opcode == SpvOpDecorate ) //@todo: member decorate + { + decorate.push_back( &opcode ); + } + } + + std::vector storageContainer{}; + + // Per each named resource build the resource map + // @todo simplify that! + for( auto&& name : names ) + { + std::string strName( name.opName->GetParameterAsString( name.isMemberName ? 2 : 1 ) ); + + // ignore member names + if( !strName.empty() && !name.isMemberName ) + { + SpvStorageClass storageClass{SpvStorageClassMax}; + Pointer* spvPointer{nullptr}; + + // resource descriptor + uint32_t resourceDescriptorSet{0u}; + uint32_t resourceLocation{0u}; + uint32_t resourceBinding{0u}; + uint32_t resourceAlignment{0u}; + + // Will contain storage + if( name.opRefId->code == SpvOpVariable ) + { + for( auto&& ptr : pointers ) + { + if( ptr.opCode->localData.resultId == name.opRefId->GetParameterU32( 0u ) ) + { + storageClass = ptr.storageClass; + spvPointer = &ptr; + + // look for all the decoration for the variable + for( auto&& decor : decorate ) + { + if( decor->GetParameterU32( 0 ) == name.opRefId->localData.resultId || + decor->GetParameterU32( 0 ) == ptr.pointerType->localData.resultId ) + { + auto decorationQualifier = decor->GetParameter( 1 ); + auto decorationParameter = decor->GetParameterU32( 2 ); + + if( decorationQualifier == SpvDecorationLocation ) + { + resourceLocation = decorationParameter; + } + else if( decorationQualifier == SpvDecorationBinding ) + { + resourceBinding = decorationParameter; + } + else if( decorationQualifier == SpvDecorationDescriptorSet ) + { + resourceDescriptorSet = decorationParameter; + } + else if( decorationQualifier == SpvDecorationAlignment ) + { + resourceAlignment = decorationParameter; + } + } + } + + //@todo: support input handling ( when vertex buffers work ) + if( storageClass == SpvStorageClassInput ) + { + } + break; + } + } + } + // if pointing at type, we need to find what refers to it among pointers and variables + else if( name.opRefId->isType ) + { + for( auto&& ptr : pointers ) + { + if( ptr.pointerType->localData.resultId == name.opRefId->GetParameterU32( 0u ) ) + { + const auto& instance = FindInstanceByType( ptr.opCode->localData.resultId ); + if( instance != OP_CODE_NULL ) + { + auto decors = FindDecorationsForId( instance.localData.resultId ); + + for( auto&& opDecorate : decors ) + { + auto decorationQualifier = opDecorate->GetParameter( 1 ); + auto decorationParameter = opDecorate->GetParameterU32( 2 ); + if( decorationQualifier == SpvDecorationLocation ) + { + resourceLocation = decorationParameter; + } + else if( decorationQualifier == SpvDecorationBinding ) + { + resourceBinding = decorationParameter; + } + else if( decorationQualifier == SpvDecorationDescriptorSet ) + { + resourceDescriptorSet = decorationParameter; + } + else if( decorationQualifier == SpvDecorationAlignment ) + { + resourceAlignment = decorationParameter; + } + } + } + storageClass = ptr.storageClass; + spvPointer = &ptr; + break; + } + } + } + + // add resource to the storage container + if( storageClass != SpvStorageClassMax ) + { + auto index = static_cast( storageClass ); + if( storageContainer.size() <= index ) + { + storageContainer.resize( index + 1 ); + } + + auto& container = storageContainer[index]; + container.storageClass = storageClass; + container.resources.push_back( {spvPointer} ); + + auto& resource = container.resources.back(); + resource.location = resourceLocation; + resource.binding = resourceBinding; + resource.descriptorSet = resourceDescriptorSet; + resource.alignment = resourceAlignment; + resource.name = strName; + } + } + } + + // Identify descriptor set types based on the usage within + // the shader ( ref. vulkan spec 1.0.68 ) + std::vector uniformResources; + for( auto&& storage : storageContainer ) + { + if( storage.storageClass == SpvStorageClassUniformConstant ) + { + for( auto&& resource : storage.resources ) + { + if( TestStorageImageDescriptor( resource ) ) + { + resource.descriptorType = vk::DescriptorType::eStorageImage; + } + else if( TestSamplerDescriptor( resource ) ) + { + resource.descriptorType = vk::DescriptorType::eSampler; + } + else if( TestSampledImageDescriptor( resource ) ) + { + resource.descriptorType = vk::DescriptorType::eSampledImage; + } + else if( TestCombinedImageSamplerDescriptor( resource ) ) + { + resource.descriptorType = vk::DescriptorType::eCombinedImageSampler; + } + else if( TestUniformTexelBufferDescriptor( resource ) ) + { + resource.descriptorType = vk::DescriptorType::eUniformTexelBuffer; + } + else if( TestStorageTexelBufferDescriptor( resource ) ) + { + resource.descriptorType = vk::DescriptorType::eStorageTexelBuffer; + } + else + { + // @todo check the shader, something hasn't been recognized + resource.descriptorType = vk::DescriptorType{}; + } + if( resource.descriptorType != vk::DescriptorType{} ) + { + uniformResources.push_back( &resource ); + } + } + } + else if( storage.storageClass == SpvStorageClassUniform ) + { + /** + * We need to test against 4 possible descriptor types: + * UniformBuffer + * StorageBuffer + * DynamicUniformBuffer + * DynamicStorageBuffer + * + * This information must be read directly from decoration + */ + for( auto&& resource : storage.resources ) + { + if( TestUniformBufferDescriptor( resource ) ) + { + resource.descriptorType = vk::DescriptorType::eUniformBuffer; + } + else if( TestStorageBufferDescriptor( resource ) ) + { + resource.descriptorType = vk::DescriptorType::eStorageBuffer; + } + else + { + resource.descriptorType = vk::DescriptorType{}; + } + if( resource.descriptorType != vk::DescriptorType{} ) + { + uniformResources.push_back( &resource ); + } + } + } + } + + // sort uniform resources by descriptor sets and bindings + std::sort( uniformResources.begin(), uniformResources.end(), ( []( const auto& lhs, const auto& rhs ) { + if( lhs->descriptorSet < rhs->descriptorSet ) + return true; + else if( lhs->binding < rhs->binding ) + return true; + else if( lhs->location < rhs->location ) + return true; + return false; + } ) ); + + GenerateDescriptorSetLayoutCreateInfo( uniformResources ); + debug( "done" ); + return true; + } + + /** + * Recognizes descriptor type VkDescriptorTypeStorageImage + * GLSL: + * layout (set=m, binding=n, r32f) uniform image2D myStorageImage; + * + * SPIR-V: + * %7 = OpTypeImage %6 2D 0 0 0 2 R32f + * %8 = OpTypePointer UniformConstant %7 + * %9 = OpVariable %8 UniformConstant + * @param resource + * @return + */ + bool TestStorageImageDescriptor( const ResourceDescriptor& resource ) + { + if( *resource.pointer->opCode == SpvOpTypePointer ) + { + auto& opCode = GetReferencedOpCode( *resource.pointer->opCode, 2 ); + if( opCode == SpvOpTypeImage && opCode.GetParameterU32( 6 ) == 2 ) + { + return true; + } + } + return false; + } + + /** + * Recognizes descriptor type VkDescriptorTypeSampler + * GLSL: + layout (set=m, binding=n) uniform sampler mySampler; + * + * SPIR-V: + %3 = OpTypeFunction %2 + %6 = OpTypeSampler + %7 = OpTypePointer UniformConstant %6 + %8 = OpVariable %7 UniformConstant + + * @param resource + * @return + */ + bool TestSamplerDescriptor( const ResourceDescriptor& resource ) + { + if( *resource.pointer->opCode == SpvOpTypePointer ) + { + auto& opCode = GetReferencedOpCode( *resource.pointer->opCode, 2 ); + if( opCode == SpvOpTypeSampler ) + { + return true; + } + } + return false; + } + + /** + * Recognizes descriptor type VkDescriptorTypeSampledImage + * GLSL: + * layout (set=m, binding=n) uniform texture2D mySampledImage; + * SPIR_V: + %6 = OpTypeFloat 32 + %7 = OpTypeImage %6 2D 0 0 0 1 Unknown + %8 = OpTypePointer UniformConstant %7 + %9 = OpVariable %8 UniformConstant + * + * @param resource + * @return + */ + bool TestSampledImageDescriptor( const ResourceDescriptor& resource ) + { + if( *resource.pointer->opCode == SpvOpTypePointer ) + { + auto& opCode = GetReferencedOpCode( *resource.pointer->opCode, 2 ); + if( opCode == SpvOpTypeImage && opCode.GetParameterU32( 6 ) == 1 ) + { + return true; + } + } + return false; + } + + /** + * Recognizes descriptor type VkDescriptorTypeCombinedImageSampler + * GLSL: + * layout (set=m, binding=n) uniform sampler2D myCombinedImageSampler; + * SPIR-V: + %7 = OpTypeImage %6 2D 0 0 0 1 Unknown + %8 = OpTypeSampledImage %7 + %9 = OpTypePointer UniformConstant %8 + %10 = OpVariable %9 UniformConstant + * @param resource + * @return + */ + bool TestCombinedImageSamplerDescriptor( const ResourceDescriptor& resource ) + { + if( *resource.pointer->opCode == SpvOpTypePointer ) + { + auto& opCode = GetReferencedOpCode( *resource.pointer->opCode, 2 ); + if( opCode == SpvOpTypeSampledImage ) + { + return true; + } + } + return false; + } + + /** + * Recognizes descriptor type VkDescriptorTypeUniformTexelBuffer + * GLSL: + * layout (set=m, binding=n) uniform samplerBuffer myUniformTexelBuffer; + * SPIR-V: + %6 = OpTypeFloat 32 + %7 = OpTypeImage %6 Buffer 0 0 0 1 Unknown + %8 = OpTypePointer UniformConstant %7 + %9 = OpVariable %8 UniformConstant + * @param resource + * @return + */ + bool TestUniformTexelBufferDescriptor( const ResourceDescriptor& resource ) + { + if( *resource.pointer->opCode == SpvOpTypePointer ) + { + auto& opCode = GetReferencedOpCode( *resource.pointer->opCode, 2 ); + if( opCode == SpvOpTypeImage && opCode.GetParameter( 2 ) == SpvDimBuffer && + opCode.GetParameterU32( 6 ) == 1 ) + { + return true; + } + } + return false; + } + + /** + * Recognizes descriptor type VkDescriptorTypeStorageTexelBuffer + * GLSL: + * layout (set=m, binding=n, r32f) uniform imageBuffer myStorageTexelBuffer; + * SPIR-V: + %7 = OpTypeImage %6 Buffer 0 0 0 2 R32f + %8 = OpTypePointer UniformConstant %7 + %9 = OpVariable %8 UniformConstant + * @param resource + * @return + */ + bool TestStorageTexelBufferDescriptor( const ResourceDescriptor& resource ) + { + if( *resource.pointer->opCode == SpvOpTypePointer ) + { + auto& opCode = GetReferencedOpCode( *resource.pointer->opCode, 2 ); + if( opCode == SpvOpTypeImage && opCode.GetParameter( 2 ) == SpvDimBuffer && + opCode.GetParameterU32( 6 ) == 2 ) + { + return true; + } + } + return false; + } + + /** + * Recognizes descriptor type VkDescriptorTypeUniformBuffer + * GLSL: + layout (set=m, binding=n) uniform myUniformBuffer + { + vec4 myElement[32]; + }; + * SPIR-V: + %11 = OpTypeStruct %10 + %12 = OpTypePointer Uniform %11 + %13 = OpVariable %12 Uniform + * @todo pull data out of OpDecorate ( Block ) + * @param resource + * @return + */ + bool TestUniformBufferDescriptor( const ResourceDescriptor& resource ) + { + auto& ptrOpCode( *resource.pointer->opCode ); + if( ptrOpCode == SpvOpTypePointer && ptrOpCode.GetParameter( 1 ) == SpvStorageClassUniform ) + { + auto& opTypeStruct = GetReferencedOpCode( ptrOpCode, 2 ); + if( opTypeStruct == SpvOpTypeStruct ) + { + return CheckDecorationForOpId( opTypeStruct, SpvDecorationBlock ); + } + } + return false; + } + + bool TestStorageBufferDescriptor( const ResourceDescriptor& resource ) + { + auto& ptrOpCode( *resource.pointer->opCode ); + if( ptrOpCode == SpvOpTypePointer && ptrOpCode.GetParameter( 1 ) == SpvStorageClassUniform ) + { + auto& opTypeStruct = GetReferencedOpCode( ptrOpCode, 2 ); + if( opTypeStruct == SpvOpTypeStruct ) + { + return CheckDecorationForOpId( opTypeStruct, SpvDecorationBufferBlock ); + } + } + return false; + } + + void GenerateDescriptorSetLayoutCreateInfo( const std::vector& uniformResources ) + { + auto currentSet = -1u; + auto currentBinding = -1u; + + for( auto&& resource : uniformResources ) + { + // if descriptor set changed, increment + if( resource->descriptorSet != currentSet ) + { + // finalize current set + if( currentSet != -1u ) + { + auto& layoutData = layoutCreateInfoCache.back(); + layoutData.createInfo.setPBindings( layoutData.bindings.data() ) + .setBindingCount( U32( layoutData.bindings.size() ) ); + } + currentSet = resource->descriptorSet; + if( currentSet == -1u || layoutCreateInfoCache.size() <= currentSet ) + { + layoutCreateInfoCache.resize(currentSet+1); + } + layoutCreateInfoCache.back() = {vk::DescriptorSetLayoutCreateInfo{}.setBindingCount( 0u ).setPBindings( nullptr ), {}}; + currentBinding = -1u; + } + + auto& layoutData = layoutCreateInfoCache.back(); + + if( resource->binding != currentBinding ) + { + currentBinding = resource->binding; + layoutData.bindings.emplace_back( vk::DescriptorSetLayoutBinding{} ); + auto& binding = layoutData.bindings.back(); + binding.setBinding( resource->binding ); + binding.setDescriptorType( resource->descriptorType ); + binding.setDescriptorCount( 1 ); //@todo: support arrays! + binding.setStageFlags( shaderStages ); + } + else + { + //@todo assert that bindings overlap within same descriptor set!!! + } + } + // finalize current set + if( currentSet != -1u ) + { + auto& layoutData = layoutCreateInfoCache.back(); + layoutData.createInfo.setPBindings( layoutData.bindings.data() ) + .setBindingCount( U32( layoutData.bindings.size() ) ); + } + } + + std::vector GenerateDescriptorSetLayoutCreateInfo() const + { + std::vector retval{}; + + retval.resize( layoutCreateInfoCache.size() ); + auto i = 0u; + for( auto&& layout : retval ) + { + layout = layoutCreateInfoCache[i++].createInfo; + } + return retval; + } + + /** + * Tests if the header is valid for SPIR-V + * @return + */ + bool CheckHeader() + { + header = *reinterpret_cast( data.data() ); + return MAGIC_NUMBER == header.magicNumber; + } + +public: + + std::vector opCodes; // contains all opcodes + std::vector opResults; // links to the resulting opcode or nullptr if opcode doesn't return + + /** + * The cache of generated create info structures, it's necessary to keep it + * due to object lifetime. + * The ownership is passed to the caller ( opaque object ). It must exist as long + * as the device::CreateDescriptorSetLayout() returns! + */ + struct LayoutAndBindings + { + vk::DescriptorSetLayoutCreateInfo createInfo; + std::vector bindings; + }; + + std::vector layoutCreateInfoCache{}; + + std::vector data; + std::vector names{}; + std::vector decorate{}; + + Header header; + + vk::ShaderStageFlags shaderStages{}; +}; +#pragma GCC diagnostic pop + + +/************************************************************************************** + * SPIRVShader + */ + +SPIRVShader::SPIRVShader() = default; + +SPIRVShader::~SPIRVShader() = default; + +SPIRVShader::SPIRVShader( SPIRVShader&& shader ) noexcept = default; + +SPIRVShader::SPIRVShader( Impl& impl ) +{ + mImpl.reset( &impl ); +} + +SPIRVShader::SPIRVShader( std::vector code, vk::ShaderStageFlags stages ) +{ + mImpl = std::make_unique( code, stages ); +} + +std::vector SPIRVShader::GenerateDescriptorSetLayoutCreateInfo() const +{ + return mImpl->GenerateDescriptorSetLayoutCreateInfo(); +} + +uint32_t SPIRVShader::GetOpCodeCount() const +{ + return static_cast( mImpl->opCodes.size() ); +} + +const SPIRVOpCode* SPIRVShader::GetOpCodeAt( uint32_t index ) const +{ + return &mImpl->opCodes[index]; +} + +const SPIRVOpCode* SPIRVShader::GetOpCodeForResultId( uint32_t resultId ) const +{ + return mImpl->opResults[resultId]; +} + +SPIRVWord SPIRVShader::GetOpCodeParameterWord( const SPIRVOpCode& opCode, uint32_t index ) const +{ + return GetOpCodeParameter( opCode, index ); +} + +SpvOp SPIRVShader::GetOpCodeType( SPIRVOpCode& opCode ) +{ + return SpvOpMax; +} + +const uint32_t* SPIRVShader::GetOpCodeParameterPtr( const SPIRVOpCode& opCode, uint32_t index ) const +{ + return ( opCode.localData.start + index + 1 ); +} + +/************************************************************************************** + * SPIRVUtils + */ + +/** + * SPIRVUtils + * @param data + * @return + */ +std::unique_ptr SPIRVUtils::Parse( std::vector data, vk::ShaderStageFlags stages ) +{ + auto shader = std::unique_ptr( new SPIRVShader( data, stages ) ); + if( !shader->GetImplementation().Initialise() ) + { + return nullptr; + } + return shader; +} + +std::unique_ptr SPIRVUtils::Parse( const SPIRVWord* data, size_t sizeInBytes, vk::ShaderStageFlags stages ) +{ + std::vector spirvCode{}; + auto wordSize = sizeInBytes / sizeof(SPIRVWord); + spirvCode.resize( wordSize ); + std::copy( data, data+wordSize, spirvCode.begin()); + return Parse( spirvCode, stages ); +} + +} // namespace SpirV + +} // namespace Vulkan + +} // namespace Graphics + +} // namespace Dali \ No newline at end of file diff --git a/dali/graphics/vulkan/spirv/vulkan-spirv.h b/dali/graphics/vulkan/spirv/vulkan-spirv.h new file mode 100644 index 0000000..6e3b8fc --- /dev/null +++ b/dali/graphics/vulkan/spirv/vulkan-spirv.h @@ -0,0 +1,174 @@ +/* + * Copyright (c) 2018 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef DALI_GRAPHICS_VULKAN_SPIRV_SPIRV_H +#define DALI_GRAPHICS_VULKAN_SPIRV_SPIRV_H + +#include +#include +#include + +namespace Dali +{ +namespace Graphics +{ +namespace Vulkan +{ +namespace SpirV +{ + +// include C header +#include "spirv.h" + +using SPIRVWord = uint32_t; + +/** + * Opcode storage, doesn't expose direct interface, must be used within + * SPIRVShader context + */ +struct SPIRVOpCode; + +/** + * Defines SPIRVShader program + */ +class SPIRVShader +{ + friend class SPIRVUtils; + +public: + + SPIRVShader( SPIRVShader&& shader ) noexcept; + SPIRVShader( const SPIRVShader& shader ) = delete; + ~SPIRVShader(); + + /** + * Generates descriptor set layout info from the supplied shader + * @note This function does not create the layout itself! + * @return create info structure + */ + std::vector GenerateDescriptorSetLayoutCreateInfo() const; + + /** + * Returns total number of OpCodes + * @return + */ + uint32_t GetOpCodeCount() const; + + /** + * Returns OpCode at specified index + * @param index + * @return + */ + const SPIRVOpCode* GetOpCodeAt( uint32_t index ) const; + + /** + * Returns OpCode associated with specified result id + * @param resultId + * @return + */ + const SPIRVOpCode* GetOpCodeForResultId( uint32_t resultId ) const; + + /** + * SPIRVOpCode API + */ + + /** + * Helper function that allows to convert SPIRVWords into requested type + * @tparam T + * @param index + * @return + */ + template + T GetOpCodeParameter( const SPIRVOpCode& opCode, uint32_t index ) const + { + return *reinterpret_cast( GetOpCodeParameterPtr( opCode, index ) ); + } + + /** + * Returns SPIRV parameter as 32bit SPIRVWord + * @param index + * @return + */ + SPIRVWord GetOpCodeParameterWord( const SPIRVOpCode& opCode,uint32_t index ) const; + + /** + * + * @param opCode + * @return + */ + SpvOp GetOpCodeType( SPIRVOpCode& opCode ); + +private: + + /** + * Accesses parameter via pointer + * @param index + * @return + */ + const uint32_t* GetOpCodeParameterPtr( const SPIRVOpCode& opCode, uint32_t index ) const; + + struct Impl; + std::unique_ptr mImpl; + + explicit SPIRVShader( Impl& impl ); + + SPIRVShader(); + + /** + * Constructor that should be called only from SPIRVUtils + * @param code + */ + explicit SPIRVShader( std::vector code, vk::ShaderStageFlags stages ); + +public: + /** + * Accessor to the implementation object + * @return + */ + Impl& GetImplementation() const; +}; + + + +/** + * Simple set + */ +class SPIRVUtils +{ +public: + + /** + * Creates SPIRVShader instance + * @param data + * @return + */ + static std::unique_ptr Parse( std::vector data, vk::ShaderStageFlags stages ); + + static std::unique_ptr Parse( const SPIRVWord* data, size_t sizeInBytes, vk::ShaderStageFlags stages ); + +private: + + struct Impl; + std::unique_ptr mImpl; +}; + +} +} // namespace Vulkan +} // namespace Graphics +} // namespace Dali + +#endif // DALI_GRAPHICS_VULKAN_SPIRV_SPIRV_H diff --git a/dali/graphics/vulkan/vulkan-command-buffer.cpp b/dali/graphics/vulkan/vulkan-command-buffer.cpp index bef027a..027622d 100644 --- a/dali/graphics/vulkan/vulkan-command-buffer.cpp +++ b/dali/graphics/vulkan/vulkan-command-buffer.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -146,8 +146,8 @@ struct CommandBuffer::Impl break; case vk::ImageLayout::ePresentSrcKHR: { - srcStageMask = vk::PipelineStageFlagBits::eBottomOfPipe; - srcAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eColorAttachmentRead; + srcStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput; + srcAccessMask = vk::AccessFlagBits::eMemoryRead | vk::AccessFlagBits::eColorAttachmentRead; } break; case vk::ImageLayout::eColorAttachmentOptimal: @@ -172,8 +172,8 @@ struct CommandBuffer::Impl { case vk::ImageLayout::eColorAttachmentOptimal: { - dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput | vk::PipelineStageFlagBits::eFragmentShader; - dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eHostWrite; + dstStageMask = vk::PipelineStageFlagBits::eColorAttachmentOutput;// | */vk::PipelineStageFlagBits::eFragmentShader; + dstAccessMask = vk::AccessFlagBits::eColorAttachmentWrite | vk::AccessFlagBits::eMemoryWrite; break; } case vk::ImageLayout::eDepthStencilAttachmentOptimal: @@ -438,6 +438,7 @@ void CommandBuffer::ImageLayoutTransition( vk::Image image, mImpl->ImageLayoutTransition( image, oldLayout, newLayout, aspectMask ); } +/* void CommandBuffer::RecordImageLayoutTransition( vk::Image image, vk::AccessFlags srcAccessMask, vk::AccessFlags dstAccessMask, @@ -450,7 +451,7 @@ void CommandBuffer::RecordImageLayoutTransition( vk::Image image, mImpl->RecordImageLayoutTransition( image, srcAccessMask, dstAccessMask, srcStageMask, dstStageMask, oldLayout, newLayout, aspectMask ); } - +*/ /** Push wait semaphores */ void CommandBuffer::PushWaitSemaphores( const std::vector& semaphores, const std::vector& stages ) diff --git a/dali/graphics/vulkan/vulkan-descriptor-set.cpp b/dali/graphics/vulkan/vulkan-descriptor-set.cpp index 67495d0..d51a23b 100644 --- a/dali/graphics/vulkan/vulkan-descriptor-set.cpp +++ b/dali/graphics/vulkan/vulkan-descriptor-set.cpp @@ -198,23 +198,7 @@ vk::DescriptorSet DescriptorSet::GetVkDescriptorSet() const } - - - - - - - - - - - - - - - - - +#if 0 struct DescriptorSetLayout::Impl { Impl( Graphics& graphics, const vk::DescriptorSetLayoutCreateInfo& createInfo ) : @@ -264,7 +248,7 @@ DescriptorSetLayout::DescriptorSetLayout( Graphics& graphics, const vk::Descript { mImpl = MakeUnique( graphics, createInfo ); } - +#endif } // Namespace Vulkan } // Namespace Graphics diff --git a/dali/graphics/vulkan/vulkan-descriptor-set.h b/dali/graphics/vulkan/vulkan-descriptor-set.h index 3b1da88..c42c3fc 100644 --- a/dali/graphics/vulkan/vulkan-descriptor-set.h +++ b/dali/graphics/vulkan/vulkan-descriptor-set.h @@ -107,7 +107,7 @@ private: std::unique_ptr mImpl; }; - +#if 0 class DescriptorSetLayout { public: @@ -123,7 +123,7 @@ private: class Impl; std::unique_ptr mImpl; }; - +#endif } // Namespace Vulkan } // Namespace Graphics diff --git a/dali/graphics/vulkan/vulkan-graphics-controller.cpp b/dali/graphics/vulkan/vulkan-graphics-controller.cpp index 95a7371..8f715e6 100644 --- a/dali/graphics/vulkan/vulkan-graphics-controller.cpp +++ b/dali/graphics/vulkan/vulkan-graphics-controller.cpp @@ -65,24 +65,7 @@ struct Controller::Impl #pragma GCC diagnostic ignored "-Wframe-larger-than=" bool Initialise() { - // create shaders - auto bindings = - std::vector{// francisco buffer - vk::DescriptorSetLayoutBinding{} - .setBinding( 0 ) - .setStageFlags( vk::ShaderStageFlagBits::eVertex ) - .setDescriptorType( vk::DescriptorType::eUniformBuffer ) - .setDescriptorCount( 1 ), - // clip matrix - vk::DescriptorSetLayoutBinding{} - .setBinding( 1 ) - .setStageFlags( vk::ShaderStageFlagBits::eVertex ) - .setDescriptorType( vk::DescriptorType::eUniformBuffer ) - .setDescriptorCount( 1 )}; - mDebugPipelineState.vertexShader = Shader::New( mGraphics, VSH_CODE.data(), VSH_CODE.size() ); - mDebugPipelineState.vertexShader->SetDescriptorSetLayout( - 0, vk::DescriptorSetLayoutCreateInfo{}.setBindingCount( 2 ).setPBindings( bindings.data() ) ); mDebugPipelineState.fragmentShader = Shader::New( mGraphics, FSH_CODE.data(), FSH_CODE.size() ); @@ -223,7 +206,7 @@ struct Controller::Impl auto descriptorSets = state.descriptorPool->AllocateDescriptorSets( vk::DescriptorSetAllocateInfo{}.setDescriptorSetCount( 1 ).setPSetLayouts( - state.vertexShader->GetDescriptorSetLayouts().data() ) ); + state.pipeline->GetVkDescriptorSetLayouts().data() ) ); descriptorSets[0]->WriteUniformBuffer( 0, state.uniformBuffer0, i * uniformBlockOffsetStride, stride ); descriptorSets[0]->WriteUniformBuffer( 1, state.uniformBuffer1, 0, state.uniformBuffer1->GetSize() ); diff --git a/dali/graphics/vulkan/vulkan-graphics.cpp b/dali/graphics/vulkan/vulkan-graphics.cpp index d1ea784..f9eb369 100644 --- a/dali/graphics/vulkan/vulkan-graphics.cpp +++ b/dali/graphics/vulkan/vulkan-graphics.cpp @@ -189,7 +189,7 @@ void Graphics::Create() { for( auto&& prop : layers.value ) { - //std::cout << prop.layerName << std::endl; + std::cout << prop.layerName << std::endl; if( std::string(prop.layerName) == reqLayer ) { validationLayers.push_back(reqLayer); @@ -207,8 +207,8 @@ void Graphics::CreateInstance( const std::vector& extensions, const info.setEnabledExtensionCount(U32(extensions.size())) .setPpEnabledExtensionNames(extensions.data()) - //.setEnabledLayerCount(U32(validationLayers.size())) - .setEnabledLayerCount(0) + .setEnabledLayerCount(U32(validationLayers.size())) + //.setEnabledLayerCount(0) .setPpEnabledLayerNames(validationLayers.data()); mInstance = VkAssert(vk::createInstance(info, *mAllocator)); diff --git a/dali/graphics/vulkan/vulkan-pipeline.cpp b/dali/graphics/vulkan/vulkan-pipeline.cpp index e7ca9ea..00971b3 100644 --- a/dali/graphics/vulkan/vulkan-pipeline.cpp +++ b/dali/graphics/vulkan/vulkan-pipeline.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,8 @@ #include #include #include +#include +#include namespace Dali { @@ -26,12 +28,19 @@ namespace Graphics namespace Vulkan { +namespace +{ +static const vk::ShaderStageFlags DEFAULT_SHADER_STAGES{ vk::ShaderStageFlagBits::eVertex|vk::ShaderStageFlagBits::eFragment }; +} + /** * Class Pipeline::Impl * Internal implementation of the pipeline */ struct Pipeline::Impl { + + Impl( Vulkan::Graphics& graphics, const vk::GraphicsPipelineCreateInfo& info ) : mInfo( info ), mGraphics( graphics ) @@ -222,7 +231,6 @@ struct Pipeline::Impl setModule( *shader ). setStage( static_cast( stage ) ). setPName( "main" ); - mShaderStageCreateInfo.push_back( info ); mShaderResources.push_back( shader ); @@ -233,40 +241,84 @@ struct Pipeline::Impl } /** + * Creates deferred pipeline layout. Since not all the shader modules + * are supplied in one go the layout creation first must instantiate + * correct descriptor set layouts. * + * @todo: Store SPIRV data of shader modules in the cache rather than + * parsing every time */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wframe-larger-than=" void CreatePipelineLayout() { // pull desciptor set layouts from shaders auto layoutInfo = vk::PipelineLayoutCreateInfo{}; - //info.setPSetLayouts( vk::DescriptorSetLayout ) + using DSLayoutBindingArray = std::vector; + + std::vector allDescriptorSetLayouts; - std::vector allLayouts{}; + // concatenate all bindings + // TODO: @todo validate if there are weird overlaps! for( auto&& shader : mShaderResources ) { - auto& layouts = shader->GetDescriptorSetLayouts(); - if( layouts.size() ) + const auto& reflection = shader->GetSPIRVReflection(); + auto layouts = reflection.GenerateDescriptorSetLayoutCreateInfo(); + + if(allDescriptorSetLayouts.size() < layouts.size()) + { + allDescriptorSetLayouts.resize(layouts.size()); + } + + for( auto i = 0u; i < layouts.size(); ++i ) { - allLayouts.resize(layouts.size()); - for (auto i = 0u; i < layouts.size(); ++i) + auto currIndex = allDescriptorSetLayouts[i].size(); + allDescriptorSetLayouts[i].insert( allDescriptorSetLayouts[i].end(), + layouts[i].pBindings, layouts[i].pBindings + layouts[i].bindingCount ); + for( auto j = 0u; j < layouts[i].bindingCount; ++j ) { - if (layouts[i]) - { - allLayouts[i] = layouts[i]; - } + allDescriptorSetLayouts[i][j+currIndex].setStageFlags( GetShaderStage( shader ) ); } } } - layoutInfo.setPSetLayouts( allLayouts.data() ); - layoutInfo.setSetLayoutCount( static_cast(allLayouts.size()) ); + // create descriptor set layouts for the pipeline + std::vector dsLayouts{}; + dsLayouts.resize( allDescriptorSetLayouts.size() ); + mDSCreateInfoArray.clear(); + for( auto i = 0u; i < allDescriptorSetLayouts.size(); ++i ) + { + auto info = vk::DescriptorSetLayoutCreateInfo{}. + setBindingCount( static_cast(allDescriptorSetLayouts[i].size()) ). + setPBindings( allDescriptorSetLayouts[i].data() ); + + mDSCreateInfoArray.push_back( info ); + dsLayouts[i] = VkAssert( mGraphics.GetDevice().createDescriptorSetLayout( info, mGraphics.GetAllocator() ) ); + } + + // create pipeline layout + layoutInfo.setPSetLayouts( dsLayouts.data() ); + layoutInfo.setSetLayoutCount( static_cast(dsLayouts.size()) ); mPipelineLayout = VkAssert( mGraphics.GetDevice().createPipelineLayout( layoutInfo, mGraphics.GetAllocator() ) ); + mDSLayoutArray = dsLayouts; mInfo.setLayout( mPipelineLayout ); } +#pragma GCC diagnostic pop + vk::ShaderStageFlagBits GetShaderStage( ShaderRef shader ) + { + for( auto&& stage : mShaderStageCreateInfo ) + { + if( stage.module == *shader ) + { + return stage.stage; + } + } + return vk::ShaderStageFlagBits{}; + } bool Compile() { @@ -281,7 +333,18 @@ struct Pipeline::Impl auto shaderHandle = mGraphics.FindShader( stage.module ); if( shaderHandle ) { - mShaderResources.push_back( shaderHandle ); + bool tracked { false }; + for(auto&& sh : mShaderResources ) + { + if( sh == shaderHandle ) + { + tracked = true; + } + } + if(!tracked) + { + mShaderResources.push_back(shaderHandle); + } } else { @@ -298,7 +361,7 @@ struct Pipeline::Impl Graphics& mGraphics; // resources - std::vector> mShaderResources; + std::vector mShaderResources; vk::PipelineViewportStateCreateInfo mViewportState {}; std::vector mViewports {}; @@ -306,6 +369,8 @@ struct Pipeline::Impl std::vector mShaderStageCreateInfo; vk::PipelineLayout mPipelineLayout{}; + std::vector mDSCreateInfoArray{}; + std::vector mDSLayoutArray{}; // vertex input state vk::PipelineVertexInputStateCreateInfo mVertexInputState {}; @@ -389,6 +454,16 @@ vk::PipelineLayout Pipeline::GetVkPipelineLayout() const return mImpl->mPipelineLayout; } +const std::vector& Pipeline::GetVkDescriptorSetLayoutCreateInfo() const +{ + return mImpl->mDSCreateInfoArray; +} + +const std::vector& Pipeline::GetVkDescriptorSetLayouts() const +{ + return mImpl->mDSLayoutArray; +} + } // namespace Vulkan } // namespace Graphics diff --git a/dali/graphics/vulkan/vulkan-pipeline.h b/dali/graphics/vulkan/vulkan-pipeline.h index 9197f4e..3f1dd8f 100644 --- a/dali/graphics/vulkan/vulkan-pipeline.h +++ b/dali/graphics/vulkan/vulkan-pipeline.h @@ -77,12 +77,26 @@ public: * @param restartEnable */ void SetInputAssemblyState( vk::PrimitiveTopology topology, bool restartEnable ); + /** * * @return */ bool Compile(); + /** + * + * @return + */ + const std::vector& GetVkDescriptorSetLayoutCreateInfo() const; + + /** + * + * @return + */ + const std::vector& GetVkDescriptorSetLayouts() const; + + private: Pipeline( Graphics& graphics, const vk::GraphicsPipelineCreateInfo& info ); diff --git a/dali/graphics/vulkan/vulkan-shader.cpp b/dali/graphics/vulkan/vulkan-shader.cpp index fa96b2f..d2d46f2 100644 --- a/dali/graphics/vulkan/vulkan-shader.cpp +++ b/dali/graphics/vulkan/vulkan-shader.cpp @@ -17,7 +17,8 @@ #include #include - +#include +#include namespace Dali { namespace Graphics @@ -35,17 +36,11 @@ struct Shader::Impl mGraphics( graphics ), mCreateInfo( info ) { + mSPIRVShader = SpirV::SPIRVUtils::Parse( info.pCode, info.codeSize, vk::ShaderStageFlagBits::eVertex ); } ~Impl() { - if(mDSLayouts.size()) - { - for(auto&& ds : mDSLayouts ) - { - mGraphics.GetDevice().destroyDescriptorSetLayout( ds, mGraphics.GetAllocator() ); - } - } if(mShaderModule) { mGraphics.GetDevice().destroyShaderModule( mShaderModule, mGraphics.GetAllocator() ); @@ -66,35 +61,11 @@ struct Shader::Impl return mShaderModule; } - - // creates new descriptor set layout - // TODO: should be read from the shader and any manual setting should not - // take place after we have proper reflection! - void SetDescriptorSetLayout( uint32_t set, vk::DescriptorSetLayoutCreateInfo info ) - { - auto layout = VkAssert( mGraphics.GetDevice().createDescriptorSetLayout( info, mGraphics.GetAllocator() ) ); - if( mDSLayouts.size() >= set ) - { - mDSLayouts.resize( set+1 ); - } - else if ( mDSLayouts[set] ) // already existing set ( this is error but for now handle it ) - { - mGraphics.GetDevice().destroyDescriptorSetLayout( mDSLayouts[set], mGraphics.GetAllocator() ); - } - mDSLayouts[set] = layout; - } - - const std::vector& GetDescriptorSetLayouts() const - { - return mDSLayouts; - } - - Shader& mOwner; Graphics& mGraphics; vk::ShaderModuleCreateInfo mCreateInfo; vk::ShaderModule mShaderModule; - std::vector mDSLayouts; // descriptorset layouts + std::unique_ptr mSPIRVShader; }; /* @@ -138,15 +109,11 @@ bool Shader::OnDestroy() return true; } -void Shader::SetDescriptorSetLayout( uint32_t set, vk::DescriptorSetLayoutCreateInfo info ) +const SpirV::SPIRVShader& Shader::GetSPIRVReflection() const { - mImpl->SetDescriptorSetLayout( set, info ); + return *mImpl->mSPIRVShader; } -const std::vector& Shader::GetDescriptorSetLayouts() const -{ - return mImpl->GetDescriptorSetLayouts(); -} } } } \ No newline at end of file diff --git a/dali/graphics/vulkan/vulkan-shader.h b/dali/graphics/vulkan/vulkan-shader.h index 1c0a997..c4ffe59 100644 --- a/dali/graphics/vulkan/vulkan-shader.h +++ b/dali/graphics/vulkan/vulkan-shader.h @@ -27,6 +27,11 @@ namespace Graphics { namespace Vulkan { +namespace SpirV +{ +class SPIRVShader; +} + class Graphics; class Shader : public VkManaged // can be overriden as ShaderGLSL for example { @@ -64,7 +69,7 @@ public: vk::ShaderModule GetVkShaderModule() const; - const std::vector& GetDescriptorSetLayouts() const; + const SpirV::SPIRVShader& GetSPIRVReflection() const; bool OnDestroy() override; diff --git a/dali/graphics/vulkan/vulkan-standalone-test.cpp b/dali/graphics/vulkan/vulkan-standalone-test.cpp index bb4cafd..f87ec77 100644 --- a/dali/graphics/vulkan/vulkan-standalone-test.cpp +++ b/dali/graphics/vulkan/vulkan-standalone-test.cpp @@ -42,6 +42,7 @@ using namespace glm; #include #include #include +#include #define USE_XLIB 0 #include @@ -50,7 +51,6 @@ using Dali::Graphics::Vulkan::Buffer; using Dali::Graphics::Vulkan::CommandBuffer; using Dali::Graphics::Vulkan::CommandPool; using Dali::Graphics::Vulkan::DescriptorPool; -using Dali::Graphics::Vulkan::DescriptorSetLayout; using Dali::Graphics::Vulkan::GpuMemoryAllocator; using Dali::Graphics::Vulkan::GpuMemoryManager; using Dali::Graphics::Vulkan::Pipeline; @@ -444,20 +444,6 @@ int RunTestMain() // shaders auto vertexShader = Shader::New( gr, VSH_CODE.data(), VSH_CODE.size() ); - vertexShader->SetDescriptorSetLayout( - 0, - vk::DescriptorSetLayoutCreateInfo{}.setBindingCount( 2 ).setPBindings( - std::vector{vk::DescriptorSetLayoutBinding{} - .setBinding( 0 ) - .setStageFlags( vk::ShaderStageFlagBits::eVertex ) - .setDescriptorType( vk::DescriptorType::eUniformBuffer ) - .setDescriptorCount( 1 ), - vk::DescriptorSetLayoutBinding{} - .setBinding( 1 ) - .setStageFlags( vk::ShaderStageFlagBits::eVertex ) - .setDescriptorType( vk::DescriptorType::eUniformBuffer ) - .setDescriptorCount( 1 )} - .data() ) ); auto fragmentShader = Shader::New( gr, FSH_CODE.data(), FSH_CODE.size() ); @@ -465,10 +451,6 @@ int RunTestMain() auto vertexBuffer = Buffer::New( gr, sizeof( float ) * 3 * 3, Buffer::Type::VERTEX ); auto descriptorPool = create_descriptor_pool( gr ); - auto descriptorSet = descriptorPool->AllocateDescriptorSets( - vk::DescriptorSetAllocateInfo{} - .setPSetLayouts( vertexShader->GetDescriptorSetLayouts().data() ) - .setDescriptorSetCount( static_cast( vertexShader->GetDescriptorSetLayouts().size() ) ) ); auto& gpuManager = gr.GetDeviceMemoryManager(); @@ -483,6 +465,12 @@ int RunTestMain() auto pipeline = create_pipeline( gr, vertexShader, fragmentShader ); + auto descriptorSet = descriptorPool->AllocateDescriptorSets( + vk::DescriptorSetAllocateInfo{} + .setPSetLayouts( pipeline->GetVkDescriptorSetLayouts().data() ) + .setDescriptorSetCount( pipeline->GetVkDescriptorSetLayouts().size() ) ); + + auto commandPool = CommandPool::New( gr ); auto uniformBuffer = create_uniform_buffer( gr ); @@ -531,9 +519,35 @@ int RunTestMain() } return 0; } + + +using namespace Dali::Graphics::Vulkan::SpirV; +void spirv_test0( std::vector code ) +{ + auto shader = SPIRVUtils::Parse( code, vk::ShaderStageFlagBits::eVertex ); + auto opcodeCount = shader->GetOpCodeCount(); + std::cout << "opcodecount" << opcodeCount << std::endl; + + auto layoutCreateInfo = shader->GenerateDescriptorSetLayoutCreateInfo(); + + std::cout<< "yay!" < data; + data.resize( VSH_CODE.size()/4 ); + std::copy( VSH_CODE.begin(), VSH_CODE.end(), reinterpret_cast(data.data()) ); + spirv_test0( data ); +} + + } // namespace VulkanTest int main() { VulkanTest::RunTestMain(); + + //VulkanTest::RunSPIRVTest(); } -- 2.7.4