Skip OOB SSBO fragment tests for ES3.1 GPUs am: 66241e9dbb
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / sparse_resources / vktSparseResourcesShaderIntrinsicsSampled.cpp
1 /*------------------------------------------------------------------------
2  * Vulkan Conformance Tests
3  * ------------------------
4  *
5  * Copyright (c) 2016 The Khronos Group Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*
20  * \file  vktSparseResourcesShaderIntrinsicsSampled.cpp
21  * \brief Sparse Resources Shader Intrinsics for sampled images
22  *//*--------------------------------------------------------------------*/
23
24 #include "vktSparseResourcesShaderIntrinsicsSampled.hpp"
25
26 using namespace vk;
27
28 namespace vkt
29 {
30 namespace sparse
31 {
32 namespace
33 {
34
35 Move<VkPipeline> makeGraphicsPipeline (const DeviceInterface&                   vk,
36                                                                            const VkDevice                                       device,
37                                                                            const VkPipelineLayout                       pipelineLayout,
38                                                                            const VkRenderPass                           renderPass,
39                                                                            const VkShaderModule                         vertexModule,
40                                                                            const VkShaderModule                         fragmentModule,
41                                                                            const VkShaderModule                         geometryModule)
42 {
43         const VkFormat          vertexFormatPosition            = VK_FORMAT_R32G32_SFLOAT;
44         const VkFormat          vertexFormatTexCoord            = VK_FORMAT_R32G32_SFLOAT;
45         const deUint32          vertexSizePosition                      = tcu::getPixelSize(mapVkFormat(vertexFormatPosition));
46         const deUint32          vertexSizeTexCoord                      = tcu::getPixelSize(mapVkFormat(vertexFormatTexCoord));
47         const deUint32          vertexBufferOffsetPosition      = 0u;
48         const deUint32          vertexBufferOffsetTexCoord      = vertexSizePosition;
49         const deUint32          vertexDataStride                        = vertexSizePosition + vertexSizeTexCoord;
50
51         const VkVertexInputBindingDescription vertexBinding =
52         {
53                 0u,                                                     // deUint32                             binding;
54                 vertexDataStride,                       // deUint32                             stride;
55                 VK_VERTEX_INPUT_RATE_VERTEX     // VkVertexInputRate    inputRate;
56         };
57
58         const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
59         {
60                 // position
61                 {
62                         0u,                                                     // deUint32     location;
63                         0u,                                                     // deUint32     binding;
64                         vertexFormatPosition,           // VkFormat     format;
65                         vertexBufferOffsetPosition,     // deUint32     offset;
66                 },
67                 // texture coordinates
68                 {
69                         1u,                                                     // deUint32     location;
70                         0u,                                                     // deUint32     binding;
71                         vertexFormatTexCoord,           // VkFormat     format;
72                         vertexBufferOffsetTexCoord,     // deUint32     offset;
73                 },
74         };
75
76         const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
77         {
78                 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,              // VkStructureType                             sType;
79                 DE_NULL,                                                                                                                // const void*                                 pNext;
80                 (VkPipelineVertexInputStateCreateFlags)0,                                               // VkPipelineVertexInputStateCreateFlags       flags;
81                 1u,                                                                                                                             // uint32_t                                    vertexBindingDescriptionCount;
82                 &vertexBinding,                                                                                                 // const VkVertexInputBindingDescription*      pVertexBindingDescriptions;
83                 DE_LENGTH_OF_ARRAY(vertexInputAttributeDescriptions),                   // uint32_t                                    vertexAttributeDescriptionCount;
84                 vertexInputAttributeDescriptions,                                                               // const VkVertexInputAttributeDescription*    pVertexAttributeDescriptions;
85         };
86
87         const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
88         {
89                 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,    // VkStructureType                             sType;
90                 DE_NULL,                                                                                                                // const void*                                 pNext;
91                 (VkPipelineInputAssemblyStateCreateFlags)0,                                             // VkPipelineInputAssemblyStateCreateFlags     flags;
92                 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,                                                   // VkPrimitiveTopology                         topology;
93                 VK_FALSE,                                                                                                               // VkBool32                                    primitiveRestartEnable;
94         };
95
96         const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
97         {
98                 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,                  // VkStructureType                             sType;
99                 DE_NULL,                                                                                                                // const void*                                 pNext;
100                 (VkPipelineViewportStateCreateFlags)0,                                                  // VkPipelineViewportStateCreateFlags          flags;
101                 1u,                                                                                                                             // uint32_t                                    viewportCount;
102                 DE_NULL, // dynamic state                                                                               // const VkViewport*                           pViewports;
103                 1u,                                                                                                                             // uint32_t                                    scissorCount;
104                 DE_NULL, // dynamic state                                                                               // const VkRect2D*                             pScissors;
105         };
106
107         const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
108         {
109                 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,             // VkStructureType                          sType;
110                 DE_NULL,                                                                                                                // const void*                              pNext;
111                 (VkPipelineRasterizationStateCreateFlags)0,                                             // VkPipelineRasterizationStateCreateFlags  flags;
112                 VK_FALSE,                                                                                                               // VkBool32                                 depthClampEnable;
113                 VK_FALSE,                                                                                                               // VkBool32                                 rasterizerDiscardEnable;
114                 VK_POLYGON_MODE_FILL,                                                                                   // VkPolygonMode                                                        polygonMode;
115                 VK_CULL_MODE_NONE,                                                                                              // VkCullModeFlags                                                      cullMode;
116                 VK_FRONT_FACE_COUNTER_CLOCKWISE,                                                                // VkFrontFace                                                          frontFace;
117                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBiasEnable;
118                 0.0f,                                                                                                                   // float                                                                        depthBiasConstantFactor;
119                 0.0f,                                                                                                                   // float                                                                        depthBiasClamp;
120                 0.0f,                                                                                                                   // float                                                                        depthBiasSlopeFactor;
121                 1.0f,                                                                                                                   // float                                                                        lineWidth;
122         };
123
124         const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
125         {
126                 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,               // VkStructureType                                                      sType;
127                 DE_NULL,                                                                                                                // const void*                                                          pNext;
128                 (VkPipelineMultisampleStateCreateFlags)0,                                               // VkPipelineMultisampleStateCreateFlags        flags;
129                 VK_SAMPLE_COUNT_1_BIT,                                                                                  // VkSampleCountFlagBits                                        rasterizationSamples;
130                 VK_FALSE,                                                                                                               // VkBool32                                                                     sampleShadingEnable;
131                 0.0f,                                                                                                                   // float                                                                        minSampleShading;
132                 DE_NULL,                                                                                                                // const VkSampleMask*                                          pSampleMask;
133                 VK_FALSE,                                                                                                               // VkBool32                                                                     alphaToCoverageEnable;
134                 VK_FALSE                                                                                                                // VkBool32                                                                     alphaToOneEnable;
135         };
136
137         const VkStencilOpState stencilOpState = makeStencilOpState(
138                 VK_STENCIL_OP_KEEP,                             // stencil fail
139                 VK_STENCIL_OP_KEEP,                             // depth & stencil pass
140                 VK_STENCIL_OP_KEEP,                             // depth only fail
141                 VK_COMPARE_OP_ALWAYS,                   // compare op
142                 0u,                                                             // compare mask
143                 0u,                                                             // write mask
144                 0u);                                                    // reference
145
146         VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
147         {
148                 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,             // VkStructureType                                                      sType;
149                 DE_NULL,                                                                                                                // const void*                                                          pNext;
150                 (VkPipelineDepthStencilStateCreateFlags)0,                                              // VkPipelineDepthStencilStateCreateFlags       flags;
151                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthTestEnable;
152                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthWriteEnable;
153                 VK_COMPARE_OP_LESS,                                                                                             // VkCompareOp                                                          depthCompareOp;
154                 VK_FALSE,                                                                                                               // VkBool32                                                                     depthBoundsTestEnable;
155                 VK_FALSE,                                                                                                               // VkBool32                                                                     stencilTestEnable;
156                 stencilOpState,                                                                                                 // VkStencilOpState                                                     front;
157                 stencilOpState,                                                                                                 // VkStencilOpState                                                     back;
158                 0.0f,                                                                                                                   // float                                                                        minDepthBounds;
159                 1.0f,                                                                                                                   // float                                                                        maxDepthBounds;
160         };
161
162         const VkColorComponentFlags                                     colorComponentsAll                                      = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
163         const VkPipelineColorBlendAttachmentState       defaultColorBlendAttachmentState        =
164         {
165                 VK_FALSE,                                               // VkBool32                                     blendEnable;
166                 VK_BLEND_FACTOR_ONE,                    // VkBlendFactor                        srcColorBlendFactor;
167                 VK_BLEND_FACTOR_ZERO,                   // VkBlendFactor                        dstColorBlendFactor;
168                 VK_BLEND_OP_ADD,                                // VkBlendOp                            colorBlendOp;
169                 VK_BLEND_FACTOR_ONE,                    // VkBlendFactor                        srcAlphaBlendFactor;
170                 VK_BLEND_FACTOR_ZERO,                   // VkBlendFactor                        dstAlphaBlendFactor;
171                 VK_BLEND_OP_ADD,                                // VkBlendOp                            alphaBlendOp;
172                 colorComponentsAll,                             // VkColorComponentFlags        colorWriteMask;
173         };
174
175         const VkPipelineColorBlendAttachmentState       colorBlendAttachmentStates[] =
176         {
177                 defaultColorBlendAttachmentState,
178                 defaultColorBlendAttachmentState,
179         };
180
181         const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
182         {
183                 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,               // VkStructureType                                                              sType;
184                 DE_NULL,                                                                                                                // const void*                                                                  pNext;
185                 (VkPipelineColorBlendStateCreateFlags)0,                                                // VkPipelineColorBlendStateCreateFlags                 flags;
186                 VK_FALSE,                                                                                                               // VkBool32                                                                             logicOpEnable;
187                 VK_LOGIC_OP_COPY,                                                                                               // VkLogicOp                                                                    logicOp;
188                 DE_LENGTH_OF_ARRAY(colorBlendAttachmentStates),                                 // deUint32                                                                             attachmentCount;
189                 colorBlendAttachmentStates,                                                                             // const VkPipelineColorBlendAttachmentState*   pAttachments;
190                 { 0.0f, 0.0f, 0.0f, 0.0f },                                                                             // float                                                                                blendConstants[4];
191         };
192
193         const VkDynamicState dynamicStates[] =
194         {
195                 VK_DYNAMIC_STATE_VIEWPORT,
196                 VK_DYNAMIC_STATE_SCISSOR,
197         };
198
199         const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
200         {
201                 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,   // VkStructureType                                              sType;
202                 DE_NULL,                                                                                                // const void*                                                  pNext;
203                 (VkPipelineDynamicStateCreateFlags)0,                                   // VkPipelineDynamicStateCreateFlags    flags;
204                 DE_LENGTH_OF_ARRAY(dynamicStates),                                              // deUint32                                                             dynamicStateCount;
205                 dynamicStates,                                                                                  // const VkDynamicState*                                pDynamicStates;
206         };
207
208         const VkPipelineShaderStageCreateInfo pShaderStages[] =
209         {
210                 {
211                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
212                         DE_NULL,                                                                                                        // const void*                                                  pNext;
213                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
214                         VK_SHADER_STAGE_VERTEX_BIT,                                                                     // VkShaderStageFlagBits                                stage;
215                         vertexModule,                                                                                           // VkShaderModule                                               module;
216                         "main",                                                                                                         // const char*                                                  pName;
217                         DE_NULL,                                                                                                        // const VkSpecializationInfo*                  pSpecializationInfo;
218                 },
219                 {
220                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
221                         DE_NULL,                                                                                                        // const void*                                                  pNext;
222                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
223                         VK_SHADER_STAGE_FRAGMENT_BIT,                                                           // VkShaderStageFlagBits                                stage;
224                         fragmentModule,                                                                                         // VkShaderModule                                               module;
225                         "main",                                                                                                         // const char*                                                  pName;
226                         DE_NULL,                                                                                                        // const VkSpecializationInfo*                  pSpecializationInfo;
227                 },
228                 {
229                         VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,            // VkStructureType                                              sType;
230                         DE_NULL,                                                                                                        // const void*                                                  pNext;
231                         (VkPipelineShaderStageCreateFlags)0,                                            // VkPipelineShaderStageCreateFlags             flags;
232                         VK_SHADER_STAGE_GEOMETRY_BIT,                                                           // VkShaderStageFlagBits                                stage;
233                         geometryModule,                                                                                         // VkShaderModule                                               module;
234                         "main",                                                                                                         // const char*                                                  pName;
235                         DE_NULL,                                                                                                        // const VkSpecializationInfo*                  pSpecializationInfo;
236                 },
237         };
238
239         const deUint32 numActiveShaderStages = DE_LENGTH_OF_ARRAY(pShaderStages) - (geometryModule == DE_NULL ? 1u : 0u);
240
241         const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
242         {
243                 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,        // VkStructureType                                                                      sType;
244                 DE_NULL,                                                                                        // const void*                                                                          pNext;
245                 (VkPipelineCreateFlags)0,                                                       // VkPipelineCreateFlags                                                        flags;
246                 numActiveShaderStages,                                                          // deUint32                                                                                     stageCount;
247                 pShaderStages,                                                                          // const VkPipelineShaderStageCreateInfo*                       pStages;
248                 &vertexInputStateInfo,                                                          // const VkPipelineVertexInputStateCreateInfo*          pVertexInputState;
249                 &pipelineInputAssemblyStateInfo,                                        // const VkPipelineInputAssemblyStateCreateInfo*        pInputAssemblyState;
250                 DE_NULL,                                                                                        // const VkPipelineTessellationStateCreateInfo*         pTessellationState;
251                 &pipelineViewportStateInfo,                                                     // const VkPipelineViewportStateCreateInfo*                     pViewportState;
252                 &pipelineRasterizationStateInfo,                                        // const VkPipelineRasterizationStateCreateInfo*        pRasterizationState;
253                 &pipelineMultisampleStateInfo,                                          // const VkPipelineMultisampleStateCreateInfo*          pMultisampleState;
254                 &pipelineDepthStencilStateInfo,                                         // const VkPipelineDepthStencilStateCreateInfo*         pDepthStencilState;
255                 &pipelineColorBlendStateInfo,                                           // const VkPipelineColorBlendStateCreateInfo*           pColorBlendState;
256                 &dynamicStateCreateInfo,                                                        // const VkPipelineDynamicStateCreateInfo*                      pDynamicState;
257                 pipelineLayout,                                                                         // VkPipelineLayout                                                                     layout;
258                 renderPass,                                                                                     // VkRenderPass                                                                         renderPass;
259                 0u,                                                                                                     // deUint32                                                                                     subpass;
260                 DE_NULL,                                                                                        // VkPipeline                                                                           basePipelineHandle;
261                 0,                                                                                                      // deInt32                                                                                      basePipelineIndex;
262         };
263
264         return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
265 }
266
267 } // anonymous
268
269 void SparseShaderIntrinsicsCaseSampledBase::initPrograms (vk::SourceCollections& programCollection) const
270 {
271         const deUint32          numLayers       = getNumLayers(m_imageType, m_imageSize);
272         const std::string       coordString = getShaderImageCoordinates(m_imageType, "%local_texCoord_x", "%local_texCoord_xy", "%local_texCoord_xyz");
273
274         // Create vertex shader
275         std::ostringstream vs;
276
277         vs      << "#version 440\n"
278                 << "layout(location = 0) in  highp vec2 vs_in_position;\n"
279                 << "layout(location = 1) in  highp vec2 vs_in_texCoord;\n"
280                 << "\n"
281                 << "layout(location = 0) out highp vec3 vs_out_texCoord;\n"
282                 << "\n"
283                 << "out gl_PerVertex {\n"
284                 << "    vec4  gl_Position;\n"
285                 << "};\n"
286                 << "void main (void)\n"
287                 << "{\n"
288                 << "    gl_Position             = vec4(vs_in_position, 0.0f, 1.0f);\n"
289                 << "    vs_out_texCoord = vec3(vs_in_texCoord, 0.0f);\n"
290                 << "}\n";
291
292         programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
293
294         if (numLayers > 1u)
295         {
296                 const deInt32 maxVertices = 3u * numLayers;
297
298                 // Create geometry shader
299                 std::ostringstream gs;
300
301                 gs << "#version 440\n"
302                         << "layout(triangles) in;\n"
303                         << "layout(triangle_strip, max_vertices = " << static_cast<deInt32>(maxVertices) << ") out;\n"
304                         << "\n"
305                         << "in gl_PerVertex {\n"
306                         << "    vec4  gl_Position;\n"
307                         << "} gl_in[];\n"
308                         << "out gl_PerVertex {\n"
309                         << "    vec4  gl_Position;\n"
310                         << "};\n"
311                         << "layout(location = 0) in  highp vec3 gs_in_texCoord[];\n"
312                         << "\n"
313                         << "layout(location = 0) out highp vec3 gs_out_texCoord;\n"
314                         << "\n"
315                         << "void main (void)\n"
316                         << "{\n"
317                         << "    for (int layerNdx = 0; layerNdx < " << static_cast<deInt32>(numLayers) << "; ++layerNdx)\n"
318                         << "    {\n"
319                         << "            for (int vertexNdx = 0; vertexNdx < gl_in.length(); ++vertexNdx)\n"
320                         << "            {\n"
321                         << "                    gl_Layer                = layerNdx;\n"
322                         << "                    gl_Position             = gl_in[vertexNdx].gl_Position;\n"
323                         << "                    gs_out_texCoord = vec3(gs_in_texCoord[vertexNdx].xy, float(layerNdx));\n"
324                         << "                    EmitVertex();\n"
325                         << "            }\n"
326                         << "            EndPrimitive();\n"
327                         << "    }\n"
328                         << "}\n";
329
330                 programCollection.glslSources.add("geometry_shader") << glu::GeometrySource(gs.str());
331         }
332
333         // Create fragment shader
334         std::ostringstream fs;
335
336         const std::string       typeImgComp             = getImageComponentTypeName(m_format);
337         const std::string       typeImgCompVec4 = getImageComponentVec4TypeName(m_format);
338
339         fs      << "OpCapability Shader\n"
340                 << "OpCapability SampledCubeArray\n"
341                 << "OpCapability ImageCubeArray\n"
342                 << "OpCapability SparseResidency\n"
343                 << "OpCapability StorageImageExtendedFormats\n"
344
345                 << "%ext_import = OpExtInstImport \"GLSL.std.450\"\n"
346                 << "OpMemoryModel Logical GLSL450\n"
347                 << "OpEntryPoint Fragment %func_main \"main\" %varying_texCoord %output_texel %output_residency\n"
348                 << "OpExecutionMode %func_main OriginUpperLeft\n"
349                 << "OpSource GLSL 440\n"
350
351                 << "OpName %func_main \"main\"\n"
352
353                 << "OpName %varying_texCoord \"varying_texCoord\"\n"
354
355                 << "OpName %output_texel \"out_texel\"\n"
356                 << "OpName %output_residency \"out_residency\"\n"
357
358                 << "OpName %type_uniformblock \"LodBlock\"\n"
359                 << "OpMemberName %type_uniformblock 0 \"lod\"\n"
360                 << "OpMemberName %type_uniformblock 1 \"size\"\n"
361                 << "OpName %uniformblock_instance \"lodInstance\"\n"
362
363                 << "OpName %uniformconst_image_sparse \"u_imageSparse\"\n"
364
365                 << "OpDecorate %varying_texCoord Location 0\n"
366
367                 << "OpDecorate %output_texel     Location 0\n"
368                 << "OpDecorate %output_residency Location 1\n"
369
370                 << "OpDecorate           %type_uniformblock Block\n"
371                 << "OpMemberDecorate %type_uniformblock 0 Offset 0\n"
372                 << "OpMemberDecorate %type_uniformblock 1 Offset 8\n"
373
374                 << "OpDecorate %uniformconst_image_sparse DescriptorSet 0\n"
375                 << "OpDecorate %uniformconst_image_sparse Binding " << BINDING_IMAGE_SPARSE << "\n"
376
377                 << "%type_void = OpTypeVoid\n"
378                 << "%type_void_func = OpTypeFunction %type_void\n"
379
380                 << "%type_bool                                                  = OpTypeBool\n"
381                 << "%type_int                                                   = OpTypeInt 32 1\n"
382                 << "%type_uint                                                  = OpTypeInt 32 0\n"
383                 << "%type_float                                                 = OpTypeFloat 32\n"
384                 << "%type_vec2                                                  = OpTypeVector %type_float 2\n"
385                 << "%type_vec3                                                  = OpTypeVector %type_float 3\n"
386                 << "%type_vec4                                                  = OpTypeVector %type_float 4\n"
387                 << "%type_ivec4                                         = OpTypeVector %type_int  4\n"
388                 << "%type_uvec4                                         = OpTypeVector %type_uint 4\n"
389                 << "%type_uniformblock                                  = OpTypeStruct %type_uint %type_vec2\n"
390                 << "%type_struct_int_img_comp_vec4      = OpTypeStruct %type_int " << typeImgCompVec4 << "\n"
391
392                 << "%type_input_vec3                                    = OpTypePointer Input %type_vec3\n"
393                 << "%type_input_float                                   = OpTypePointer Input %type_float\n"
394
395                 << "%type_output_img_comp_vec4                  = OpTypePointer Output " << typeImgCompVec4 << "\n"
396                 << "%type_output_uint                                   = OpTypePointer Output %type_uint\n"
397
398                 << "%type_function_int                                  = OpTypePointer Function %type_int\n"
399                 << "%type_function_img_comp_vec4                = OpTypePointer Function " << typeImgCompVec4 << "\n"
400                 << "%type_function_int_img_comp_vec4    = OpTypePointer Function %type_struct_int_img_comp_vec4\n"
401
402                 << "%type_pushconstant_uniformblock                             = OpTypePointer PushConstant %type_uniformblock\n"
403                 << "%type_pushconstant_uniformblock_member_lod  = OpTypePointer PushConstant %type_uint\n"
404                 << "%type_pushconstant_uniformblock_member_size = OpTypePointer PushConstant %type_vec2\n"
405
406                 << "%type_image_sparse                          = " << getOpTypeImageSparse(m_imageType, m_format, typeImgComp, true) << "\n"
407                 << "%type_sampled_image_sparse          = OpTypeSampledImage %type_image_sparse\n"
408                 << "%type_uniformconst_image_sparse = OpTypePointer UniformConstant %type_sampled_image_sparse\n"
409
410                 << "%varying_texCoord                   = OpVariable %type_input_vec3 Input\n"
411
412                 << "%output_texel                               = OpVariable %type_output_img_comp_vec4 Output\n"
413                 << "%output_residency                   = OpVariable %type_output_uint Output\n"
414
415                 << "%uniformconst_image_sparse  = OpVariable %type_uniformconst_image_sparse UniformConstant\n"
416
417                 << "%uniformblock_instance  = OpVariable %type_pushconstant_uniformblock PushConstant\n"
418
419                 // Declare constants
420                 << "%constant_uint_0                            = OpConstant %type_uint 0\n"
421                 << "%constant_uint_1                            = OpConstant %type_uint 1\n"
422                 << "%constant_uint_2                            = OpConstant %type_uint 2\n"
423                 << "%constant_uint_3                            = OpConstant %type_uint 3\n"
424                 << "%constant_int_0                                     = OpConstant %type_int  0\n"
425                 << "%constant_int_1                                     = OpConstant %type_int  1\n"
426                 << "%constant_int_2                                     = OpConstant %type_int  2\n"
427                 << "%constant_int_3                                     = OpConstant %type_int  3\n"
428                 << "%constant_float_0                           = OpConstant %type_float 0.0\n"
429                 << "%constant_float_half                        = OpConstant %type_float 0.5\n"
430                 << "%constant_texel_resident            = OpConstant %type_uint " << MEMORY_BLOCK_BOUND_VALUE << "\n"
431                 << "%constant_texel_not_resident        = OpConstant %type_uint " << MEMORY_BLOCK_NOT_BOUND_VALUE << "\n"
432
433                 // Call main function
434                 << "%func_main           = OpFunction %type_void None %type_void_func\n"
435                 << "%label_func_main = OpLabel\n"
436
437                 << "%local_image_sparse = OpLoad %type_sampled_image_sparse %uniformconst_image_sparse\n"
438
439                 << "%texCoord = OpLoad %type_vec3 %varying_texCoord\n"
440
441                 << "%local_texCoord_x = OpCompositeExtract %type_float %texCoord 0\n"
442                 << "%local_texCoord_y = OpCompositeExtract %type_float %texCoord 1\n"
443                 << "%local_texCoord_z = OpCompositeExtract %type_float %texCoord 2\n"
444
445                 << "%local_texCoord_xy  = OpCompositeConstruct %type_vec2 %local_texCoord_x %local_texCoord_y\n"
446                 << "%local_texCoord_xyz = OpCompositeConstruct %type_vec3 %local_texCoord_x %local_texCoord_y %local_texCoord_z\n"
447
448                 << "%access_uniformblock_member_uint_lod = OpAccessChain %type_pushconstant_uniformblock_member_lod %uniformblock_instance %constant_int_0\n"
449                 << "%local_uniformblock_member_uint_lod  = OpLoad %type_uint %access_uniformblock_member_uint_lod\n"
450                 << "%local_uniformblock_member_float_lod = OpConvertUToF %type_float %local_uniformblock_member_uint_lod\n"
451                 << "%access_uniformblock_member_size     = OpAccessChain %type_pushconstant_uniformblock_member_size %uniformblock_instance %constant_int_1\n"
452                 << "%local_uniformblock_member_size              = OpLoad %type_vec2 %access_uniformblock_member_size\n"
453
454                 << sparseImageOpString("%local_sparse_op_result", "%type_struct_int_img_comp_vec4", "%local_image_sparse", coordString, "%local_uniformblock_member_float_lod") << "\n"
455
456                 // Load texel value
457                 << "%local_img_comp_vec4 = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_op_result 1\n"
458
459                 << "OpStore %output_texel %local_img_comp_vec4\n"
460
461                 // Load residency code
462                 << "%local_residency_code = OpCompositeExtract %type_int %local_sparse_op_result 0\n"
463
464                 // Check if loaded texel is placed in resident memory
465                 << "%local_texel_resident = OpImageSparseTexelsResident %type_bool %local_residency_code\n"
466                 << "OpSelectionMerge %branch_texel_resident None\n"
467                 << "OpBranchConditional %local_texel_resident %label_texel_resident %label_texel_not_resident\n"
468                 << "%label_texel_resident = OpLabel\n"
469
470                 // Loaded texel is in resident memory
471                 << "OpStore %output_residency %constant_texel_resident\n"
472
473                 << "OpBranch %branch_texel_resident\n"
474                 << "%label_texel_not_resident = OpLabel\n"
475
476                 // Loaded texel is not in resident memory
477                 << "OpStore %output_residency %constant_texel_not_resident\n"
478
479                 << "OpBranch %branch_texel_resident\n"
480                 << "%branch_texel_resident = OpLabel\n"
481
482                 << "OpReturn\n"
483                 << "OpFunctionEnd\n";
484
485         programCollection.spirvAsmSources.add("fragment_shader") << fs.str();
486 }
487
488 std::string     SparseCaseOpImageSparseSampleExplicitLod::sparseImageOpString (const std::string& resultVariable,
489                                                                                                                                                    const std::string& resultType,
490                                                                                                                                                    const std::string& image,
491                                                                                                                                                    const std::string& coord,
492                                                                                                                                                    const std::string& miplevel) const
493 {
494         std::ostringstream      src;
495
496         src << resultVariable << " = OpImageSparseSampleExplicitLod " << resultType << " " << image << " " << coord << " Lod " << miplevel << "\n";
497
498         return src.str();
499 }
500
501 std::string     SparseCaseOpImageSparseSampleImplicitLod::sparseImageOpString  (const std::string& resultVariable,
502                                                                                                                                                         const std::string& resultType,
503                                                                                                                                                         const std::string& image,
504                                                                                                                                                         const std::string& coord,
505                                                                                                                                                         const std::string& miplevel) const
506 {
507         DE_UNREF(miplevel);
508
509         std::ostringstream      src;
510
511         src << resultVariable << " = OpImageSparseSampleImplicitLod " << resultType << " " << image << " " << coord << "\n";
512
513         return src.str();
514 }
515
516 std::string     SparseCaseOpImageSparseGather::sparseImageOpString (const std::string& resultVariable,
517                                                                                                                                 const std::string& resultType,
518                                                                                                                                 const std::string& image,
519                                                                                                                                 const std::string& coord,
520                                                                                                                                 const std::string& miplevel) const
521 {
522         DE_UNREF(miplevel);
523
524         std::ostringstream      src;
525
526         const std::string       typeImgComp             = getImageComponentTypeName(m_format);
527         const std::string       typeImgCompVec4 = getImageComponentVec4TypeName(m_format);
528
529         // Bias the coord value by half a texel, so we sample from center of 2x2 gather rectangle
530
531         src << "%local_image_width      = OpCompositeExtract %type_float %local_uniformblock_member_size 0\n";
532         src << "%local_image_height     = OpCompositeExtract %type_float %local_uniformblock_member_size 1\n";
533         src << "%local_coord_x_bias     = OpFDiv %type_float %constant_float_half %local_image_width\n";
534         src << "%local_coord_y_bias     = OpFDiv %type_float %constant_float_half %local_image_height\n";
535
536         switch (m_imageType)
537         {
538                 case IMAGE_TYPE_2D:
539                 {
540                         src << "%local_coord_bias       = OpCompositeConstruct %type_vec2 %local_coord_x_bias %local_coord_y_bias\n";
541                         src << "%local_coord_biased     = OpFAdd %type_vec2 " << coord << " %local_coord_bias\n";
542
543                         break;
544                 }
545
546                 case IMAGE_TYPE_2D_ARRAY:
547                 case IMAGE_TYPE_3D:
548                 {
549                         src << "%local_coord_bias       = OpCompositeConstruct %type_vec3 %local_coord_x_bias %local_coord_y_bias %constant_float_0\n";
550                         src << "%local_coord_biased     = OpFAdd %type_vec3 " << coord << " %local_coord_bias\n";
551
552                         break;
553                 }
554
555                 default:
556                 {
557                         /* This can't be happening. */
558                         DE_ASSERT(DE_FALSE);
559                 }
560         }
561
562         src << "%local_sparse_gather_result_x = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_0\n";
563         src << "%local_sparse_gather_result_y = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_1\n";
564         src << "%local_sparse_gather_result_z = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_2\n";
565         src << "%local_sparse_gather_result_w = OpImageSparseGather " << resultType << " " << image << " %local_coord_biased %constant_int_3\n";
566
567         src << "%local_gather_residency_code = OpCompositeExtract %type_int %local_sparse_gather_result_x 0\n";
568
569         src << "%local_gather_texels_x = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_x 1\n";
570         src << "%local_gather_texels_y = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_y 1\n";
571         src << "%local_gather_texels_z = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_z 1\n";
572         src << "%local_gather_texels_w = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_gather_result_w 1\n";
573
574         src << "%local_gather_primary_texel_x = OpCompositeExtract " << typeImgComp << " %local_gather_texels_x 3\n";
575         src << "%local_gather_primary_texel_y = OpCompositeExtract " << typeImgComp << " %local_gather_texels_y 3\n";
576         src << "%local_gather_primary_texel_z = OpCompositeExtract " << typeImgComp << " %local_gather_texels_z 3\n";
577         src << "%local_gather_primary_texel_w = OpCompositeExtract " << typeImgComp << " %local_gather_texels_w 3\n";
578
579         src << "%local_gather_primary_texel     = OpCompositeConstruct " << typeImgCompVec4 << " %local_gather_primary_texel_x %local_gather_primary_texel_y %local_gather_primary_texel_z %local_gather_primary_texel_w\n";
580         src << resultVariable << " = OpCompositeConstruct " << resultType << " %local_gather_residency_code %local_gather_primary_texel\n";
581
582         return src.str();
583 }
584
585 class SparseShaderIntrinsicsInstanceSampledBase : public SparseShaderIntrinsicsInstanceBase
586 {
587 public:
588         SparseShaderIntrinsicsInstanceSampledBase       (Context&                                       context,
589                                                                                                  const SpirVFunction            function,
590                                                                                                  const ImageType                        imageType,
591                                                                                                  const tcu::UVec3&                      imageSize,
592                                                                                                  const tcu::TextureFormat&      format)
593         : SparseShaderIntrinsicsInstanceBase(context, function, imageType, imageSize, format) {}
594
595         VkImageUsageFlags               imageSparseUsageFlags   (void) const;
596         VkImageUsageFlags               imageOutputUsageFlags   (void) const;
597
598         VkQueueFlags                    getQueueFlags                   (void) const;
599
600         void                                    recordCommands                  (const VkCommandBuffer          commandBuffer,
601                                                                                                          const VkImageCreateInfo&       imageSparseInfo,
602                                                                                                          const VkImage                          imageSparse,
603                                                                                                          const VkImage                          imageTexels,
604                                                                                                          const VkImage                          imageResidency);
605
606         virtual VkImageSubresourceRange sampledImageRangeToBind(const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const = 0;
607
608 private:
609         typedef de::SharedPtr< vk::Unique<vk::VkFramebuffer> > VkFramebufferSp;
610
611         Move<VkBuffer>                                  m_vertexBuffer;
612         de::MovePtr<Allocation>                 m_vertexBufferAlloc;
613         std::vector<VkFramebufferSp>    m_framebuffers;
614         Move<VkRenderPass>                              m_renderPass;
615         Move<VkSampler>                                 m_sampler;
616 };
617
618 VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageSparseUsageFlags (void) const
619 {
620         return VK_IMAGE_USAGE_SAMPLED_BIT;
621 }
622
623 VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageOutputUsageFlags (void) const
624 {
625         return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
626 }
627
628 VkQueueFlags SparseShaderIntrinsicsInstanceSampledBase::getQueueFlags (void) const
629 {
630         return VK_QUEUE_GRAPHICS_BIT;
631 }
632
633 void SparseShaderIntrinsicsInstanceSampledBase::recordCommands (const VkCommandBuffer           commandBuffer,
634                                                                                                                                 const VkImageCreateInfo&        imageSparseInfo,
635                                                                                                                                 const VkImage                           imageSparse,
636                                                                                                                                 const VkImage                           imageTexels,
637                                                                                                                                 const VkImage                           imageResidency)
638 {
639         const InstanceInterface&                 instance                       = m_context.getInstanceInterface();
640         const DeviceInterface&                   deviceInterface        = getDeviceInterface();
641         const VkPhysicalDevice                   physicalDevice         = m_context.getPhysicalDevice();
642         const VkPhysicalDeviceProperties deviceProperties       = getPhysicalDeviceProperties(instance, physicalDevice);
643
644         if (imageSparseInfo.extent.width  > deviceProperties.limits.maxFramebufferWidth  ||
645                 imageSparseInfo.extent.height > deviceProperties.limits.maxFramebufferHeight ||
646                 imageSparseInfo.arrayLayers   > deviceProperties.limits.maxFramebufferLayers)
647         {
648                 TCU_THROW(NotSupportedError, "Image size exceeds allowed framebuffer dimensions");
649         }
650
651         // Check if device supports image format for sampled images
652         if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
653                 TCU_THROW(NotSupportedError, "Device does not support image format for sampled images");
654
655         // Check if device supports image format for color attachment
656         if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
657                 TCU_THROW(NotSupportedError, "Device does not support image format for color attachment");
658
659         // Make sure device supports VK_FORMAT_R32_UINT format for color attachment
660         if (!checkImageFormatFeatureSupport(instance, physicalDevice, mapTextureFormat(m_residencyFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
661                 TCU_THROW(TestError, "Device does not support VK_FORMAT_R32_UINT format for color attachment");
662
663         // Create buffer storing vertex data
664         std::vector<tcu::Vec2> vertexData;
665
666         vertexData.push_back(tcu::Vec2(-1.0f,-1.0f));
667         vertexData.push_back(tcu::Vec2( 0.0f, 0.0f));
668
669         vertexData.push_back(tcu::Vec2(-1.0f, 1.0f));
670         vertexData.push_back(tcu::Vec2( 0.0f, 1.0f));
671
672         vertexData.push_back(tcu::Vec2( 1.0f,-1.0f));
673         vertexData.push_back(tcu::Vec2( 1.0f, 0.0f));
674
675         vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
676         vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
677
678         const VkDeviceSize                      vertexDataSizeInBytes   = sizeInBytes(vertexData);
679         const VkBufferCreateInfo        vertexBufferCreateInfo  = makeBufferCreateInfo(vertexDataSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
680
681         m_vertexBuffer          = createBuffer(deviceInterface, getDevice(), &vertexBufferCreateInfo);
682         m_vertexBufferAlloc     = bindBuffer(deviceInterface, getDevice(), getAllocator(), *m_vertexBuffer, MemoryRequirement::HostVisible);
683
684         deMemcpy(m_vertexBufferAlloc->getHostPtr(), &vertexData[0], static_cast<std::size_t>(vertexDataSizeInBytes));
685         flushMappedMemoryRange(deviceInterface, getDevice(), m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexDataSizeInBytes);
686
687         // Create render pass
688         const VkAttachmentDescription texelsAttachmentDescription =
689         {
690                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
691                 imageSparseInfo.format,                                                         // VkFormat                                                     format;
692                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
693                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
694                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
695                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
696                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
697                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
698                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                        finalLayout;
699         };
700
701         const VkAttachmentDescription residencyAttachmentDescription =
702         {
703                 (VkAttachmentDescriptionFlags)0,                                        // VkAttachmentDescriptionFlags         flags;
704                 mapTextureFormat(m_residencyFormat),                            // VkFormat                                                     format;
705                 VK_SAMPLE_COUNT_1_BIT,                                                          // VkSampleCountFlagBits                        samples;
706                 VK_ATTACHMENT_LOAD_OP_CLEAR,                                            // VkAttachmentLoadOp                           loadOp;
707                 VK_ATTACHMENT_STORE_OP_STORE,                                           // VkAttachmentStoreOp                          storeOp;
708                 VK_ATTACHMENT_LOAD_OP_DONT_CARE,                                        // VkAttachmentLoadOp                           stencilLoadOp;
709                 VK_ATTACHMENT_STORE_OP_DONT_CARE,                                       // VkAttachmentStoreOp                          stencilStoreOp;
710                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,                       // VkImageLayout                                        initialLayout;
711                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout                                        finalLayout;
712         };
713
714         const VkAttachmentDescription colorAttachmentsDescription[] = { texelsAttachmentDescription, residencyAttachmentDescription };
715
716         const VkAttachmentReference texelsAttachmentReference =
717         {
718                 0u,                                                                                                     // deUint32                     attachment;
719                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
720         };
721
722         const VkAttachmentReference residencyAttachmentReference =
723         {
724                 1u,                                                                                                     // deUint32                     attachment;
725                 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL                        // VkImageLayout        layout;
726         };
727
728         const VkAttachmentReference colorAttachmentsReference[] = { texelsAttachmentReference, residencyAttachmentReference };
729
730         const VkAttachmentReference depthAttachmentReference =
731         {
732                 VK_ATTACHMENT_UNUSED,                                                           // deUint32                     attachment;
733                 VK_IMAGE_LAYOUT_UNDEFINED                                                       // VkImageLayout        layout;
734         };
735
736         const VkSubpassDescription subpassDescription =
737         {
738                 (VkSubpassDescriptionFlags)0,                                           // VkSubpassDescriptionFlags            flags;
739                 VK_PIPELINE_BIND_POINT_GRAPHICS,                                        // VkPipelineBindPoint                          pipelineBindPoint;
740                 0u,                                                                                                     // deUint32                                                     inputAttachmentCount;
741                 DE_NULL,                                                                                        // const VkAttachmentReference*         pInputAttachments;
742                 2u,                                                                                                     // deUint32                                                     colorAttachmentCount;
743                 colorAttachmentsReference,                                                      // const VkAttachmentReference*         pColorAttachments;
744                 DE_NULL,                                                                                        // const VkAttachmentReference*         pResolveAttachments;
745                 &depthAttachmentReference,                                                      // const VkAttachmentReference*         pDepthStencilAttachment;
746                 0u,                                                                                                     // deUint32                                                     preserveAttachmentCount;
747                 DE_NULL                                                                                         // const deUint32*                                      pPreserveAttachments;
748         };
749
750         const VkRenderPassCreateInfo renderPassInfo =
751         {
752                 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,                      // VkStructureType                                      sType;
753                 DE_NULL,                                                                                        // const void*                                          pNext;
754                 (VkRenderPassCreateFlags)0,                                                     // VkRenderPassCreateFlags                      flags;
755                 2u,                                                                                                     // deUint32                                                     attachmentCount;
756                 colorAttachmentsDescription,                                            // const VkAttachmentDescription*       pAttachments;
757                 1u,                                                                                                     // deUint32                                                     subpassCount;
758                 &subpassDescription,                                                            // const VkSubpassDescription*          pSubpasses;
759                 0u,                                                                                                     // deUint32                                                     dependencyCount;
760                 DE_NULL                                                                                         // const VkSubpassDependency*           pDependencies;
761         };
762
763         m_renderPass = createRenderPass(deviceInterface, getDevice(), &renderPassInfo);
764
765         // Create descriptor set layout
766         DescriptorSetLayoutBuilder descriptorLayerBuilder;
767
768         descriptorLayerBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
769
770         const Unique<VkDescriptorSetLayout> descriptorSetLayout(descriptorLayerBuilder.build(deviceInterface, getDevice()));
771
772         // Create descriptor pool
773         DescriptorPoolBuilder descriptorPoolBuilder;
774
775         descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSparseInfo.mipLevels);
776
777         descriptorPool = descriptorPoolBuilder.build(deviceInterface, getDevice(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, imageSparseInfo.mipLevels);
778
779         // Create sampler object
780         const tcu::Sampler                      samplerObject(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST);
781         const VkSamplerCreateInfo       samplerCreateInfo = mapSampler(samplerObject, m_format);
782         m_sampler = createSampler(deviceInterface, getDevice(), &samplerCreateInfo);
783
784         struct PushConstants
785         {
786                 deUint32        lod;
787                 deUint32        padding;                        // padding needed to satisfy std430 rules
788                 float           lodWidth;
789                 float           lodHeight;
790         };
791
792         // Create pipeline layout
793         const VkPushConstantRange lodConstantRange =
794         {
795                 VK_SHADER_STAGE_FRAGMENT_BIT,   // VkShaderStageFlags   stageFlags;
796                 0u,                                                             // deUint32                     offset;
797                 sizeof(PushConstants),                  // deUint32                     size;
798         };
799
800         const VkPipelineLayoutCreateInfo pipelineLayoutParams =
801         {
802                 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,          // VkStructureType                                      sType;
803                 DE_NULL,                                                                                        // const void*                                          pNext;
804                 0u,                                                                                                     // VkPipelineLayoutCreateFlags          flags;
805                 1u,                                                                                                     // deUint32                                                     setLayoutCount;
806                 &descriptorSetLayout.get(),                                                     // const VkDescriptorSetLayout*         pSetLayouts;
807                 1u,                                                                                                     // deUint32                                                     pushConstantRangeCount;
808                 &lodConstantRange,                                                                      // const VkPushConstantRange*           pPushConstantRanges;
809         };
810
811         const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(deviceInterface, getDevice(), &pipelineLayoutParams));
812
813         // Create graphics pipeline
814         {
815                 Move<VkShaderModule> vertexModule       = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("vertex_shader"), (VkShaderModuleCreateFlags)0);
816                 Move<VkShaderModule> fragmentModule     = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("fragment_shader"), (VkShaderModuleCreateFlags)0);
817                 Move<VkShaderModule> geometryModule;
818
819                 if (imageSparseInfo.arrayLayers > 1u)
820                 {
821                         requireFeatures(instance, physicalDevice, FEATURE_GEOMETRY_SHADER);
822                         geometryModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("geometry_shader"), (VkShaderModuleCreateFlags)0);
823                 }
824
825                 pipelines.push_back(makeVkSharedPtr(makeGraphicsPipeline(
826                         deviceInterface, getDevice(), *pipelineLayout, *m_renderPass, *vertexModule, *fragmentModule, *geometryModule)));
827         }
828
829         const VkPipeline graphicsPipeline = **pipelines[0];
830
831         {
832                 const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
833
834                 VkImageMemoryBarrier imageShaderAccessBarriers[3];
835
836                 imageShaderAccessBarriers[0] = makeImageMemoryBarrier
837                 (
838                         VK_ACCESS_TRANSFER_WRITE_BIT,
839                         VK_ACCESS_SHADER_READ_BIT,
840                         VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
841                         VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
842                         imageSparse,
843                         fullImageSubresourceRange
844                 );
845
846                 imageShaderAccessBarriers[1] = makeImageMemoryBarrier
847                 (
848                         0u,
849                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
850                         VK_IMAGE_LAYOUT_UNDEFINED,
851                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
852                         imageTexels,
853                         fullImageSubresourceRange
854                 );
855
856                 imageShaderAccessBarriers[2] = makeImageMemoryBarrier
857                 (
858                         0u,
859                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
860                         VK_IMAGE_LAYOUT_UNDEFINED,
861                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
862                         imageResidency,
863                         fullImageSubresourceRange
864                 );
865
866                 deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 3u, imageShaderAccessBarriers);
867         }
868
869         imageSparseViews.resize(imageSparseInfo.mipLevels);
870         imageTexelsViews.resize(imageSparseInfo.mipLevels);
871         imageResidencyViews.resize(imageSparseInfo.mipLevels);
872         m_framebuffers.resize(imageSparseInfo.mipLevels);
873         descriptorSets.resize(imageSparseInfo.mipLevels);
874
875         std::vector<VkClearValue> clearValues;
876         clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
877         clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
878
879         for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
880         {
881                 const vk::VkExtent3D mipLevelSize = mipLevelExtents(imageSparseInfo.extent, mipLevelNdx);
882
883                 const vk::VkRect2D renderArea =
884                 {
885                         makeOffset2D(0u, 0u),
886                         makeExtent2D(mipLevelSize.width, mipLevelSize.height),
887                 };
888
889                 const VkViewport viewport = makeViewport
890                 (
891                         0.0f, 0.0f,
892                         static_cast<float>(mipLevelSize.width), static_cast<float>(mipLevelSize.height),
893                         0.0f, 1.0f
894                 );
895
896                 const VkImageSubresourceRange mipLevelRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevelNdx, 1u, 0u, imageSparseInfo.arrayLayers);
897
898                 // Create color attachments image views
899                 imageTexelsViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageTexels, mapImageViewType(m_imageType), imageSparseInfo.format, mipLevelRange));
900                 imageResidencyViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageResidency, mapImageViewType(m_imageType), mapTextureFormat(m_residencyFormat), mipLevelRange));
901
902                 const VkImageView attachmentsViews[] = { **imageTexelsViews[mipLevelNdx], **imageResidencyViews[mipLevelNdx] };
903
904                 // Create framebuffer
905                 const VkFramebufferCreateInfo framebufferInfo =
906                 {
907                         VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,      // VkStructureType                             sType;
908                         DE_NULL,                                                                        // const void*                                 pNext;
909                         (VkFramebufferCreateFlags)0,                            // VkFramebufferCreateFlags                    flags;
910                         *m_renderPass,                                                          // VkRenderPass                                renderPass;
911                         2u,                                                                                     // uint32_t                                    attachmentCount;
912                         attachmentsViews,                                                       // const VkImageView*                          pAttachments;
913                         mipLevelSize.width,                                                     // uint32_t                                    width;
914                         mipLevelSize.height,                                            // uint32_t                                    height;
915                         imageSparseInfo.arrayLayers,                            // uint32_t                                    layers;
916                 };
917
918                 m_framebuffers[mipLevelNdx] = makeVkSharedPtr(createFramebuffer(deviceInterface, getDevice(), &framebufferInfo));
919
920                 // Create descriptor set
921                 descriptorSets[mipLevelNdx] = makeVkSharedPtr(makeDescriptorSet(deviceInterface, getDevice(), *descriptorPool, *descriptorSetLayout));
922                 const VkDescriptorSet descriptorSet = **descriptorSets[mipLevelNdx];
923
924                 // Update descriptor set
925                 const VkImageSubresourceRange sparseImageSubresourceRange = sampledImageRangeToBind(imageSparseInfo, mipLevelNdx);
926
927                 imageSparseViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageSparse, mapImageViewType(m_imageType), imageSparseInfo.format, sparseImageSubresourceRange));
928
929                 const VkDescriptorImageInfo imageSparseDescInfo = makeDescriptorImageInfo(*m_sampler, **imageSparseViews[mipLevelNdx], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
930
931                 DescriptorSetUpdateBuilder descriptorUpdateBuilder;
932
933                 descriptorUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(BINDING_IMAGE_SPARSE), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSparseDescInfo);
934                 descriptorUpdateBuilder.update(deviceInterface, getDevice());
935
936                 // Begin render pass
937                 {
938                         const VkRenderPassBeginInfo renderPassBeginInfo =
939                         {
940                                 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,               // VkStructureType         sType;
941                                 DE_NULL,                                                                                // const void*             pNext;
942                                 *m_renderPass,                                                                  // VkRenderPass            renderPass;
943                                 **m_framebuffers[mipLevelNdx],                                  // VkFramebuffer           framebuffer;
944                                 renderArea,                                                                             // VkRect2D                renderArea;
945                                 static_cast<deUint32>(clearValues.size()),              // deUint32                clearValueCount;
946                                 &clearValues[0],                                                                // const VkClearValue*     pClearValues;
947                         };
948
949                         deviceInterface.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
950                 }
951
952                 // Bind graphics pipeline
953                 deviceInterface.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
954
955                 // Bind descriptor set
956                 deviceInterface.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
957
958                 // Bind vertex buffer
959                 {
960                         const VkDeviceSize offset = 0ull;
961                         deviceInterface.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &m_vertexBuffer.get(), &offset);
962                 }
963
964                 // Bind Viewport
965                 deviceInterface.cmdSetViewport(commandBuffer, 0u, 1u, &viewport);
966
967                 // Bind Scissor Rectangle
968                 deviceInterface.cmdSetScissor(commandBuffer, 0u, 1u, &renderArea);
969
970                 const PushConstants pushConstants =
971                 {
972                         mipLevelNdx,
973                         0u,                                                                                     // padding
974                         static_cast<float>(mipLevelSize.width),
975                         static_cast<float>(mipLevelSize.height)
976                 };
977
978                 // Update push constants
979                 deviceInterface.cmdPushConstants(commandBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(PushConstants), &pushConstants);
980
981                 // Draw full screen quad
982                 deviceInterface.cmdDraw(commandBuffer, 4u, 1u, 0u, 0u);
983
984                 // End render pass
985                 deviceInterface.cmdEndRenderPass(commandBuffer);
986         }
987
988         {
989                 const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
990
991                 VkImageMemoryBarrier imageOutputTransferSrcBarriers[2];
992
993                 imageOutputTransferSrcBarriers[0] = makeImageMemoryBarrier
994                 (
995                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
996                         VK_ACCESS_TRANSFER_READ_BIT,
997                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
998                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
999                         imageTexels,
1000                         fullImageSubresourceRange
1001                 );
1002
1003                 imageOutputTransferSrcBarriers[1] = makeImageMemoryBarrier
1004                 (
1005                         VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
1006                         VK_ACCESS_TRANSFER_READ_BIT,
1007                         VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
1008                         VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1009                         imageResidency,
1010                         fullImageSubresourceRange
1011                 );
1012
1013                 deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputTransferSrcBarriers);
1014         }
1015 }
1016
1017 class SparseShaderIntrinsicsInstanceSampledExplicit : public SparseShaderIntrinsicsInstanceSampledBase
1018 {
1019 public:
1020         SparseShaderIntrinsicsInstanceSampledExplicit   (Context&                                       context,
1021                                                                                                          const SpirVFunction            function,
1022                                                                                                          const ImageType                        imageType,
1023                                                                                                          const tcu::UVec3&                      imageSize,
1024                                                                                                          const tcu::TextureFormat&      format)
1025         : SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
1026
1027         VkImageSubresourceRange sampledImageRangeToBind (const VkImageCreateInfo&       imageSparseInfo,
1028                                                                                                          const deUint32                         mipLevel) const
1029         {
1030                 DE_UNREF(mipLevel);
1031                 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
1032         }
1033 };
1034
1035 TestInstance* SparseShaderIntrinsicsCaseSampledExplicit::createInstance (Context& context) const
1036 {
1037         return new SparseShaderIntrinsicsInstanceSampledExplicit(context, m_function, m_imageType, m_imageSize, m_format);
1038 }
1039
1040 class SparseShaderIntrinsicsInstanceSampledImplicit : public SparseShaderIntrinsicsInstanceSampledBase
1041 {
1042 public:
1043         SparseShaderIntrinsicsInstanceSampledImplicit   (Context&                                       context,
1044                                                                                                          const SpirVFunction            function,
1045                                                                                                          const ImageType                        imageType,
1046                                                                                                          const tcu::UVec3&                      imageSize,
1047                                                                                                          const tcu::TextureFormat&      format)
1048         : SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
1049
1050         VkImageSubresourceRange sampledImageRangeToBind (const VkImageCreateInfo&       imageSparseInfo,
1051                                                                                                          const deUint32                         mipLevel) const
1052         {
1053                 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 1u, 0u, imageSparseInfo.arrayLayers);
1054         }
1055 };
1056
1057 TestInstance* SparseShaderIntrinsicsCaseSampledImplicit::createInstance (Context& context) const
1058 {
1059         return new SparseShaderIntrinsicsInstanceSampledImplicit(context, m_function, m_imageType, m_imageSize, m_format);
1060 }
1061
1062 } // sparse
1063 } // vkt