1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 * \file vktSparseResourcesShaderIntrinsicsSampled.cpp
21 * \brief Sparse Resources Shader Intrinsics for sampled images
22 *//*--------------------------------------------------------------------*/
24 #include "vktSparseResourcesShaderIntrinsicsSampled.hpp"
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)
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;
51 const VkVertexInputBindingDescription vertexBinding =
53 0u, // deUint32 binding;
54 vertexDataStride, // deUint32 stride;
55 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
58 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[] =
62 0u, // deUint32 location;
63 0u, // deUint32 binding;
64 vertexFormatPosition, // VkFormat format;
65 vertexBufferOffsetPosition, // deUint32 offset;
67 // texture coordinates
69 1u, // deUint32 location;
70 0u, // deUint32 binding;
71 vertexFormatTexCoord, // VkFormat format;
72 vertexBufferOffsetTexCoord, // deUint32 offset;
76 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
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;
87 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
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;
96 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
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;
107 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
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;
124 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
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;
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
146 VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
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;
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 =
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;
175 const VkPipelineColorBlendAttachmentState colorBlendAttachmentStates[] =
177 defaultColorBlendAttachmentState,
178 defaultColorBlendAttachmentState,
181 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
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];
193 const VkDynamicState dynamicStates[] =
195 VK_DYNAMIC_STATE_VIEWPORT,
196 VK_DYNAMIC_STATE_SCISSOR,
199 const VkPipelineDynamicStateCreateInfo dynamicStateCreateInfo =
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;
208 const VkPipelineShaderStageCreateInfo pShaderStages[] =
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;
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;
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;
239 const deUint32 numActiveShaderStages = DE_LENGTH_OF_ARRAY(pShaderStages) - (geometryModule == DE_NULL ? 1u : 0u);
241 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
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;
264 return createGraphicsPipeline(vk, device, DE_NULL, &graphicsPipelineInfo);
269 void SparseShaderIntrinsicsCaseSampledBase::initPrograms (vk::SourceCollections& programCollection) const
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");
274 // Create vertex shader
275 std::ostringstream vs;
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"
281 << "layout(location = 0) out highp vec3 vs_out_texCoord;\n"
283 << "out gl_PerVertex {\n"
284 << " vec4 gl_Position;\n"
286 << "void main (void)\n"
288 << " gl_Position = vec4(vs_in_position, 0.0f, 1.0f);\n"
289 << " vs_out_texCoord = vec3(vs_in_texCoord, 0.0f);\n"
292 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
296 const deInt32 maxVertices = 3u * numLayers;
298 // Create geometry shader
299 std::ostringstream gs;
301 gs << "#version 440\n"
302 << "layout(triangles) in;\n"
303 << "layout(triangle_strip, max_vertices = " << static_cast<deInt32>(maxVertices) << ") out;\n"
305 << "in gl_PerVertex {\n"
306 << " vec4 gl_Position;\n"
308 << "out gl_PerVertex {\n"
309 << " vec4 gl_Position;\n"
311 << "layout(location = 0) in highp vec3 gs_in_texCoord[];\n"
313 << "layout(location = 0) out highp vec3 gs_out_texCoord;\n"
315 << "void main (void)\n"
317 << " for (int layerNdx = 0; layerNdx < " << static_cast<deInt32>(numLayers) << "; ++layerNdx)\n"
319 << " for (int vertexNdx = 0; vertexNdx < gl_in.length(); ++vertexNdx)\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"
326 << " EndPrimitive();\n"
330 programCollection.glslSources.add("geometry_shader") << glu::GeometrySource(gs.str());
333 // Create fragment shader
334 std::ostringstream fs;
336 const std::string typeImgComp = getImageComponentTypeName(m_format);
337 const std::string typeImgCompVec4 = getImageComponentVec4TypeName(m_format);
339 fs << "OpCapability Shader\n"
340 << "OpCapability SampledCubeArray\n"
341 << "OpCapability ImageCubeArray\n"
342 << "OpCapability SparseResidency\n"
343 << "OpCapability StorageImageExtendedFormats\n"
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"
351 << "OpName %func_main \"main\"\n"
353 << "OpName %varying_texCoord \"varying_texCoord\"\n"
355 << "OpName %output_texel \"out_texel\"\n"
356 << "OpName %output_residency \"out_residency\"\n"
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"
363 << "OpName %uniformconst_image_sparse \"u_imageSparse\"\n"
365 << "OpDecorate %varying_texCoord Location 0\n"
367 << "OpDecorate %output_texel Location 0\n"
368 << "OpDecorate %output_residency Location 1\n"
370 << "OpDecorate %type_uniformblock Block\n"
371 << "OpMemberDecorate %type_uniformblock 0 Offset 0\n"
372 << "OpMemberDecorate %type_uniformblock 1 Offset 8\n"
374 << "OpDecorate %uniformconst_image_sparse DescriptorSet 0\n"
375 << "OpDecorate %uniformconst_image_sparse Binding " << BINDING_IMAGE_SPARSE << "\n"
377 << "%type_void = OpTypeVoid\n"
378 << "%type_void_func = OpTypeFunction %type_void\n"
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"
392 << "%type_input_vec3 = OpTypePointer Input %type_vec3\n"
393 << "%type_input_float = OpTypePointer Input %type_float\n"
395 << "%type_output_img_comp_vec4 = OpTypePointer Output " << typeImgCompVec4 << "\n"
396 << "%type_output_uint = OpTypePointer Output %type_uint\n"
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"
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"
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"
410 << "%varying_texCoord = OpVariable %type_input_vec3 Input\n"
412 << "%output_texel = OpVariable %type_output_img_comp_vec4 Output\n"
413 << "%output_residency = OpVariable %type_output_uint Output\n"
415 << "%uniformconst_image_sparse = OpVariable %type_uniformconst_image_sparse UniformConstant\n"
417 << "%uniformblock_instance = OpVariable %type_pushconstant_uniformblock PushConstant\n"
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"
433 // Call main function
434 << "%func_main = OpFunction %type_void None %type_void_func\n"
435 << "%label_func_main = OpLabel\n"
437 << "%local_image_sparse = OpLoad %type_sampled_image_sparse %uniformconst_image_sparse\n"
439 << "%texCoord = OpLoad %type_vec3 %varying_texCoord\n"
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"
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"
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"
454 << sparseImageOpString("%local_sparse_op_result", "%type_struct_int_img_comp_vec4", "%local_image_sparse", coordString, "%local_uniformblock_member_float_lod") << "\n"
457 << "%local_img_comp_vec4 = OpCompositeExtract " << typeImgCompVec4 << " %local_sparse_op_result 1\n"
459 << "OpStore %output_texel %local_img_comp_vec4\n"
461 // Load residency code
462 << "%local_residency_code = OpCompositeExtract %type_int %local_sparse_op_result 0\n"
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"
470 // Loaded texel is in resident memory
471 << "OpStore %output_residency %constant_texel_resident\n"
473 << "OpBranch %branch_texel_resident\n"
474 << "%label_texel_not_resident = OpLabel\n"
476 // Loaded texel is not in resident memory
477 << "OpStore %output_residency %constant_texel_not_resident\n"
479 << "OpBranch %branch_texel_resident\n"
480 << "%branch_texel_resident = OpLabel\n"
483 << "OpFunctionEnd\n";
485 programCollection.spirvAsmSources.add("fragment_shader") << fs.str();
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
494 std::ostringstream src;
496 src << resultVariable << " = OpImageSparseSampleExplicitLod " << resultType << " " << image << " " << coord << " Lod " << miplevel << "\n";
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
509 std::ostringstream src;
511 src << resultVariable << " = OpImageSparseSampleImplicitLod " << resultType << " " << image << " " << coord << "\n";
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
524 std::ostringstream src;
526 const std::string typeImgComp = getImageComponentTypeName(m_format);
527 const std::string typeImgCompVec4 = getImageComponentVec4TypeName(m_format);
529 // Bias the coord value by half a texel, so we sample from center of 2x2 gather rectangle
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";
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";
546 case IMAGE_TYPE_2D_ARRAY:
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";
557 /* This can't be happening. */
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";
567 src << "%local_gather_residency_code = OpCompositeExtract %type_int %local_sparse_gather_result_x 0\n";
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";
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";
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";
585 class SparseShaderIntrinsicsInstanceSampledBase : public SparseShaderIntrinsicsInstanceBase
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) {}
595 VkImageUsageFlags imageSparseUsageFlags (void) const;
596 VkImageUsageFlags imageOutputUsageFlags (void) const;
598 VkQueueFlags getQueueFlags (void) const;
600 void recordCommands (const VkCommandBuffer commandBuffer,
601 const VkImageCreateInfo& imageSparseInfo,
602 const VkImage imageSparse,
603 const VkImage imageTexels,
604 const VkImage imageResidency);
606 virtual VkImageSubresourceRange sampledImageRangeToBind(const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const = 0;
609 typedef de::SharedPtr< vk::Unique<vk::VkFramebuffer> > VkFramebufferSp;
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;
618 VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageSparseUsageFlags (void) const
620 return VK_IMAGE_USAGE_SAMPLED_BIT;
623 VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageOutputUsageFlags (void) const
625 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
628 VkQueueFlags SparseShaderIntrinsicsInstanceSampledBase::getQueueFlags (void) const
630 return VK_QUEUE_GRAPHICS_BIT;
633 void SparseShaderIntrinsicsInstanceSampledBase::recordCommands (const VkCommandBuffer commandBuffer,
634 const VkImageCreateInfo& imageSparseInfo,
635 const VkImage imageSparse,
636 const VkImage imageTexels,
637 const VkImage imageResidency)
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);
644 if (imageSparseInfo.extent.width > deviceProperties.limits.maxFramebufferWidth ||
645 imageSparseInfo.extent.height > deviceProperties.limits.maxFramebufferHeight ||
646 imageSparseInfo.arrayLayers > deviceProperties.limits.maxFramebufferLayers)
648 TCU_THROW(NotSupportedError, "Image size exceeds allowed framebuffer dimensions");
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");
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");
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");
663 // Create buffer storing vertex data
664 std::vector<tcu::Vec2> vertexData;
666 vertexData.push_back(tcu::Vec2(-1.0f,-1.0f));
667 vertexData.push_back(tcu::Vec2( 0.0f, 0.0f));
669 vertexData.push_back(tcu::Vec2(-1.0f, 1.0f));
670 vertexData.push_back(tcu::Vec2( 0.0f, 1.0f));
672 vertexData.push_back(tcu::Vec2( 1.0f,-1.0f));
673 vertexData.push_back(tcu::Vec2( 1.0f, 0.0f));
675 vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
676 vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
678 const VkDeviceSize vertexDataSizeInBytes = sizeInBytes(vertexData);
679 const VkBufferCreateInfo vertexBufferCreateInfo = makeBufferCreateInfo(vertexDataSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT);
681 m_vertexBuffer = createBuffer(deviceInterface, getDevice(), &vertexBufferCreateInfo);
682 m_vertexBufferAlloc = bindBuffer(deviceInterface, getDevice(), getAllocator(), *m_vertexBuffer, MemoryRequirement::HostVisible);
684 deMemcpy(m_vertexBufferAlloc->getHostPtr(), &vertexData[0], static_cast<std::size_t>(vertexDataSizeInBytes));
685 flushMappedMemoryRange(deviceInterface, getDevice(), m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexDataSizeInBytes);
687 // Create render pass
688 const VkAttachmentDescription texelsAttachmentDescription =
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;
701 const VkAttachmentDescription residencyAttachmentDescription =
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;
714 const VkAttachmentDescription colorAttachmentsDescription[] = { texelsAttachmentDescription, residencyAttachmentDescription };
716 const VkAttachmentReference texelsAttachmentReference =
718 0u, // deUint32 attachment;
719 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
722 const VkAttachmentReference residencyAttachmentReference =
724 1u, // deUint32 attachment;
725 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
728 const VkAttachmentReference colorAttachmentsReference[] = { texelsAttachmentReference, residencyAttachmentReference };
730 const VkAttachmentReference depthAttachmentReference =
732 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
733 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout;
736 const VkSubpassDescription subpassDescription =
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;
750 const VkRenderPassCreateInfo renderPassInfo =
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;
763 m_renderPass = createRenderPass(deviceInterface, getDevice(), &renderPassInfo);
765 // Create descriptor set layout
766 DescriptorSetLayoutBuilder descriptorLayerBuilder;
768 descriptorLayerBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
770 const Unique<VkDescriptorSetLayout> descriptorSetLayout(descriptorLayerBuilder.build(deviceInterface, getDevice()));
772 // Create descriptor pool
773 DescriptorPoolBuilder descriptorPoolBuilder;
775 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSparseInfo.mipLevels);
777 descriptorPool = descriptorPoolBuilder.build(deviceInterface, getDevice(), VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, imageSparseInfo.mipLevels);
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);
787 deUint32 padding; // padding needed to satisfy std430 rules
792 // Create pipeline layout
793 const VkPushConstantRange lodConstantRange =
795 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
796 0u, // deUint32 offset;
797 sizeof(PushConstants), // deUint32 size;
800 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
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;
811 const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(deviceInterface, getDevice(), &pipelineLayoutParams));
813 // Create graphics pipeline
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;
819 if (imageSparseInfo.arrayLayers > 1u)
821 requireFeatures(instance, physicalDevice, FEATURE_GEOMETRY_SHADER);
822 geometryModule = createShaderModule(deviceInterface, getDevice(), m_context.getBinaryCollection().get("geometry_shader"), (VkShaderModuleCreateFlags)0);
825 pipelines.push_back(makeVkSharedPtr(makeGraphicsPipeline(
826 deviceInterface, getDevice(), *pipelineLayout, *m_renderPass, *vertexModule, *fragmentModule, *geometryModule)));
829 const VkPipeline graphicsPipeline = **pipelines[0];
832 const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
834 VkImageMemoryBarrier imageShaderAccessBarriers[3];
836 imageShaderAccessBarriers[0] = makeImageMemoryBarrier
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,
843 fullImageSubresourceRange
846 imageShaderAccessBarriers[1] = makeImageMemoryBarrier
849 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
850 VK_IMAGE_LAYOUT_UNDEFINED,
851 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
853 fullImageSubresourceRange
856 imageShaderAccessBarriers[2] = makeImageMemoryBarrier
859 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
860 VK_IMAGE_LAYOUT_UNDEFINED,
861 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
863 fullImageSubresourceRange
866 deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 3u, imageShaderAccessBarriers);
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);
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)));
879 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
881 const vk::VkExtent3D mipLevelSize = mipLevelExtents(imageSparseInfo.extent, mipLevelNdx);
883 const vk::VkRect2D renderArea =
885 makeOffset2D(0u, 0u),
886 makeExtent2D(mipLevelSize.width, mipLevelSize.height),
889 const VkViewport viewport = makeViewport
892 static_cast<float>(mipLevelSize.width), static_cast<float>(mipLevelSize.height),
896 const VkImageSubresourceRange mipLevelRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevelNdx, 1u, 0u, imageSparseInfo.arrayLayers);
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));
902 const VkImageView attachmentsViews[] = { **imageTexelsViews[mipLevelNdx], **imageResidencyViews[mipLevelNdx] };
904 // Create framebuffer
905 const VkFramebufferCreateInfo framebufferInfo =
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;
918 m_framebuffers[mipLevelNdx] = makeVkSharedPtr(createFramebuffer(deviceInterface, getDevice(), &framebufferInfo));
920 // Create descriptor set
921 descriptorSets[mipLevelNdx] = makeVkSharedPtr(makeDescriptorSet(deviceInterface, getDevice(), *descriptorPool, *descriptorSetLayout));
922 const VkDescriptorSet descriptorSet = **descriptorSets[mipLevelNdx];
924 // Update descriptor set
925 const VkImageSubresourceRange sparseImageSubresourceRange = sampledImageRangeToBind(imageSparseInfo, mipLevelNdx);
927 imageSparseViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, getDevice(), imageSparse, mapImageViewType(m_imageType), imageSparseInfo.format, sparseImageSubresourceRange));
929 const VkDescriptorImageInfo imageSparseDescInfo = makeDescriptorImageInfo(*m_sampler, **imageSparseViews[mipLevelNdx], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
931 DescriptorSetUpdateBuilder descriptorUpdateBuilder;
933 descriptorUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(BINDING_IMAGE_SPARSE), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSparseDescInfo);
934 descriptorUpdateBuilder.update(deviceInterface, getDevice());
938 const VkRenderPassBeginInfo renderPassBeginInfo =
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;
949 deviceInterface.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
952 // Bind graphics pipeline
953 deviceInterface.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
955 // Bind descriptor set
956 deviceInterface.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
958 // Bind vertex buffer
960 const VkDeviceSize offset = 0ull;
961 deviceInterface.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &m_vertexBuffer.get(), &offset);
965 deviceInterface.cmdSetViewport(commandBuffer, 0u, 1u, &viewport);
967 // Bind Scissor Rectangle
968 deviceInterface.cmdSetScissor(commandBuffer, 0u, 1u, &renderArea);
970 const PushConstants pushConstants =
974 static_cast<float>(mipLevelSize.width),
975 static_cast<float>(mipLevelSize.height)
978 // Update push constants
979 deviceInterface.cmdPushConstants(commandBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(PushConstants), &pushConstants);
981 // Draw full screen quad
982 deviceInterface.cmdDraw(commandBuffer, 4u, 1u, 0u, 0u);
985 deviceInterface.cmdEndRenderPass(commandBuffer);
989 const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
991 VkImageMemoryBarrier imageOutputTransferSrcBarriers[2];
993 imageOutputTransferSrcBarriers[0] = makeImageMemoryBarrier
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,
1000 fullImageSubresourceRange
1003 imageOutputTransferSrcBarriers[1] = makeImageMemoryBarrier
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,
1010 fullImageSubresourceRange
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);
1017 class SparseShaderIntrinsicsInstanceSampledExplicit : public SparseShaderIntrinsicsInstanceSampledBase
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) {}
1027 VkImageSubresourceRange sampledImageRangeToBind (const VkImageCreateInfo& imageSparseInfo,
1028 const deUint32 mipLevel) const
1031 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
1035 TestInstance* SparseShaderIntrinsicsCaseSampledExplicit::createInstance (Context& context) const
1037 return new SparseShaderIntrinsicsInstanceSampledExplicit(context, m_function, m_imageType, m_imageSize, m_format);
1040 class SparseShaderIntrinsicsInstanceSampledImplicit : public SparseShaderIntrinsicsInstanceSampledBase
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) {}
1050 VkImageSubresourceRange sampledImageRangeToBind (const VkImageCreateInfo& imageSparseInfo,
1051 const deUint32 mipLevel) const
1053 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 1u, 0u, imageSparseInfo.arrayLayers);
1057 TestInstance* SparseShaderIntrinsicsCaseSampledImplicit::createInstance (Context& context) const
1059 return new SparseShaderIntrinsicsInstanceSampledImplicit(context, m_function, m_imageType, m_imageSize, m_format);