[Vulkan] SPIRV simplified reflection ( work in progress )
authoradam.b <jsr184@gmail.com>
Thu, 8 Mar 2018 16:45:15 +0000 (16:45 +0000)
committersidein74 <sidein74@gmail.com>
Mon, 19 Mar 2018 09:26:07 +0000 (04:26 -0500)
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

19 files changed:
dali/graphics/file.list
dali/graphics/vulkan/generated/spv-shaders-gen.cpp
dali/graphics/vulkan/generated/spv-shaders-gen.h
dali/graphics/vulkan/shaders/basic-shader.vert
dali/graphics/vulkan/shaders/experimental-shader.vert [new file with mode: 0644]
dali/graphics/vulkan/spirv/spirv.h [new file with mode: 0644]
dali/graphics/vulkan/spirv/vulkan-spirv-opcode.h [new file with mode: 0644]
dali/graphics/vulkan/spirv/vulkan-spirv.cpp [new file with mode: 0644]
dali/graphics/vulkan/spirv/vulkan-spirv.h [new file with mode: 0644]
dali/graphics/vulkan/vulkan-command-buffer.cpp
dali/graphics/vulkan/vulkan-descriptor-set.cpp
dali/graphics/vulkan/vulkan-descriptor-set.h
dali/graphics/vulkan/vulkan-graphics-controller.cpp
dali/graphics/vulkan/vulkan-graphics.cpp
dali/graphics/vulkan/vulkan-pipeline.cpp
dali/graphics/vulkan/vulkan-pipeline.h
dali/graphics/vulkan/vulkan-shader.cpp
dali/graphics/vulkan/vulkan-shader.h
dali/graphics/vulkan/vulkan-standalone-test.cpp

index 0860f36..6ec3e20 100644 (file)
@@ -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
 
 
+
index 7cb07c3..a6b8988 100644 (file)
@@ -140,7 +140,7 @@ std::vector<uint8_t> VSH_CODE = {
 };
 std::vector<uint8_t> 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<uint8_t> 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
index 90d6511..5a4709f 100644 (file)
@@ -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<uint8_t> 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));
 }*/
 
 
