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"
33 void SparseShaderIntrinsicsCaseSampledBase::initPrograms (vk::SourceCollections& programCollection) const
35 const deUint32 numLayers = getNumLayers(m_imageType, m_imageSize);
36 const std::string coordString = getShaderImageCoordinates(m_imageType, "%local_texCoord_x", "%local_texCoord_xy", "%local_texCoord_xyz");
38 // Create vertex shader
39 std::ostringstream vs;
41 vs << "#version 440\n"
42 << "layout(location = 0) in highp vec2 vs_in_position;\n"
43 << "layout(location = 1) in highp vec2 vs_in_texCoord;\n"
45 << "layout(location = 0) out highp vec3 vs_out_texCoord;\n"
47 << "out gl_PerVertex {\n"
48 << " vec4 gl_Position;\n"
50 << "void main (void)\n"
52 << " gl_Position = vec4(vs_in_position, 0.0f, 1.0f);\n"
53 << " vs_out_texCoord = vec3(vs_in_texCoord, 0.0f);\n"
56 programCollection.glslSources.add("vertex_shader") << glu::VertexSource(vs.str());
60 const deInt32 maxVertices = 3u * numLayers;
62 // Create geometry shader
63 std::ostringstream gs;
65 gs << "#version 440\n"
66 << "layout(triangles) in;\n"
67 << "layout(triangle_strip, max_vertices = " << static_cast<deInt32>(maxVertices) << ") out;\n"
69 << "in gl_PerVertex {\n"
70 << " vec4 gl_Position;\n"
72 << "out gl_PerVertex {\n"
73 << " vec4 gl_Position;\n"
75 << "layout(location = 0) in highp vec3 gs_in_texCoord[];\n"
77 << "layout(location = 0) out highp vec3 gs_out_texCoord;\n"
79 << "void main (void)\n"
81 << " for (int layerNdx = 0; layerNdx < " << static_cast<deInt32>(numLayers) << "; ++layerNdx)\n"
83 << " for (int vertexNdx = 0; vertexNdx < gl_in.length(); ++vertexNdx)\n"
85 << " gl_Layer = layerNdx;\n"
86 << " gl_Position = gl_in[vertexNdx].gl_Position;\n"
87 << " gs_out_texCoord = vec3(gs_in_texCoord[vertexNdx].xy, float(layerNdx));\n"
90 << " EndPrimitive();\n"
94 programCollection.glslSources.add("geometry_shader") << glu::GeometrySource(gs.str());
97 // Create fragment shader
98 std::ostringstream fs;
100 fs << "OpCapability Shader\n"
101 << "OpCapability SampledCubeArray\n"
102 << "OpCapability ImageCubeArray\n"
103 << "OpCapability SparseResidency\n"
104 << "OpCapability StorageImageExtendedFormats\n"
106 << "%ext_import = OpExtInstImport \"GLSL.std.450\"\n"
107 << "OpMemoryModel Logical GLSL450\n"
108 << "OpEntryPoint Fragment %func_main \"main\" %varying_texCoord %output_texel %output_residency\n"
109 << "OpExecutionMode %func_main OriginUpperLeft\n"
110 << "OpSource GLSL 440\n"
112 << "OpName %func_main \"main\"\n"
114 << "OpName %varying_texCoord \"varying_texCoord\"\n"
116 << "OpName %output_texel \"out_texel\"\n"
117 << "OpName %output_residency \"out_residency\"\n"
119 << "OpName %type_uniformblock_lod \"LodBlock\"\n"
120 << "OpMemberName %type_uniformblock_lod 0 \"lod\"\n"
121 << "OpName %uniformblock_lod_instance \"lodInstance\"\n"
123 << "OpName %uniformconst_image_sparse \"u_imageSparse\"\n"
125 << "OpDecorate %varying_texCoord Location 0\n"
127 << "OpDecorate %output_texel Location 0\n"
128 << "OpDecorate %output_residency Location 1\n"
130 << "OpDecorate %type_uniformblock_lod Block\n"
131 << "OpMemberDecorate %type_uniformblock_lod 0 Offset 0\n"
133 << "OpDecorate %uniformconst_image_sparse DescriptorSet 0\n"
134 << "OpDecorate %uniformconst_image_sparse Binding " << BINDING_IMAGE_SPARSE << "\n"
136 << "%type_void = OpTypeVoid\n"
137 << "%type_void_func = OpTypeFunction %type_void\n"
139 << "%type_bool = OpTypeBool\n"
140 << "%type_int = OpTypeInt 32 1\n"
141 << "%type_uint = OpTypeInt 32 0\n"
142 << "%type_float = OpTypeFloat 32\n"
143 << "%type_vec2 = OpTypeVector %type_float 2\n"
144 << "%type_vec3 = OpTypeVector %type_float 3\n"
145 << "%type_vec4 = OpTypeVector %type_float 4\n"
146 << "%type_uniformblock_lod = OpTypeStruct %type_uint\n"
147 << "%type_img_comp = " << getOpTypeImageComponent(m_format) << "\n"
148 << "%type_img_comp_vec4 = OpTypeVector %type_img_comp 4\n"
149 << "%type_struct_int_img_comp_vec4 = OpTypeStruct %type_int %type_img_comp_vec4\n"
151 << "%type_input_vec3 = OpTypePointer Input %type_vec3\n"
152 << "%type_input_float = OpTypePointer Input %type_float\n"
154 << "%type_output_img_comp_vec4 = OpTypePointer Output %type_img_comp_vec4\n"
155 << "%type_output_uint = OpTypePointer Output %type_uint\n"
157 << "%type_function_int = OpTypePointer Function %type_int\n"
158 << "%type_function_img_comp = OpTypePointer Function %type_img_comp\n"
159 << "%type_function_img_comp_vec4 = OpTypePointer Function %type_img_comp_vec4\n"
160 << "%type_function_int_img_comp_vec4 = OpTypePointer Function %type_struct_int_img_comp_vec4\n"
162 << "%type_pushconstant_uniformblock_lod = OpTypePointer PushConstant %type_uniformblock_lod\n"
163 << "%type_pushconstant_uniformblock_member_lod = OpTypePointer PushConstant %type_uint\n"
165 << "%type_image_sparse = " << getOpTypeImageSparse(m_imageType, m_format, "%type_img_comp", true) << "\n"
166 << "%type_sampled_image_sparse = OpTypeSampledImage %type_image_sparse\n"
167 << "%type_uniformconst_image_sparse = OpTypePointer UniformConstant %type_sampled_image_sparse\n"
169 << "%varying_texCoord = OpVariable %type_input_vec3 Input\n"
171 << "%output_texel = OpVariable %type_output_img_comp_vec4 Output\n"
172 << "%output_residency = OpVariable %type_output_uint Output\n"
174 << "%uniformconst_image_sparse = OpVariable %type_uniformconst_image_sparse UniformConstant\n"
176 << "%uniformblock_lod_instance = OpVariable %type_pushconstant_uniformblock_lod PushConstant\n"
179 << "%constant_uint_0 = OpConstant %type_uint 0\n"
180 << "%constant_uint_1 = OpConstant %type_uint 1\n"
181 << "%constant_uint_2 = OpConstant %type_uint 2\n"
182 << "%constant_uint_3 = OpConstant %type_uint 3\n"
183 << "%constant_int_0 = OpConstant %type_int 0\n"
184 << "%constant_int_1 = OpConstant %type_int 1\n"
185 << "%constant_int_2 = OpConstant %type_int 2\n"
186 << "%constant_int_3 = OpConstant %type_int 3\n"
187 << "%constant_texel_resident = OpConstant %type_uint " << MEMORY_BLOCK_BOUND_VALUE << "\n"
188 << "%constant_texel_not_resident = OpConstant %type_uint " << MEMORY_BLOCK_NOT_BOUND_VALUE << "\n"
190 // Call main function
191 << "%func_main = OpFunction %type_void None %type_void_func\n"
192 << "%label_func_main = OpLabel\n"
194 << "%local_image_sparse = OpLoad %type_sampled_image_sparse %uniformconst_image_sparse\n"
196 << "%local_texCoord_x = OpCompositeExtract %type_float %varying_texCoord 0\n"
197 << "%local_texCoord_y = OpCompositeExtract %type_float %varying_texCoord 1\n"
198 << "%local_texCoord_z = OpCompositeExtract %type_float %varying_texCoord 2\n"
200 << "%local_texCoord_xy = OpCompositeConstruct %type_vec2 %local_texCoord_x %local_texCoord_y\n"
201 << "%local_texCoord_xyz = OpCompositeConstruct %type_vec3 %local_texCoord_x %local_texCoord_y %local_texCoord_z\n"
203 << "%access_uniformblock_member_uint_lod = OpAccessChain %type_pushconstant_uniformblock_member_lod %uniformblock_lod_instance %constant_int_0\n"
204 << "%local_uniformblock_member_uint_lod = OpLoad %type_uint %access_uniformblock_member_uint_lod\n"
205 << "%local_uniformblock_member_float_lod = OpConvertUToF %type_float %local_uniformblock_member_uint_lod\n"
207 << sparseImageOpString("%local_sparse_op_result", "%type_struct_int_img_comp_vec4", "%local_image_sparse", coordString, "%local_uniformblock_member_float_lod") << "\n"
210 << "%local_img_comp_vec4 = OpCompositeExtract %type_img_comp_vec4 %local_sparse_op_result 1\n"
212 << "OpStore %output_texel %local_img_comp_vec4\n"
214 // Load residency code
215 << "%local_residency_code = OpCompositeExtract %type_int %local_sparse_op_result 0\n"
217 // Check if loaded texel is placed in resident memory
218 << "%local_texel_resident = OpImageSparseTexelsResident %type_bool %local_residency_code\n"
219 << "OpSelectionMerge %branch_texel_resident None\n"
220 << "OpBranchConditional %local_texel_resident %label_texel_resident %label_texel_not_resident\n"
221 << "%label_texel_resident = OpLabel\n"
223 // Loaded texel is in resident memory
224 << "OpStore %output_residency %constant_texel_resident\n"
226 << "OpBranch %branch_texel_resident\n"
227 << "%label_texel_not_resident = OpLabel\n"
229 // Loaded texel is not in resident memory
230 << "OpStore %output_residency %constant_texel_not_resident\n"
232 << "OpBranch %branch_texel_resident\n"
233 << "%branch_texel_resident = OpLabel\n"
236 << "OpFunctionEnd\n";
238 programCollection.spirvAsmSources.add("fragment_shader") << fs.str();
241 std::string SparseCaseOpImageSparseSampleExplicitLod::sparseImageOpString (const std::string& resultVariable,
242 const std::string& resultType,
243 const std::string& image,
244 const std::string& coord,
245 const std::string& miplevel) const
247 std::ostringstream src;
249 src << resultVariable << " = OpImageSparseSampleExplicitLod " << resultType << " " << image << " " << coord << " Lod " << miplevel << "\n";
254 std::string SparseCaseOpImageSparseSampleImplicitLod::sparseImageOpString (const std::string& resultVariable,
255 const std::string& resultType,
256 const std::string& image,
257 const std::string& coord,
258 const std::string& miplevel) const
262 std::ostringstream src;
264 src << resultVariable << " = OpImageSparseSampleImplicitLod " << resultType << " " << image << " " << coord << "\n";
269 std::string SparseCaseOpImageSparseGather::sparseImageOpString (const std::string& resultVariable,
270 const std::string& resultType,
271 const std::string& image,
272 const std::string& coord,
273 const std::string& miplevel) const
277 std::ostringstream src;
279 src << "%local_sparse_gather_result_x = OpImageSparseGather " << resultType << " " << image << " " << coord << " %constant_int_0\n";
280 src << "%local_sparse_gather_result_y = OpImageSparseGather " << resultType << " " << image << " " << coord << " %constant_int_1\n";
281 src << "%local_sparse_gather_result_z = OpImageSparseGather " << resultType << " " << image << " " << coord << " %constant_int_2\n";
282 src << "%local_sparse_gather_result_w = OpImageSparseGather " << resultType << " " << image << " " << coord << " %constant_int_3\n";
284 src << "%local_gather_residency_code = OpCompositeExtract %type_int %local_sparse_gather_result_x 0\n";
286 src << "%local_gather_texels_x = OpCompositeExtract %type_img_comp_vec4 %local_sparse_gather_result_x 1\n";
287 src << "%local_gather_texels_y = OpCompositeExtract %type_img_comp_vec4 %local_sparse_gather_result_y 1\n";
288 src << "%local_gather_texels_z = OpCompositeExtract %type_img_comp_vec4 %local_sparse_gather_result_z 1\n";
289 src << "%local_gather_texels_w = OpCompositeExtract %type_img_comp_vec4 %local_sparse_gather_result_w 1\n";
291 src << "%local_gather_primary_texel_x = OpCompositeExtract %type_img_comp %local_gather_texels_x 3\n";
292 src << "%local_gather_primary_texel_y = OpCompositeExtract %type_img_comp %local_gather_texels_y 3\n";
293 src << "%local_gather_primary_texel_z = OpCompositeExtract %type_img_comp %local_gather_texels_z 3\n";
294 src << "%local_gather_primary_texel_w = OpCompositeExtract %type_img_comp %local_gather_texels_w 3\n";
296 src << "%local_gather_primary_texel = OpCompositeConstruct %type_img_comp_vec4 %local_gather_primary_texel_x %local_gather_primary_texel_y %local_gather_primary_texel_z %local_gather_primary_texel_w\n";
297 src << resultVariable << " = OpCompositeConstruct " << resultType << " %local_gather_residency_code %local_gather_primary_texel\n";
302 class SparseShaderIntrinsicsInstanceSampledBase : public SparseShaderIntrinsicsInstanceBase
305 SparseShaderIntrinsicsInstanceSampledBase (Context& context,
306 const SpirVFunction function,
307 const ImageType imageType,
308 const tcu::UVec3& imageSize,
309 const tcu::TextureFormat& format)
310 : SparseShaderIntrinsicsInstanceBase(context, function, imageType, imageSize, format) {}
312 VkImageUsageFlags imageSparseUsageFlags (void) const;
313 VkImageUsageFlags imageOutputUsageFlags (void) const;
315 VkQueueFlags getQueueFlags (void) const;
317 void recordCommands (vk::Allocator& allocator,
318 const VkCommandBuffer commandBuffer,
319 const VkImageCreateInfo& imageSparseInfo,
320 const VkImage imageSparse,
321 const VkImage imageTexels,
322 const VkImage imageResidency);
324 virtual VkImageSubresourceRange sampledImageRangeToBind(const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const = 0;
328 typedef de::SharedPtr< vk::Unique<vk::VkFramebuffer> > SharedVkFramebuffer;
330 de::SharedPtr<Buffer> vertexBuffer;
331 std::vector<SharedVkFramebuffer> framebuffers;
332 Move<VkRenderPass> renderPass;
333 Move<VkSampler> sampler;
336 VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageSparseUsageFlags (void) const
338 return VK_IMAGE_USAGE_SAMPLED_BIT;
341 VkImageUsageFlags SparseShaderIntrinsicsInstanceSampledBase::imageOutputUsageFlags (void) const
343 return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
346 VkQueueFlags SparseShaderIntrinsicsInstanceSampledBase::getQueueFlags (void) const
348 return VK_QUEUE_GRAPHICS_BIT;
351 void SparseShaderIntrinsicsInstanceSampledBase::recordCommands (vk::Allocator& allocator,
352 const VkCommandBuffer commandBuffer,
353 const VkImageCreateInfo& imageSparseInfo,
354 const VkImage imageSparse,
355 const VkImage imageTexels,
356 const VkImage imageResidency)
358 const InstanceInterface& instance = m_context.getInstanceInterface();
359 const DeviceInterface& deviceInterface = m_context.getDeviceInterface();
360 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
361 const VkPhysicalDeviceProperties deviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
363 if (imageSparseInfo.extent.width > deviceProperties.limits.maxFramebufferWidth ||
364 imageSparseInfo.extent.height > deviceProperties.limits.maxFramebufferHeight ||
365 imageSparseInfo.arrayLayers > deviceProperties.limits.maxFramebufferLayers)
367 TCU_THROW(NotSupportedError, "Image size exceeds allowed framebuffer dimensions");
370 // Check if device supports image format for sampled images
371 if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT))
372 TCU_THROW(NotSupportedError, "Device does not support image format for sampled images");
374 // Check if device supports image format for color attachment
375 if (!checkImageFormatFeatureSupport(instance, physicalDevice, imageSparseInfo.format, VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
376 TCU_THROW(NotSupportedError, "Device does not support image format for color attachment");
378 // Make sure device supports VK_FORMAT_R32_UINT format for color attachment
379 if (!checkImageFormatFeatureSupport(instance, physicalDevice, mapTextureFormat(m_residencyFormat), VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT))
380 TCU_THROW(TestError, "Device does not support VK_FORMAT_R32_UINT format for color attachment");
382 // Create buffer storing vertex data
383 std::vector<tcu::Vec2> vertexData;
385 vertexData.push_back(tcu::Vec2(-1.0f,-1.0f));
386 vertexData.push_back(tcu::Vec2( 0.0f, 0.0f));
388 vertexData.push_back(tcu::Vec2(-1.0f, 1.0f));
389 vertexData.push_back(tcu::Vec2( 0.0f, 1.0f));
391 vertexData.push_back(tcu::Vec2( 1.0f,-1.0f));
392 vertexData.push_back(tcu::Vec2( 1.0f, 0.0f));
394 vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
395 vertexData.push_back(tcu::Vec2( 1.0f, 1.0f));
397 const VkFormat vertexFormatPosition = VK_FORMAT_R32G32_SFLOAT;
398 const VkFormat vertexFormatTexCoord = VK_FORMAT_R32G32_SFLOAT;
400 const deUint32 vertexSizePosition = tcu::getPixelSize(mapVkFormat(vertexFormatPosition));
401 const deUint32 vertexSizeTexCoord = tcu::getPixelSize(mapVkFormat(vertexFormatTexCoord));
403 const VkDeviceSize vertexBufferStartOffset = 0ull;
404 const deUint32 vertexBufferOffsetPosition = 0ull;
405 const deUint32 vertexBufferOffsetTexCoord = vertexSizePosition;
407 const deUint32 vertexDataStride = vertexSizePosition + vertexSizeTexCoord;
408 const VkDeviceSize vertexDataSizeInBytes = sizeInBytes(vertexData);
410 vertexBuffer = de::SharedPtr<Buffer>(new Buffer(deviceInterface, *m_logicalDevice, allocator, makeBufferCreateInfo(vertexDataSizeInBytes, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT), MemoryRequirement::HostVisible));
411 const Allocation& vertexBufferAllocation = vertexBuffer->getAllocation();
413 deMemcpy(vertexBufferAllocation.getHostPtr(), &vertexData[0], static_cast<std::size_t>(vertexDataSizeInBytes));
414 flushMappedMemoryRange(deviceInterface, *m_logicalDevice, vertexBufferAllocation.getMemory(), vertexBufferAllocation.getOffset(), vertexDataSizeInBytes);
416 // Create render pass
417 const VkAttachmentDescription texelsAttachmentDescription =
419 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
420 imageSparseInfo.format, // VkFormat format;
421 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
422 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
423 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
424 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
425 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
426 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
427 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
430 const VkAttachmentDescription residencyAttachmentDescription =
432 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
433 mapTextureFormat(m_residencyFormat), // VkFormat format;
434 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
435 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
436 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
437 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
438 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
439 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
440 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
443 const VkAttachmentDescription colorAttachmentsDescription[] = { texelsAttachmentDescription, residencyAttachmentDescription };
445 const VkAttachmentReference texelsAttachmentReference =
447 0u, // deUint32 attachment;
448 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
451 const VkAttachmentReference residencyAttachmentReference =
453 1u, // deUint32 attachment;
454 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
457 const VkAttachmentReference colorAttachmentsReference[] = { texelsAttachmentReference, residencyAttachmentReference };
459 const VkAttachmentReference depthAttachmentReference =
461 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
462 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout;
465 const VkSubpassDescription subpassDescription =
467 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
468 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
469 0u, // deUint32 inputAttachmentCount;
470 DE_NULL, // const VkAttachmentReference* pInputAttachments;
471 2u, // deUint32 colorAttachmentCount;
472 colorAttachmentsReference, // const VkAttachmentReference* pColorAttachments;
473 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
474 &depthAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment;
475 0u, // deUint32 preserveAttachmentCount;
476 DE_NULL // const deUint32* pPreserveAttachments;
479 const VkRenderPassCreateInfo renderPassInfo =
481 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
482 DE_NULL, // const void* pNext;
483 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
484 2u, // deUint32 attachmentCount;
485 colorAttachmentsDescription, // const VkAttachmentDescription* pAttachments;
486 1u, // deUint32 subpassCount;
487 &subpassDescription, // const VkSubpassDescription* pSubpasses;
488 0u, // deUint32 dependencyCount;
489 DE_NULL // const VkSubpassDependency* pDependencies;
492 renderPass = createRenderPass(deviceInterface, *m_logicalDevice, &renderPassInfo);
494 // Create descriptor set layout
495 DescriptorSetLayoutBuilder descriptorLayerBuilder;
497 descriptorLayerBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
499 const Unique<VkDescriptorSetLayout> descriptorSetLayout(descriptorLayerBuilder.build(deviceInterface, *m_logicalDevice));
501 // Create descriptor pool
502 DescriptorPoolBuilder descriptorPoolBuilder;
504 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, imageSparseInfo.mipLevels);
506 descriptorPool = descriptorPoolBuilder.build(deviceInterface, *m_logicalDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, imageSparseInfo.mipLevels);
508 // Create sampler object
509 const tcu::Sampler samplerObject(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::NEAREST_MIPMAP_NEAREST, tcu::Sampler::NEAREST);
510 const VkSamplerCreateInfo samplerCreateInfo = mapSampler(samplerObject, m_format);
511 sampler = createSampler(deviceInterface, *m_logicalDevice, &samplerCreateInfo);
513 // Create pipeline layout
514 const VkPushConstantRange lodConstantRange =
516 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags;
517 0u, // deUint32 offset;
518 sizeof(deUint32), // deUint32 size;
521 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
523 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
524 DE_NULL, // const void* pNext;
525 0u, // VkPipelineLayoutCreateFlags flags;
526 1u, // deUint32 setLayoutCount;
527 &descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
528 1u, // deUint32 pushConstantRangeCount;
529 &lodConstantRange, // const VkPushConstantRange* pPushConstantRanges;
532 const Unique<VkPipelineLayout> pipelineLayout(createPipelineLayout(deviceInterface, *m_logicalDevice, &pipelineLayoutParams));
534 // Create graphics pipeline
535 const VkVertexInputBindingDescription vertexBinding =
537 0u, // deUint32 binding;
538 vertexDataStride, // deUint32 stride;
539 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputRate inputRate;
542 const VkVertexInputAttributeDescription vertexAttributePosition =
544 0u, // deUint32 location;
545 0u, // deUint32 binding;
546 vertexFormatPosition, // VkFormat format;
547 vertexBufferOffsetPosition, // deUint32 offset;
550 const VkVertexInputAttributeDescription vertexAttributeTexCoord =
552 1u, // deUint32 location;
553 0u, // deUint32 binding;
554 vertexFormatTexCoord, // VkFormat format;
555 vertexBufferOffsetTexCoord, // deUint32 offset;
559 GraphicsPipelineBuilder graphicPipelineBuilder;
561 graphicPipelineBuilder.addVertexBinding(vertexBinding);
562 graphicPipelineBuilder.addVertexAttribute(vertexAttributePosition);
563 graphicPipelineBuilder.addVertexAttribute(vertexAttributeTexCoord);
564 graphicPipelineBuilder.setPrimitiveTopology(vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP);
565 graphicPipelineBuilder.addDynamicState(VK_DYNAMIC_STATE_VIEWPORT);
566 graphicPipelineBuilder.addDynamicState(VK_DYNAMIC_STATE_SCISSOR);
567 graphicPipelineBuilder.setAttachmentsCount(2u);
568 graphicPipelineBuilder.setShader(deviceInterface, *m_logicalDevice, VK_SHADER_STAGE_VERTEX_BIT, m_context.getBinaryCollection().get("vertex_shader"), DE_NULL);
569 graphicPipelineBuilder.setShader(deviceInterface, *m_logicalDevice, VK_SHADER_STAGE_FRAGMENT_BIT, m_context.getBinaryCollection().get("fragment_shader"), DE_NULL);
571 if (imageSparseInfo.arrayLayers > 1u)
573 requireFeatures(instance, physicalDevice, FEATURE_GEOMETRY_SHADER);
574 graphicPipelineBuilder.setShader(deviceInterface, *m_logicalDevice, VK_SHADER_STAGE_GEOMETRY_BIT, m_context.getBinaryCollection().get("geometry_shader"), DE_NULL);
577 pipelines.push_back(makeVkSharedPtr(graphicPipelineBuilder.build(deviceInterface, *m_logicalDevice, *pipelineLayout, *renderPass)));
580 const VkPipeline graphicsPipeline = **pipelines[0];
583 const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
585 VkImageMemoryBarrier imageShaderAccessBarriers[3];
587 imageShaderAccessBarriers[0] = makeImageMemoryBarrier
589 VK_ACCESS_TRANSFER_WRITE_BIT,
590 VK_ACCESS_SHADER_READ_BIT,
591 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
592 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
594 fullImageSubresourceRange
597 imageShaderAccessBarriers[1] = makeImageMemoryBarrier
600 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
601 VK_IMAGE_LAYOUT_UNDEFINED,
602 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
604 fullImageSubresourceRange
607 imageShaderAccessBarriers[2] = makeImageMemoryBarrier
610 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
611 VK_IMAGE_LAYOUT_UNDEFINED,
612 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
614 fullImageSubresourceRange
617 deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 3u, imageShaderAccessBarriers);
620 imageSparseViews.resize(imageSparseInfo.mipLevels);
621 imageTexelsViews.resize(imageSparseInfo.mipLevels);
622 imageResidencyViews.resize(imageSparseInfo.mipLevels);
623 framebuffers.resize(imageSparseInfo.mipLevels);
624 descriptorSets.resize(imageSparseInfo.mipLevels);
626 std::vector<VkClearValue> clearValues;
627 clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
628 clearValues.push_back(makeClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 1.0f)));
630 for (deUint32 mipLevelNdx = 0u; mipLevelNdx < imageSparseInfo.mipLevels; ++mipLevelNdx)
632 const vk::VkExtent3D mipLevelSize = mipLevelExtents(imageSparseInfo.extent, mipLevelNdx);
634 const vk::VkRect2D renderArea =
636 makeOffset2D(0u, 0u),
637 makeExtent2D(mipLevelSize.width, mipLevelSize.height),
640 const VkViewport viewport = makeViewport
643 static_cast<float>(mipLevelSize.width), static_cast<float>(mipLevelSize.height),
647 const VkImageSubresourceRange mipLevelRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevelNdx, 1u, 0u, imageSparseInfo.arrayLayers);
649 // Create color attachments image views
650 imageTexelsViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, *m_logicalDevice, imageTexels, mapImageViewType(m_imageType), imageSparseInfo.format, mipLevelRange));
651 imageResidencyViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, *m_logicalDevice, imageResidency, mapImageViewType(m_imageType), mapTextureFormat(m_residencyFormat), mipLevelRange));
653 const VkImageView attachmentsViews[] = { **imageTexelsViews[mipLevelNdx], **imageResidencyViews[mipLevelNdx] };
655 // Create framebuffer
656 const VkFramebufferCreateInfo framebufferInfo =
658 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
659 DE_NULL, // const void* pNext;
660 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
661 *renderPass, // VkRenderPass renderPass;
662 2u, // uint32_t attachmentCount;
663 attachmentsViews, // const VkImageView* pAttachments;
664 mipLevelSize.width, // uint32_t width;
665 mipLevelSize.height, // uint32_t height;
666 imageSparseInfo.arrayLayers, // uint32_t layers;
669 framebuffers[mipLevelNdx] = makeVkSharedPtr(createFramebuffer(deviceInterface, *m_logicalDevice, &framebufferInfo));
671 // Create descriptor set
672 descriptorSets[mipLevelNdx] = makeVkSharedPtr(makeDescriptorSet(deviceInterface, *m_logicalDevice, *descriptorPool, *descriptorSetLayout));
673 const VkDescriptorSet descriptorSet = **descriptorSets[mipLevelNdx];
675 // Update descriptor set
676 const VkImageSubresourceRange sparseImageSubresourceRange = sampledImageRangeToBind(imageSparseInfo, mipLevelNdx);
678 imageSparseViews[mipLevelNdx] = makeVkSharedPtr(makeImageView(deviceInterface, *m_logicalDevice, imageSparse, mapImageViewType(m_imageType), imageSparseInfo.format, sparseImageSubresourceRange));
680 const VkDescriptorImageInfo imageSparseDescInfo = makeDescriptorImageInfo(*sampler, **imageSparseViews[mipLevelNdx], VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
682 DescriptorSetUpdateBuilder descriptorUpdateBuilder;
684 descriptorUpdateBuilder.writeSingle(descriptorSet, DescriptorSetUpdateBuilder::Location::binding(BINDING_IMAGE_SPARSE), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSparseDescInfo);
685 descriptorUpdateBuilder.update(deviceInterface, *m_logicalDevice);
688 beginRenderPass(deviceInterface, commandBuffer, *renderPass, **framebuffers[mipLevelNdx], renderArea, clearValues);
690 // Bind graphics pipeline
691 deviceInterface.cmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, graphicsPipeline);
693 // Bind descriptor set
694 deviceInterface.cmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayout, 0u, 1u, &descriptorSet, 0u, DE_NULL);
696 // Bind vertex buffer
697 deviceInterface.cmdBindVertexBuffers(commandBuffer, 0u, 1u, &vertexBuffer->get(), &vertexBufferStartOffset);
700 deviceInterface.cmdSetViewport(commandBuffer, 0u, 1u, &viewport);
702 // Bind Scissor Rectangle
703 deviceInterface.cmdSetScissor(commandBuffer, 0u, 1u, &renderArea);
705 // Update push constants
706 deviceInterface.cmdPushConstants(commandBuffer, *pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0u, sizeof(deUint32), &mipLevelNdx);
708 // Draw full screen quad
709 deviceInterface.cmdDraw(commandBuffer, 4u, 1u, 0u, 0u);
712 endRenderPass(deviceInterface, commandBuffer);
716 const VkImageSubresourceRange fullImageSubresourceRange = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
718 VkImageMemoryBarrier imageOutputTransferSrcBarriers[2];
720 imageOutputTransferSrcBarriers[0] = makeImageMemoryBarrier
722 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
723 VK_ACCESS_TRANSFER_READ_BIT,
724 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
725 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
727 fullImageSubresourceRange
730 imageOutputTransferSrcBarriers[1] = makeImageMemoryBarrier
732 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
733 VK_ACCESS_TRANSFER_READ_BIT,
734 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
735 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
737 fullImageSubresourceRange
740 deviceInterface.cmdPipelineBarrier(commandBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 2u, imageOutputTransferSrcBarriers);
744 class SparseShaderIntrinsicsInstanceSampledExplicit : public SparseShaderIntrinsicsInstanceSampledBase
747 SparseShaderIntrinsicsInstanceSampledExplicit (Context& context,
748 const SpirVFunction function,
749 const ImageType imageType,
750 const tcu::UVec3& imageSize,
751 const tcu::TextureFormat& format)
752 : SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
754 VkImageSubresourceRange sampledImageRangeToBind(const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const;
757 VkImageSubresourceRange SparseShaderIntrinsicsInstanceSampledExplicit::sampledImageRangeToBind (const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const
761 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, imageSparseInfo.mipLevels, 0u, imageSparseInfo.arrayLayers);
764 TestInstance* SparseShaderIntrinsicsCaseSampledExplicit::createInstance (Context& context) const
766 return new SparseShaderIntrinsicsInstanceSampledExplicit(context, m_function, m_imageType, m_imageSize, m_format);
769 class SparseShaderIntrinsicsInstanceSampledImplicit : public SparseShaderIntrinsicsInstanceSampledBase
772 SparseShaderIntrinsicsInstanceSampledImplicit (Context& context,
773 const SpirVFunction function,
774 const ImageType imageType,
775 const tcu::UVec3& imageSize,
776 const tcu::TextureFormat& format)
777 : SparseShaderIntrinsicsInstanceSampledBase(context, function, imageType, imageSize, format) {}
779 VkImageSubresourceRange sampledImageRangeToBind(const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const;
782 VkImageSubresourceRange SparseShaderIntrinsicsInstanceSampledImplicit::sampledImageRangeToBind (const VkImageCreateInfo& imageSparseInfo, const deUint32 mipLevel) const
784 return makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, mipLevel, 1u, 0u, imageSparseInfo.arrayLayers);
787 TestInstance* SparseShaderIntrinsicsCaseSampledImplicit::createInstance (Context& context) const
789 return new SparseShaderIntrinsicsInstanceSampledImplicit(context, m_function, m_imageType, m_imageSize, m_format);