index d60999c..20ac3f7 100644 (file)
@@ -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 (file)
index 0000000..9a091c3
--- /dev/null
@@ -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 (file)
index 0000000..d1f5792
--- /dev/null
@@ -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 (file)
index 0000000..81cd2e0
--- /dev/null
@@ -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<uint32_t>( -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<uint32_t>(op) );
+  }
+
+  template<class T>
+  T GetParameter( uint32_t index ) const
+  {
+    return static_cast<T>( *( localData.start + index + 1 ) );
+  }
+
+  uint32_t GetParameterU32( uint32_t index ) const
+  {
+    return GetParameter<uint32_t>( index );
+  }
+
+  std::string GetParameterAsString( uint32_t index ) const
+  {
+    return reinterpret_cast<const char*>( localData.start + index + 1 );
+  }
+
+  template<class T>
+  T operator[]( uint32_t index ) const
+  {
+    return GetParameter<T>( 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 (file)
index 0000000..54b4618
--- /dev/null
@@ -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 <dali/graphics/vulkan/spirv/vulkan-spirv.h>
+#include <dali/graphics/vulkan/spirv/vulkan-spirv-opcode.h>
+#include <iostream>
+
+#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<Pointer> 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<ResourceDescriptor>;
+    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<uint32_t*>( pData );
+    auto end   = begin + size;
+    std::copy( begin, end, data.begin() );
+    shaderStages = stages;
+  }
+
+  /**
+   * Constructor
+   * @tparam T
+   * @param buffer
+   * @param stages
+   */
+  template<typename T>
+  explicit Impl( std::vector<T> buffer, vk::ShaderStageFlags stages )
+  {
+    data.resize( ( buffer.size() * sizeof( buffer[0] ) ) / sizeof( uint32_t ) );
+    auto begin = reinterpret_cast<uint32_t*>( &*buffer.begin() );
+    auto end   = reinterpret_cast<uint32_t*>( &*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<const SPIRVOpCode*> 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<SPIRVOpCode*> 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<SpvDecoration>( 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<int32_t>(*( 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<SpvStorageClass>( 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<SpvStorageClass>( 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> 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<SpvDecoration>( 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<SpvDecoration>( 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<uint32_t>( 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<ResourceDescriptor*> 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<SpvDim>( 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<SpvDim>( 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<SpvStorageClass>( 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<SpvStorageClass>( 1 ) == SpvStorageClassUniform )
+    {
+      auto& opTypeStruct = GetReferencedOpCode( ptrOpCode, 2 );
+      if( opTypeStruct == SpvOpTypeStruct )
+      {
+        return CheckDecorationForOpId( opTypeStruct, SpvDecorationBufferBlock );
+      }
+    }
+    return false;
+  }
+
+  void GenerateDescriptorSetLayoutCreateInfo( const std::vector<ResourceDescriptor*>& 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<vk::DescriptorSetLayoutCreateInfo> GenerateDescriptorSetLayoutCreateInfo() const
+  {
+    std::vector<vk::DescriptorSetLayoutCreateInfo> 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<Header*>( data.data() );
+    return MAGIC_NUMBER == header.magicNumber;
+  }
+
+public:
+
+  std::vector<SPIRVOpCode>  opCodes; // contains all opcodes
+  std::vector<SPIRVOpCode*> 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<vk::DescriptorSetLayoutBinding> bindings;
+  };
+
+  std::vector<LayoutAndBindings> layoutCreateInfoCache{};
+
+  std::vector<SPIRVWord>    data;
+  std::vector<PointerName>  names{};
+  std::vector<SPIRVOpCode*> 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<SPIRVWord> code, vk::ShaderStageFlags stages )
+{
+  mImpl = std::make_unique<Impl>( code, stages );
+}
+
+std::vector<vk::DescriptorSetLayoutCreateInfo> SPIRVShader::GenerateDescriptorSetLayoutCreateInfo() const
+{
+  return mImpl->GenerateDescriptorSetLayoutCreateInfo();
+}
+
+uint32_t SPIRVShader::GetOpCodeCount() const
+{
+  return static_cast<uint32_t>( 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<SPIRVWord>( 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<SPIRVShader> SPIRVUtils::Parse( std::vector<SPIRVWord> data, vk::ShaderStageFlags stages )
+{
+  auto shader = std::unique_ptr<SPIRVShader>( new SPIRVShader( data, stages ) );
+  if( !shader->GetImplementation().Initialise() )
+  {
+    return nullptr;
+  }
+  return shader;
+}
+
+std::unique_ptr<SPIRVShader> SPIRVUtils::Parse( const SPIRVWord* data, size_t sizeInBytes, vk::ShaderStageFlags stages )
+{
+  std::vector<SPIRVWord> 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 (file)
index 0000000..6e3b8fc
--- /dev/null
@@ -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 <dali/graphics/vulkan/vulkan-types.h>
+#include <cstdint>
+#include <vector>
+
+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<vk::DescriptorSetLayoutCreateInfo> 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<class T>
+  T GetOpCodeParameter( const SPIRVOpCode& opCode, uint32_t index ) const
+  {
+    return *reinterpret_cast<const T*>( 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<Impl> mImpl;
+
+  explicit SPIRVShader( Impl& impl );
+
+  SPIRVShader();
+
+  /**
+   * Constructor that should be called only from SPIRVUtils
+   * @param code
+   */
+  explicit SPIRVShader( std::vector<SPIRVWord> 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<SPIRVShader> Parse( std::vector<SPIRVWord> data, vk::ShaderStageFlags stages );
+
+  static std::unique_ptr<SPIRVShader> Parse( const SPIRVWord* data, size_t sizeInBytes, vk::ShaderStageFlags stages );
+
+private:
+
+  struct Impl;
+  std::unique_ptr<Impl> mImpl;
+};
+
+}
+} // namespace Vulkan
+} // namespace Graphics
+} // namespace Dali
+
+#endif // DALI_GRAPHICS_VULKAN_SPIRV_SPIRV_H
index bef027a..027622d 100644 (file)
@@ -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<vk::Semaphore>&          semaphores,
                                         const std::vector<vk::PipelineStageFlags>& stages )
index 67495d0..d51a23b 100644 (file)
@@ -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<DescriptorSetLayout::Impl>( graphics, createInfo );
 }
-
+#endif
 } // Namespace Vulkan
 
 } // Namespace Graphics
index 3b1da88..c42c3fc 100644 (file)
@@ -107,7 +107,7 @@ private:
   std::unique_ptr<Impl> mImpl;
 };
 
-
+#if 0
 class DescriptorSetLayout
 {
 public:
@@ -123,7 +123,7 @@ private:
   class Impl;
   std::unique_ptr<Impl> mImpl;
 };
-
+#endif
 } // Namespace Vulkan
 
 } // Namespace Graphics
index 95a7371..8f715e6 100644 (file)
@@ -65,24 +65,7 @@ struct Controller::Impl
 #pragma GCC diagnostic ignored "-Wframe-larger-than="
   bool Initialise()
   {
-    // create shaders
-    auto bindings =
-      std::vector<vk::DescriptorSetLayoutBinding>{// 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() );
index d1ea784..f9eb369 100644 (file)
@@ -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<const char*>& 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));
index e7ca9ea..00971b3 100644 (file)
@@ -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 <dali/graphics/vulkan/vulkan-pipeline.h>
 #include <dali/graphics/vulkan/vulkan-graphics.h>
 #include <dali/graphics/vulkan/vulkan-surface.h>
+#include <dali/graphics/vulkan/vulkan-descriptor-set.h>
+#include <dali/graphics/vulkan/spirv/vulkan-spirv.h>
 
 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<vk::ShaderStageFlagBits>( 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<vk::DescriptorSetLayoutBinding>;
+
+    std::vector<DSLayoutBindingArray> allDescriptorSetLayouts;
 
-    std::vector<vk::DescriptorSetLayout> 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<uint32_t>(allLayouts.size()) );
+    // create descriptor set layouts for the pipeline
+    std::vector<vk::DescriptorSetLayout> dsLayouts{};
+    dsLayouts.resize( allDescriptorSetLayouts.size() );
+    mDSCreateInfoArray.clear();
+    for( auto i = 0u; i < allDescriptorSetLayouts.size(); ++i )
+    {
+      auto info = vk::DescriptorSetLayoutCreateInfo{}.
+                    setBindingCount( static_cast<uint32_t>(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<uint32_t>(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<Handle<Shader>>     mShaderResources;
+  std::vector<ShaderRef>     mShaderResources;
 
   vk::PipelineViewportStateCreateInfo mViewportState {};
   std::vector<vk::Viewport> mViewports {};
@@ -306,6 +369,8 @@ struct Pipeline::Impl
 
   std::vector<vk::PipelineShaderStageCreateInfo> mShaderStageCreateInfo;
   vk::PipelineLayout mPipelineLayout{};
+  std::vector<vk::DescriptorSetLayoutCreateInfo>    mDSCreateInfoArray{};
+  std::vector<vk::DescriptorSetLayout>              mDSLayoutArray{};
 
   // vertex input state
   vk::PipelineVertexInputStateCreateInfo            mVertexInputState {};
@@ -389,6 +454,16 @@ vk::PipelineLayout Pipeline::GetVkPipelineLayout() const
   return mImpl->mPipelineLayout;
 }
 
+const std::vector<vk::DescriptorSetLayoutCreateInfo>& Pipeline::GetVkDescriptorSetLayoutCreateInfo() const
+{
+  return mImpl->mDSCreateInfoArray;
+}
+
+const std::vector<vk::DescriptorSetLayout>& Pipeline::GetVkDescriptorSetLayouts() const
+{
+  return mImpl->mDSLayoutArray;
+}
+
 } // namespace Vulkan
 
 } // namespace Graphics
index 9197f4e..3f1dd8f 100644 (file)
@@ -77,12 +77,26 @@ public:
    * @param restartEnable
    */
   void SetInputAssemblyState( vk::PrimitiveTopology topology, bool restartEnable );
+
   /**
    *
    * @return
    */
   bool Compile();
 
+  /**
+   *
+   * @return
+   */
+  const std::vector<vk::DescriptorSetLayoutCreateInfo>& GetVkDescriptorSetLayoutCreateInfo() const;
+
+  /**
+   *
+   * @return
+   */
+  const std::vector<vk::DescriptorSetLayout>& GetVkDescriptorSetLayouts() const;
+
+
 private:
 
   Pipeline( Graphics& graphics, const vk::GraphicsPipelineCreateInfo& info );
index fa96b2f..d2d46f2 100644 (file)
@@ -17,7 +17,8 @@
 
 #include <dali/graphics/vulkan/vulkan-shader.h>
 #include <dali/graphics/vulkan/vulkan-graphics.h>
-
+#include <dali/graphics/vulkan/spirv/vulkan-spirv.h>
+#include <iostream>
 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<vk::DescriptorSetLayout>& GetDescriptorSetLayouts() const
-  {
-    return mDSLayouts;
-  }
-
-
   Shader& mOwner;
   Graphics& mGraphics;
   vk::ShaderModuleCreateInfo mCreateInfo;
   vk::ShaderModule mShaderModule;
-  std::vector<vk::DescriptorSetLayout> mDSLayouts; // descriptorset layouts
+  std::unique_ptr<SpirV::SPIRVShader> 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<vk::DescriptorSetLayout>& Shader::GetDescriptorSetLayouts() const
-{
-  return mImpl->GetDescriptorSetLayouts();
-}
 }
 }
 }
\ No newline at end of file
index 1c0a997..c4ffe59 100644 (file)
@@ -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<vk::DescriptorSetLayout>& GetDescriptorSetLayouts() const;
+  const SpirV::SPIRVShader& GetSPIRVReflection() const;
 
   bool OnDestroy() override;
 
index bb4cafd..f87ec77 100644 (file)
@@ -42,6 +42,7 @@ using namespace glm;
 #include <dali/graphics/vulkan/vulkan-pipeline.h>
 #include <dali/graphics/vulkan/vulkan-shader.h>
 #include <dali/graphics/vulkan/vulkan-surface.h>
+#include <dali/graphics/vulkan/spirv/vulkan-spirv.h>
 
 #define USE_XLIB 0
 #include <iostream>
@@ -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>{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<uint32_t>( 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<SPIRVWord> 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!" <<std::endl;
+
+}
+
+void RunSPIRVTest()
+{
+  std::vector<SPIRVWord> data;
+  data.resize( VSH_CODE.size()/4 );
+  std::copy( VSH_CODE.begin(), VSH_CODE.end(), reinterpret_cast<decltype(VSH_CODE.data())>(data.data()) );
+  spirv_test0( data );
+}
+
+
 } // namespace VulkanTest
 
 int main()
 {
   VulkanTest::RunTestMain();
+
+  //VulkanTest::RunSPIRVTest();
 }