1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2019 The Khronos Group Inc.
6 * Copyright (c) 2018 Google Inc.
7 * Copyright (c) 2015 Imagination Technologies Ltd.
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief Tests sparse input attachments in VkSubpassDescription::pInputAttachments
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktRenderPassUnusedAttachmentSparseFillingTests.hpp"
27 #include "vktRenderPassTestsUtil.hpp"
28 #include "vktTestCase.hpp"
29 #include "vkImageUtil.hpp"
30 #include "vkBarrierUtil.hpp"
31 #include "vkBuilderUtil.hpp"
32 #include "vkQueryUtil.hpp"
33 #include "vkCmdUtil.hpp"
34 #include "vkObjUtil.hpp"
35 #include "tcuTestLog.hpp"
36 #include "deRandom.hpp"
37 #include <sstream>
38 #include <vector>
39 #include <algorithm>
40 #include <numeric>
41 #include <random>
42
43 typedef de::SharedPtr<vk::Unique<vk::VkImage>> VkImageSp;
44 typedef de::SharedPtr<vk::Unique<vk::VkImageView>> VkImageViewSp;
45 typedef de::SharedPtr<vk::Unique<vk::VkBuffer>> VkBufferSp;
46 typedef de::SharedPtr<vk::Allocation> AllocationSp;
47
48 namespace vkt
49 {
50
51 namespace renderpass
52 {
53
54 using namespace vk;
55
56 template <typename T>
safeSharedPtr(T * ptr)57 de::SharedPtr<T> safeSharedPtr(T *ptr)
58 {
59 try
60 {
61 return de::SharedPtr<T>(ptr);
62 }
63 catch (...)
64 {
65 delete ptr;
66 throw;
67 }
68 }
69
70 static const uint32_t RENDER_SIZE = 8u;
71 static const unsigned int DEFAULT_SEED = 31u;
72
73 namespace
74 {
75
76 struct TestParams
77 {
78 SharedGroupParams groupParams;
79 uint32_t activeInputAttachmentCount;
80 };
81
82 struct Vertex
83 {
84 tcu::Vec4 position;
85 tcu::Vec4 uv;
86 };
87
createFullscreenTriangle(void)88 std::vector<Vertex> createFullscreenTriangle(void)
89 {
90 std::vector<Vertex> vertices;
91
92 for (uint32_t i = 0; i < 3; ++i)
93 {
94 float x = static_cast<float>((i << 1) & 2);
95 float y = static_cast<float>(i & 2);
96 vertices.push_back(
97 Vertex{tcu::Vec4(x * 2.0f - 1.0f, y * 2.0f - 1.0f, 0.0f, 1.0f), tcu::Vec4(x, y, 0.0f, 0.0f)});
98 }
99 return vertices;
100 }
101
generateInputAttachmentParams(RenderingType renderingType,uint32_t activeAttachmentCount,uint32_t allAttachmentCount,std::vector<uint32_t> & attachmentIndices,std::vector<uint32_t> & descriptorBindings)102 void generateInputAttachmentParams(RenderingType renderingType, uint32_t activeAttachmentCount,
103 uint32_t allAttachmentCount, std::vector<uint32_t> &attachmentIndices,
104 std::vector<uint32_t> &descriptorBindings)
105 {
106 DE_ASSERT(attachmentIndices.empty());
107 DE_ASSERT(descriptorBindings.empty());
108
109 attachmentIndices.resize(allAttachmentCount, VK_ATTACHMENT_UNUSED);
110 descriptorBindings.resize(activeAttachmentCount + 1, VK_ATTACHMENT_UNUSED);
111
112 de::Random random(DEFAULT_SEED);
113
114 // there is diference in test logic for dynamic rendering cases where attachment indices
115 // needed to be from range <0; 2 * activeAttachmentCount - 1> where for renderpass cases
116 // attachment indices had to be from range <0; activeAttachmentCount - 1>
117 if (renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
118 {
119 // fill all indices and shuffle them
120 std::iota(begin(attachmentIndices), end(attachmentIndices), 0);
121 random.shuffle(begin(attachmentIndices), end(attachmentIndices));
122
123 // set every other attachment as unused
124 for (uint32_t i = 0; i < (uint32_t)attachmentIndices.size(); i += 2)
125 attachmentIndices[i] = VK_ATTACHMENT_UNUSED;
126
127 // shuffle once again
128 random.shuffle(begin(attachmentIndices), end(attachmentIndices));
129
130 for (uint32_t i = 0, lastBinding = 1; i < allAttachmentCount; ++i)
131 {
132 if (attachmentIndices[i] != VK_ATTACHMENT_UNUSED)
133 descriptorBindings[lastBinding++] = attachmentIndices[i];
134 }
135 }
136 else
137 {
138 // fill half of indices
139 std::iota(begin(attachmentIndices), begin(attachmentIndices) + activeAttachmentCount, 0);
140
141 // shuffle values with remaining unused indices
142 random.shuffle(begin(attachmentIndices), end(attachmentIndices));
143
144 for (uint32_t i = 0, lastBinding = 1; i < allAttachmentCount; ++i)
145 {
146 if (attachmentIndices[i] != VK_ATTACHMENT_UNUSED)
147 descriptorBindings[lastBinding++] = i;
148 }
149 }
150 }
151
chooseInputImageLayout(const SharedGroupParams groupParams)152 VkImageLayout chooseInputImageLayout(const SharedGroupParams groupParams)
153 {
154 #ifndef CTS_USES_VULKANSC
155 if (groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
156 {
157 // use general layout for local reads for some tests
158 if (groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
159 return VK_IMAGE_LAYOUT_GENERAL;
160 return VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
161 }
162 #else
163 DE_UNREF(groupParams);
164 #endif
165 return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
166 }
167
168 #ifndef CTS_USES_VULKANSC
beginSecondaryCmdBuffer(const DeviceInterface & vk,VkCommandBuffer secCmdBuffer,std::vector<VkFormat> colorAttachmentFormats,const void * additionalInheritanceRenderingInfo=DE_NULL,VkCommandBufferUsageFlags usageFlags=0)169 void beginSecondaryCmdBuffer(const DeviceInterface &vk, VkCommandBuffer secCmdBuffer,
170 std::vector<VkFormat> colorAttachmentFormats,
171 const void *additionalInheritanceRenderingInfo = DE_NULL,
172 VkCommandBufferUsageFlags usageFlags = 0)
173 {
174 const VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo{
175 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
176 additionalInheritanceRenderingInfo, // const void* pNext;
177 0u, // VkRenderingFlagsKHR flags;
178 0u, // uint32_t viewMask;
179 (uint32_t)colorAttachmentFormats.size(), // uint32_t colorAttachmentCount;
180 colorAttachmentFormats.data(), // const VkFormat* pColorAttachmentFormats;
181 VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat;
182 VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat;
183 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
184 };
185 const VkCommandBufferInheritanceInfo bufferInheritanceInfo{
186 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO, // VkStructureType sType;
187 &inheritanceRenderingInfo, // const void* pNext;
188 DE_NULL, // VkRenderPass renderPass;
189 0u, // uint32_t subpass;
190 DE_NULL, // VkFramebuffer framebuffer;
191 VK_FALSE, // VkBool32 occlusionQueryEnable;
192 (VkQueryControlFlags)0u, // VkQueryControlFlags queryFlags;
193 (VkQueryPipelineStatisticFlags)0u // VkQueryPipelineStatisticFlags pipelineStatistics;
194 };
195 usageFlags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
196 const VkCommandBufferBeginInfo commandBufBeginParams{
197 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
198 DE_NULL, // const void* pNext;
199 usageFlags, // VkCommandBufferUsageFlags flags;
200 &bufferInheritanceInfo // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
201 };
202 VK_CHECK(vk.beginCommandBuffer(secCmdBuffer, &commandBufBeginParams));
203 }
204
getRenderingInputAttachmentIndexInfo(RenderingType renderingType,uint32_t activeAttachmentCount,std::vector<uint32_t> & inputAttachments)205 VkRenderingInputAttachmentIndexInfoKHR getRenderingInputAttachmentIndexInfo(RenderingType renderingType,
206 uint32_t activeAttachmentCount,
207 std::vector<uint32_t> &inputAttachments)
208 {
209 std::vector<uint32_t> unnededBindings;
210 generateInputAttachmentParams(renderingType, activeAttachmentCount, 2u * activeAttachmentCount, inputAttachments,
211 unnededBindings);
212
213 return {
214 VK_STRUCTURE_TYPE_RENDERING_INPUT_ATTACHMENT_INDEX_INFO_KHR,
215 DE_NULL,
216 (uint32_t)inputAttachments.size(), // uint32_t colorAttachmentCount
217 inputAttachments.data(), // const uint32_t* pColorAttachmentInputIndices
218 DE_NULL, // uint32_t depthInputAttachmentIndex
219 DE_NULL, // uint32_t stencilInputAttachmentIndex
220 };
221 }
222 #endif
223
224 class InputAttachmentSparseFillingTest : public vkt::TestCase
225 {
226 public:
227 InputAttachmentSparseFillingTest(tcu::TestContext &testContext, const std::string &name,
228 const TestParams &testParams);
229 virtual ~InputAttachmentSparseFillingTest(void) = default;
230 virtual void initPrograms(SourceCollections &sourceCollections) const;
231 virtual TestInstance *createInstance(Context &context) const;
232 virtual void checkSupport(Context &context) const;
233
234 private:
235 TestParams m_testParams;
236 };
237
238 class InputAttachmentSparseFillingTestInstance : public vkt::TestInstance
239 {
240 public:
241 InputAttachmentSparseFillingTestInstance(Context &context, const TestParams &testParams);
242 virtual ~InputAttachmentSparseFillingTestInstance(void) = default;
243 virtual tcu::TestStatus iterate(void);
244
245 protected:
246 template <typename RenderpassSubpass>
247 void createCommandBuffer(const DeviceInterface &vk, VkDevice vkDevice);
248 void createCommandBufferDynamicRendering(const DeviceInterface &vk, VkDevice vkDevice);
249 void preRenderCommands(const DeviceInterface &vk, VkCommandBuffer cmdBuffer);
250 void drawCommands(const DeviceInterface &vk, VkCommandBuffer cmdBuffer);
251 void postRenderCommands(const DeviceInterface &vk, VkCommandBuffer cmdBuffer);
252
253 template <typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep,
254 typename RenderPassCreateInfo>
255 Move<VkRenderPass> createRenderPass(const DeviceInterface &vk, VkDevice vkDevice);
256
257 private:
258 tcu::TestStatus verifyImage(void);
259
260 const tcu::UVec2 m_renderSize;
261 std::vector<Vertex> m_vertices;
262 TestParams m_testParams;
263
264 std::vector<VkImageSp> m_inputImages;
265 std::vector<AllocationSp> m_inputImageMemory;
266 std::vector<VkImageViewSp> m_inputImageViews;
267 VkImageLayout m_inputImageReadLayout;
268
269 VkImageSp m_outputImage;
270 AllocationSp m_outputImageMemory;
271 VkImageViewSp m_outputImageView;
272
273 VkBufferSp m_outputBuffer;
274 AllocationSp m_outputBufferMemory;
275
276 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
277 Move<VkDescriptorPool> m_descriptorPool;
278 Move<VkDescriptorSet> m_descriptorSet;
279 Move<VkRenderPass> m_renderPass;
280 Move<VkFramebuffer> m_framebuffer;
281
282 Move<VkBuffer> m_vertexBuffer;
283 de::MovePtr<Allocation> m_vertexBufferAlloc;
284
285 PipelineLayoutWrapper m_pipelineLayout;
286 GraphicsPipelineWrapper m_graphicsPipeline;
287
288 Move<VkCommandPool> m_cmdPool;
289 Move<VkCommandBuffer> m_cmdBuffer;
290 Move<VkCommandBuffer> m_secCmdBuffer;
291 };
292
InputAttachmentSparseFillingTest(tcu::TestContext & testContext,const std::string & name,const TestParams & testParams)293 InputAttachmentSparseFillingTest::InputAttachmentSparseFillingTest(tcu::TestContext &testContext,
294 const std::string &name,
295 const TestParams &testParams)
296 : vkt::TestCase(testContext, name)
297 , m_testParams(testParams)
298 {
299 }
300
initPrograms(SourceCollections & sourceCollections) const301 void InputAttachmentSparseFillingTest::initPrograms(SourceCollections &sourceCollections) const
302 {
303 std::ostringstream fragmentSource;
304
305 sourceCollections.glslSources.add("vertex") << glu::VertexSource("#version 450\n"
306 "layout(location = 0) in vec4 position;\n"
307 "layout(location = 1) in vec4 uv;\n"
308 "layout(location = 0) out vec4 outUV;\n"
309 "void main (void)\n"
310 "{\n"
311 " gl_Position = position;\n"
312 " outUV = uv;\n"
313 "}\n");
314
315 // We read from X input attachments randomly spread in input attachment array of size 2*X
316 std::ostringstream str;
317 str << "#version 450\n"
318 << "layout(location = 0) in vec4 inUV;\n"
319 << "layout(binding = 0, rg32ui) uniform uimage2D resultImage;\n";
320
321 std::vector<uint32_t> attachmentIndices, descriptorBindings;
322 generateInputAttachmentParams(m_testParams.groupParams->renderingType, m_testParams.activeInputAttachmentCount,
323 2u * m_testParams.activeInputAttachmentCount, attachmentIndices, descriptorBindings);
324
325 for (std::size_t i = 1; i < descriptorBindings.size(); ++i)
326 str << "layout(binding = " << i << ", input_attachment_index = " << descriptorBindings[i]
327 << ") uniform subpassInput attach" << i << ";\n";
328
329 str << "void main (void)\n"
330 << "{\n"
331 << " uvec4 result = uvec4(0);\n";
332
333 for (std::size_t i = 1; i < descriptorBindings.size(); ++i)
334 {
335 str << " result.x = result.x + 1;\n";
336 str << " if(subpassLoad(attach" << i << ").x > 0.0)\n";
337 str << " result.y = result.y + 1;\n";
338 }
339
340 str << " imageStore(resultImage, ivec2(imageSize(resultImage) * inUV.xy), result);\n"
341 << "}\n";
342
343 sourceCollections.glslSources.add("fragment") << glu::FragmentSource(str.str());
344 }
345
createInstance(Context & context) const346 TestInstance *InputAttachmentSparseFillingTest::createInstance(Context &context) const
347 {
348 return new InputAttachmentSparseFillingTestInstance(context, m_testParams);
349 }
350
checkSupport(Context & context) const351 void InputAttachmentSparseFillingTest::checkSupport(Context &context) const
352 {
353 const InstanceInterface &vki = context.getInstanceInterface();
354 vk::VkPhysicalDevice physicalDevice = context.getPhysicalDevice();
355 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(vki, physicalDevice);
356 const vk::VkPhysicalDeviceLimits &limits = properties.limits;
357
358 checkPipelineConstructionRequirements(vki, physicalDevice, m_testParams.groupParams->pipelineConstructionType);
359 if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
360 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
361 else if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
362 {
363 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering_local_read");
364 if ((2u * m_testParams.activeInputAttachmentCount) > limits.maxColorAttachments)
365 TCU_THROW(NotSupportedError, "Required number of color attachments not supported.");
366 }
367
368 if (2u * m_testParams.activeInputAttachmentCount > limits.maxPerStageDescriptorInputAttachments)
369 TCU_THROW(NotSupportedError,
370 "Input attachment count including unused elements exceeds maxPerStageDescriptorInputAttachments");
371
372 if (2u * m_testParams.activeInputAttachmentCount > limits.maxPerStageResources)
373 TCU_THROW(NotSupportedError, "Input attachment count including unused elements exceeds maxPerStageResources");
374 }
375
InputAttachmentSparseFillingTestInstance(Context & context,const TestParams & testParams)376 InputAttachmentSparseFillingTestInstance::InputAttachmentSparseFillingTestInstance(Context &context,
377 const TestParams &testParams)
378 : vkt::TestInstance(context)
379 , m_renderSize(RENDER_SIZE, RENDER_SIZE)
380 , m_vertices(createFullscreenTriangle())
381 , m_testParams(testParams)
382 , m_inputImageReadLayout(chooseInputImageLayout(testParams.groupParams))
383 , m_graphicsPipeline(context.getInstanceInterface(), context.getDeviceInterface(), context.getPhysicalDevice(),
384 context.getDevice(), context.getDeviceExtensions(),
385 m_testParams.groupParams->pipelineConstructionType)
386 {
387 const DeviceInterface &vk = m_context.getDeviceInterface();
388 const VkDevice vkDevice = m_context.getDevice();
389 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
390 SimpleAllocator memAlloc(
391 vk, vkDevice,
392 getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
393 const VkComponentMapping componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
394 VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
395
396 {
397 VkImageCreateInfo inputImageParams{
398 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
399 DE_NULL, // const void* pNext;
400 0u, // VkImageCreateFlags flags;
401 VK_IMAGE_TYPE_2D, // VkImageType imageType;
402 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
403 {m_renderSize.x(), m_renderSize.y(), 1u}, // VkExtent3D extent;
404 1u, // uint32_t mipLevels;
405 1u, // uint32_t arrayLayers;
406 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
407 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
408 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
409 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
410 1u, // uint32_t queueFamilyIndexCount;
411 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
412 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
413 };
414
415 if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
416 inputImageParams.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
417
418 VkImageViewCreateInfo inputAttachmentViewParams = {
419 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
420 DE_NULL, // const void* pNext;
421 0u, // VkImageViewCreateFlags flags;
422 0, // VkImage image;
423 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
424 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format;
425 componentMappingRGBA, // VkChannelMapping channels;
426 {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u} // VkImageSubresourceRange subresourceRange;
427 };
428
429 // Create input attachment images with image views
430 for (uint32_t imageNdx = 0; imageNdx < m_testParams.activeInputAttachmentCount; ++imageNdx)
431 {
432 auto inputImage = safeSharedPtr(new Unique<VkImage>(vk::createImage(vk, vkDevice, &inputImageParams)));
433
434 auto inputImageAlloc = safeSharedPtr(
435 memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, **inputImage), MemoryRequirement::Any)
436 .release());
437 VK_CHECK(
438 vk.bindImageMemory(vkDevice, **inputImage, inputImageAlloc->getMemory(), inputImageAlloc->getOffset()));
439
440 inputAttachmentViewParams.image = **inputImage;
441 auto inputImageView =
442 safeSharedPtr(new Unique<VkImageView>(createImageView(vk, vkDevice, &inputAttachmentViewParams)));
443
444 m_inputImages.push_back(inputImage);
445 m_inputImageMemory.push_back(inputImageAlloc);
446 m_inputImageViews.push_back(inputImageView);
447 }
448 }
449
450 {
451 const VkImageCreateInfo outputImageParams = {
452 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
453 DE_NULL, // const void* pNext;
454 0u, // VkImageCreateFlags flags;
455 VK_IMAGE_TYPE_2D, // VkImageType imageType;
456 VK_FORMAT_R32G32_UINT, // VkFormat format;
457 {m_renderSize.x(), m_renderSize.y(), 1u}, // VkExtent3D extent;
458 1u, // uint32_t mipLevels;
459 1u, // uint32_t arrayLayers;
460 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
461 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
462 VK_IMAGE_USAGE_STORAGE_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
463 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
464 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
465 1u, // uint32_t queueFamilyIndexCount;
466 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
467 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
468 };
469
470 m_outputImage = safeSharedPtr(new Unique<VkImage>(vk::createImage(vk, vkDevice, &outputImageParams)));
471 m_outputImageMemory = safeSharedPtr(
472 memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, **m_outputImage), MemoryRequirement::Any)
473 .release());
474 VK_CHECK(vk.bindImageMemory(vkDevice, **m_outputImage, m_outputImageMemory->getMemory(),
475 m_outputImageMemory->getOffset()));
476
477 VkImageViewCreateInfo inputAttachmentViewParams = {
478 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
479 DE_NULL, // const void* pNext;
480 0u, // VkImageViewCreateFlags flags;
481 **m_outputImage, // VkImage image;
482 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
483 VK_FORMAT_R32G32_UINT, // VkFormat format;
484 componentMappingRGBA, // VkChannelMapping channels;
485 {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u} // VkImageSubresourceRange subresourceRange;
486 };
487 m_outputImageView =
488 safeSharedPtr(new Unique<VkImageView>(createImageView(vk, vkDevice, &inputAttachmentViewParams)));
489 }
490
491 {
492 const VkDeviceSize outputBufferSizeBytes =
493 m_renderSize.x() * m_renderSize.y() * tcu::getPixelSize(mapVkFormat(VK_FORMAT_R32G32_UINT));
494 const VkBufferCreateInfo outputBufferParams = {
495 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // sType
496 DE_NULL, // pNext
497 (VkBufferCreateFlags)0u, // flags
498 outputBufferSizeBytes, // size
499 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage
500 VK_SHARING_MODE_EXCLUSIVE, // sharingMode
501 1u, // queueFamilyIndexCount
502 &queueFamilyIndex, // pQueueFamilyIndices
503 };
504 m_outputBuffer = safeSharedPtr(new Unique<VkBuffer>(createBuffer(vk, vkDevice, &outputBufferParams)));
505 m_outputBufferMemory = safeSharedPtr(
506 memAlloc
507 .allocate(getBufferMemoryRequirements(vk, vkDevice, **m_outputBuffer), MemoryRequirement::HostVisible)
508 .release());
509 VK_CHECK(vk.bindBufferMemory(vkDevice, **m_outputBuffer, m_outputBufferMemory->getMemory(),
510 m_outputBufferMemory->getOffset()));
511 }
512
513 // Create render pass
514 if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
515 m_renderPass = createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1,
516 SubpassDependency1, RenderPassCreateInfo1>(vk, vkDevice);
517 else if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
518 m_renderPass = createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2,
519 SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice);
520
521 std::vector<VkDescriptorImageInfo> descriptorImageInfos;
522 std::vector<VkImageView> framebufferImageViews;
523 descriptorImageInfos.push_back(VkDescriptorImageInfo{
524 DE_NULL, // VkSampleri sampler;
525 **m_outputImageView, // VkImageView imageView;
526 VK_IMAGE_LAYOUT_GENERAL // VkImageLayout imageLayout;
527 });
528 for (auto &inputImageView : m_inputImageViews)
529 {
530 framebufferImageViews.push_back(**inputImageView);
531 descriptorImageInfos.push_back(VkDescriptorImageInfo{
532 DE_NULL, // VkSampleri sampler;
533 **inputImageView, // VkImageView imageView;
534 m_inputImageReadLayout // VkImageLayout imageLayout;
535 });
536 }
537
538 // Create framebuffer if renderpass handle is valid
539 if (*m_renderPass != DE_NULL)
540 {
541 const VkFramebufferCreateInfo framebufferParams = {
542 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
543 DE_NULL, // const void* pNext;
544 0u, // VkFramebufferCreateFlags flags;
545 *m_renderPass, // VkRenderPass renderPass;
546 static_cast<uint32_t>(framebufferImageViews.size()), // uint32_t attachmentCount;
547 framebufferImageViews.data(), // const VkImageView* pAttachments;
548 static_cast<uint32_t>(m_renderSize.x()), // uint32_t width;
549 static_cast<uint32_t>(m_renderSize.y()), // uint32_t height;
550 1u // uint32_t layers;
551 };
552
553 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
554 }
555
556 // Create pipeline layout
557 {
558 DescriptorSetLayoutBuilder layoutBuilder;
559 // add output image storage
560 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, VK_SHADER_STAGE_FRAGMENT_BIT);
561 // add input attachments
562 for (uint32_t imageNdx = 0; imageNdx < m_testParams.activeInputAttachmentCount; ++imageNdx)
563 layoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, VK_SHADER_STAGE_FRAGMENT_BIT);
564 m_descriptorSetLayout = layoutBuilder.build(vk, vkDevice);
565
566 m_pipelineLayout = PipelineLayoutWrapper(m_testParams.groupParams->pipelineConstructionType, vk, vkDevice,
567 *m_descriptorSetLayout);
568 }
569
570 // Update descriptor set
571 {
572 m_descriptorPool = DescriptorPoolBuilder()
573 .addType(VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1u)
574 .addType(VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, m_testParams.activeInputAttachmentCount)
575 .build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
576
577 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {
578 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
579 DE_NULL, // const void* pNext
580 *m_descriptorPool, // VkDescriptorPool descriptorPool
581 1u, // uint32_t descriptorSetCount
582 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts
583 };
584 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
585
586 DescriptorSetUpdateBuilder builder;
587 builder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0u),
588 VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, &descriptorImageInfos[0]);
589 for (uint32_t i = 1; i < static_cast<uint32_t>(descriptorImageInfos.size()); ++i)
590 builder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(i),
591 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, &descriptorImageInfos[i]);
592 builder.update(vk, vkDevice);
593 }
594
595 ShaderWrapper vertexShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vertex"), 0);
596 ShaderWrapper fragmentShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("fragment"), 0);
597
598 // Create pipelines
599 {
600 const VkVertexInputBindingDescription vertexInputBindingDescription = {
601 0u, // uint32_t binding;
602 sizeof(Vertex), // uint32_t strideInBytes;
603 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate;
604 };
605
606 std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescription = {
607 {
608 0u, // uint32_t location;
609 0u, // uint32_t binding;
610 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
611 0u // uint32_t offset;
612 },
613 {
614 1u, // uint32_t location;
615 0u, // uint32_t binding;
616 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
617 offsetof(Vertex, uv) // uint32_t offset;
618 }};
619
620 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams{
621 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
622 DE_NULL, // const void* pNext;
623 0u, // VkPipelineVertexInputStateCreateFlags flags;
624 1u, // uint32_t vertexBindingDescriptionCount;
625 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
626 static_cast<uint32_t>(vertexInputAttributeDescription.size()), // uint32_t vertexAttributeDescriptionCount;
627 vertexInputAttributeDescription
628 .data() // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
629 };
630
631 VkPipelineColorBlendAttachmentState colorBlendAttachmentState;
632 deMemset(&colorBlendAttachmentState, 0x00, sizeof(VkPipelineColorBlendAttachmentState));
633 colorBlendAttachmentState.colorWriteMask = 0xF;
634
635 uint32_t colorAttachmentsCount = (*m_renderPass == DE_NULL) ? 2u * m_testParams.activeInputAttachmentCount : 1u;
636 const std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates(colorAttachmentsCount,
637 colorBlendAttachmentState);
638 VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfoDefault = initVulkanStructure();
639 colorBlendStateCreateInfoDefault.attachmentCount = uint32_t(colorBlendAttachmentStates.size());
640 colorBlendStateCreateInfoDefault.pAttachments = colorBlendAttachmentStates.data();
641
642 PipelineRenderingCreateInfoWrapper renderingCreateInfoWrapper;
643 RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfoWrapper;
644 const std::vector<VkViewport> viewports{makeViewport(m_renderSize)};
645 const std::vector<VkRect2D> scissors{makeRect2D(m_renderSize)};
646
647 #ifndef CTS_USES_VULKANSC
648 std::vector<uint32_t> inputAttachments;
649 auto renderingInputAttachmentIndexInfo = getRenderingInputAttachmentIndexInfo(
650 m_testParams.groupParams->renderingType, m_testParams.activeInputAttachmentCount, inputAttachments);
651
652 std::vector<VkFormat> colorAttachmentFormats(colorAttachmentsCount, VK_FORMAT_UNDEFINED);
653 for (uint32_t index = 0; index < colorAttachmentsCount; ++index)
654 {
655 if (inputAttachments[index] != VK_ATTACHMENT_UNUSED)
656 colorAttachmentFormats[index] = VK_FORMAT_R8G8B8A8_UNORM;
657 }
658
659 VkPipelineRenderingCreateInfo renderingCreateInfo{VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO,
660 DE_NULL,
661 0u,
662 (uint32_t)colorAttachmentFormats.size(),
663 colorAttachmentFormats.data(),
664 VK_FORMAT_UNDEFINED,
665 VK_FORMAT_UNDEFINED};
666
667 if (*m_renderPass == DE_NULL)
668 {
669 renderingCreateInfoWrapper.ptr = &renderingCreateInfo;
670 renderingInputAttachmentIndexInfoWrapper.ptr = &renderingInputAttachmentIndexInfo;
671 }
672 #endif // CTS_USES_VULKANSC
673
674 m_graphicsPipeline.setDefaultMultisampleState()
675 .setDefaultDepthStencilState()
676 .setDefaultRasterizationState()
677 .setupVertexInputState(&vertexInputStateParams)
678 .setupPreRasterizationShaderState(viewports, scissors, m_pipelineLayout, *m_renderPass, 0u,
679 vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(), ShaderWrapper(),
680 DE_NULL, DE_NULL, renderingCreateInfoWrapper, DE_NULL)
681 .setupFragmentShaderState(m_pipelineLayout, *m_renderPass, 0u, fragmentShaderModule, 0, 0, 0, 0, {},
682 renderingInputAttachmentIndexInfoWrapper)
683 .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateCreateInfoDefault)
684 .setMonolithicPipelineLayout(m_pipelineLayout)
685 .buildPipeline();
686 }
687
688 // Create vertex buffer
689 {
690 const VkBufferCreateInfo vertexBufferParams = {
691 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
692 DE_NULL, // const void* pNext;
693 0u, // VkBufferCreateFlags flags;
694 (VkDeviceSize)(sizeof(Vertex) * m_vertices.size()), // VkDeviceSize size;
695 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
696 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
697 1u, // uint32_t queueFamilyIndexCount;
698 &queueFamilyIndex // const uint32_t* pQueueFamilyIndices;
699 };
700
701 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
702 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer),
703 MemoryRequirement::HostVisible);
704 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(),
705 m_vertexBufferAlloc->getOffset()));
706
707 // Upload vertex data
708 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex));
709 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
710 }
711
712 // Create command pool
713 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
714
715 // Create command buffer
716 if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
717 createCommandBuffer<RenderpassSubpass1>(vk, vkDevice);
718 else if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
719 createCommandBuffer<RenderpassSubpass2>(vk, vkDevice);
720 else
721 createCommandBufferDynamicRendering(vk, vkDevice);
722 }
723
724 template <typename RenderpassSubpass>
createCommandBuffer(const DeviceInterface & vk,VkDevice vkDevice)725 void InputAttachmentSparseFillingTestInstance::createCommandBuffer(const DeviceInterface &vk, VkDevice vkDevice)
726 {
727 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
728
729 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
730
731 preRenderCommands(vk, *m_cmdBuffer);
732
733 // Render pass does not use clear values - input images were prepared beforehand
734 const VkRenderPassBeginInfo renderPassBeginInfo = {
735 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
736 DE_NULL, // const void* pNext;
737 *m_renderPass, // VkRenderPass renderPass;
738 *m_framebuffer, // VkFramebuffer framebuffer;
739 makeRect2D(m_renderSize), // VkRect2D renderArea;
740 0, // uint32_t clearValueCount;
741 DE_NULL // const VkClearValue* pClearValues;
742 };
743 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
744 RenderpassSubpass::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfo, &subpassBeginInfo);
745
746 drawCommands(vk, *m_cmdBuffer);
747
748 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
749 RenderpassSubpass::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
750
751 postRenderCommands(vk, *m_cmdBuffer);
752
753 endCommandBuffer(vk, *m_cmdBuffer);
754 }
755
createCommandBufferDynamicRendering(const DeviceInterface & vk,VkDevice vkDevice)756 void InputAttachmentSparseFillingTestInstance::createCommandBufferDynamicRendering(const DeviceInterface &vk,
757 VkDevice vkDevice)
758 {
759 #ifndef CTS_USES_VULKANSC
760
761 std::vector<uint32_t> inputAttachments;
762 const auto renderingInputAttachmentIndexInfo = getRenderingInputAttachmentIndexInfo(
763 m_testParams.groupParams->renderingType, m_testParams.activeInputAttachmentCount, inputAttachments);
764
765 uint32_t colorAttachmentCount = 2u * m_testParams.activeInputAttachmentCount;
766 std::vector<VkFormat> colorAttachmentFormats(colorAttachmentCount, VK_FORMAT_UNDEFINED);
767 std::vector<VkRenderingAttachmentInfo> colorAttachments(
768 colorAttachmentCount,
769 {
770 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType sType;
771 DE_NULL, // const void* pNext;
772 VK_NULL_HANDLE, // VkImageView imageView;
773 m_inputImageReadLayout, // VkImageLayout imageLayout;
774 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
775 DE_NULL, // VkImageView resolveImageView;
776 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
777 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
778 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
779 makeClearValueColorU32(0, 0, 0, 0) // VkClearValue clearValue;
780 });
781 uint32_t imageViewIndex = 0;
782 for (uint32_t index = 0; index < (uint32_t)inputAttachments.size(); ++index)
783 {
784 if (inputAttachments[index] == VK_ATTACHMENT_UNUSED)
785 continue;
786
787 colorAttachments[index].imageView = **m_inputImageViews[imageViewIndex];
788 colorAttachmentFormats[index] = VK_FORMAT_R8G8B8A8_UNORM;
789 ++imageViewIndex;
790 }
791
792 VkRenderingInfo renderingInfo{
793 VK_STRUCTURE_TYPE_RENDERING_INFO,
794 DE_NULL,
795 0, // VkRenderingFlagsKHR flags;
796 makeRect2D(m_renderSize), // VkRect2D renderArea;
797 1u, // uint32_t layerCount;
798 0u, // uint32_t viewMask;
799 (uint32_t)colorAttachments.size(), // uint32_t colorAttachmentCount;
800 colorAttachments.data(), // const VkRenderingAttachmentInfoKHR* pColorAttachments;
801 DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
802 DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
803 };
804
805 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
806
807 if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
808 {
809 m_secCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
810
811 // record secondary command buffer
812 beginSecondaryCmdBuffer(vk, *m_secCmdBuffer, colorAttachmentFormats);
813 vk.cmdBeginRendering(*m_secCmdBuffer, &renderingInfo);
814 vk.cmdSetRenderingInputAttachmentIndicesKHR(*m_secCmdBuffer, &renderingInputAttachmentIndexInfo);
815 drawCommands(vk, *m_secCmdBuffer);
816 vk.cmdEndRendering(*m_secCmdBuffer);
817 endCommandBuffer(vk, *m_secCmdBuffer);
818
819 // record primary command buffer
820 beginCommandBuffer(vk, *m_cmdBuffer);
821 preRenderCommands(vk, *m_cmdBuffer);
822 vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
823 postRenderCommands(vk, *m_cmdBuffer);
824 endCommandBuffer(vk, *m_cmdBuffer);
825 }
826 else if (m_testParams.groupParams->useSecondaryCmdBuffer)
827 {
828 m_secCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
829 renderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR;
830
831 // record secondary command buffer
832 beginSecondaryCmdBuffer(vk, *m_secCmdBuffer, colorAttachmentFormats, &renderingInputAttachmentIndexInfo,
833 VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT);
834 drawCommands(vk, *m_secCmdBuffer);
835 endCommandBuffer(vk, *m_secCmdBuffer);
836
837 // record primary command buffer
838 beginCommandBuffer(vk, *m_cmdBuffer);
839 preRenderCommands(vk, *m_cmdBuffer);
840 vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
841 vk.cmdSetRenderingInputAttachmentIndicesKHR(*m_cmdBuffer, &renderingInputAttachmentIndexInfo);
842 vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
843 vk.cmdEndRendering(*m_cmdBuffer);
844 postRenderCommands(vk, *m_cmdBuffer);
845 endCommandBuffer(vk, *m_cmdBuffer);
846 }
847 else
848 {
849 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
850 preRenderCommands(vk, *m_cmdBuffer);
851 vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
852
853 vk.cmdSetRenderingInputAttachmentIndicesKHR(*m_cmdBuffer, &renderingInputAttachmentIndexInfo);
854 drawCommands(vk, *m_cmdBuffer);
855
856 vk.cmdEndRendering(*m_cmdBuffer);
857 postRenderCommands(vk, *m_cmdBuffer);
858 endCommandBuffer(vk, *m_cmdBuffer);
859 }
860 #else
861 DE_UNREF(vk);
862 DE_UNREF(vkDevice);
863 #endif // CTS_USES_VULKANSC
864 }
865
preRenderCommands(const DeviceInterface & vk,VkCommandBuffer cmdBuffer)866 void InputAttachmentSparseFillingTestInstance::preRenderCommands(const DeviceInterface &vk, VkCommandBuffer cmdBuffer)
867 {
868 VkImageSubresourceRange range = makeImageSubresourceRange(VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u);
869 VkClearValue clearColor = makeClearValueColorU32(0, 0, 0, 0);
870
871 // clear output image (rg16ui) to (0,0), set image layout to GENERAL
872 VkImageMemoryBarrier imageBarrier = makeImageMemoryBarrier(
873 0u, VK_ACCESS_TRANSFER_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_GENERAL, **m_outputImage, range);
874 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u, DE_NULL,
875 0u, DE_NULL, 1u, &imageBarrier);
876
877 vk.cmdClearColorImage(cmdBuffer, **m_outputImage, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
878
879 imageBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_SHADER_WRITE_BIT,
880 VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_GENERAL, **m_outputImage, range);
881 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u,
882 DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
883
884 auto inputImageLayout = VK_IMAGE_LAYOUT_GENERAL;
885 if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
886 inputImageLayout = m_inputImageReadLayout;
887
888 // clear all input attachments (rgba8) to (1,1,1,1), set image layout to GENERAL or LOCAL_READ
889 clearColor = makeClearValueColorF32(1.0f, 1.0f, 1.0f, 1.0f);
890 for (auto &inputImage : m_inputImages)
891 {
892 imageBarrier = makeImageMemoryBarrier(0u, VK_ACCESS_MEMORY_WRITE_BIT, VK_IMAGE_LAYOUT_UNDEFINED,
893 VK_IMAGE_LAYOUT_GENERAL, **inputImage, range);
894 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0u, 0u,
895 DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
896
897 vk.cmdClearColorImage(cmdBuffer, **inputImage, VK_IMAGE_LAYOUT_GENERAL, &clearColor.color, 1, &range);
898
899 imageBarrier = makeImageMemoryBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
900 VK_IMAGE_LAYOUT_GENERAL, inputImageLayout, **inputImage, range);
901 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, 0u, 0u,
902 DE_NULL, 0u, DE_NULL, 1u, &imageBarrier);
903 }
904 }
905
drawCommands(const DeviceInterface & vk,VkCommandBuffer cmdBuffer)906 void InputAttachmentSparseFillingTestInstance::drawCommands(const DeviceInterface &vk, VkCommandBuffer cmdBuffer)
907 {
908 const VkDeviceSize vertexBufferOffset = 0;
909 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline.getPipeline());
910 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1u,
911 &m_descriptorSet.get(), 0u, DE_NULL);
912 vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
913 vk.cmdDraw(cmdBuffer, (uint32_t)m_vertices.size(), 1, 0, 0);
914 }
915
postRenderCommands(const DeviceInterface & vk,VkCommandBuffer cmdBuffer)916 void InputAttachmentSparseFillingTestInstance::postRenderCommands(const DeviceInterface &vk, VkCommandBuffer cmdBuffer)
917 {
918 copyImageToBuffer(vk, cmdBuffer, **m_outputImage, **m_outputBuffer, tcu::IVec2(m_renderSize.x(), m_renderSize.y()),
919 VK_ACCESS_SHADER_WRITE_BIT, VK_IMAGE_LAYOUT_GENERAL);
920 }
921
922 template <typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep,
923 typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vk,VkDevice vkDevice)924 Move<VkRenderPass> InputAttachmentSparseFillingTestInstance::createRenderPass(const DeviceInterface &vk,
925 VkDevice vkDevice)
926 {
927 const auto renderingType = m_testParams.groupParams->renderingType;
928 const VkImageAspectFlags aspectMask =
929 renderingType == RENDERING_TYPE_RENDERPASS_LEGACY ? 0 : VK_IMAGE_ASPECT_COLOR_BIT;
930 std::vector<AttachmentDesc> attachmentDescriptions;
931 std::vector<AttachmentRef> attachmentRefs;
932
933 std::vector<uint32_t> attachmentIndices;
934 std::vector<uint32_t> descriptorBindings;
935 generateInputAttachmentParams(renderingType, m_testParams.activeInputAttachmentCount,
936 2u * m_testParams.activeInputAttachmentCount, attachmentIndices, descriptorBindings);
937
938 for (uint32_t i = 0; i < m_testParams.activeInputAttachmentCount; ++i)
939 {
940 attachmentDescriptions.push_back(
941 AttachmentDesc(DE_NULL, // const void* pNext
942 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
943 VK_FORMAT_R8G8B8A8_UNORM, // VkFormat format
944 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
945 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp
946 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
947 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
948 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
949 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout initialLayout
950 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout finalLayout
951 ));
952 }
953 for (std::size_t i = 0; i < attachmentIndices.size(); ++i)
954 attachmentRefs.push_back(AttachmentRef(DE_NULL, // const void* pNext
955 attachmentIndices[i], // uint32_t attachment
956 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // VkImageLayout layout
957 aspectMask // VkImageAspectFlags aspectMask
958 ));
959
960 std::vector<SubpassDesc> subpassDescriptions = {
961 SubpassDesc(
962 DE_NULL,
963 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
964 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
965 0u, // uint32_t viewMask
966 static_cast<uint32_t>(attachmentRefs.size()), // uint32_t inputAttachmentCount
967 attachmentRefs.data(), // const VkAttachmentReference* pInputAttachments
968 0u, // uint32_t colorAttachmentCount
969 DE_NULL, // const VkAttachmentReference* pColorAttachments
970 DE_NULL, // const VkAttachmentReference* pResolveAttachments
971 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment
972 0u, // uint32_t preserveAttachmentCount
973 DE_NULL // const uint32_t* pPreserveAttachments
974 ),
975 };
976 std::vector<SubpassDep> subpassDependencies = {
977 SubpassDep(DE_NULL,
978 0u, // uint32_t srcPass
979 VK_SUBPASS_EXTERNAL, // uint32_t dstPass
980 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags srcStageMask
981 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, // VkPipelineStageFlags dstStageMask
982 VK_ACCESS_SHADER_WRITE_BIT, // VkAccessFlags srcAccessMask
983 VK_ACCESS_INDIRECT_COMMAND_READ_BIT, // VkAccessFlags dstAccessMask
984 0, // VkDependencyFlags flags
985 0 // int32_t viewOffset
986 ),
987 };
988
989 const RenderPassCreateInfo renderPassInfo(
990 DE_NULL, // const void* pNext
991 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
992 static_cast<uint32_t>(attachmentDescriptions.size()), // uint32_t attachmentCount
993 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments
994 static_cast<uint32_t>(subpassDescriptions.size()), // uint32_t subpassCount
995 subpassDescriptions.data(), // const VkSubpassDescription* pSubpasses
996 static_cast<uint32_t>(subpassDependencies.size()), // uint32_t dependencyCount
997 subpassDependencies.data(), // const VkSubpassDependency* pDependencies
998 0u, // uint32_t correlatedViewMaskCount
999 DE_NULL // const uint32_t* pCorrelatedViewMasks
1000 );
1001
1002 return renderPassInfo.createRenderPass(vk, vkDevice);
1003 }
1004
iterate(void)1005 tcu::TestStatus InputAttachmentSparseFillingTestInstance::iterate(void)
1006 {
1007 const DeviceInterface &vk = m_context.getDeviceInterface();
1008 const VkDevice vkDevice = m_context.getDevice();
1009 const VkQueue queue = m_context.getUniversalQueue();
1010
1011 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1012
1013 return verifyImage();
1014 }
1015
verifyImage(void)1016 tcu::TestStatus InputAttachmentSparseFillingTestInstance::verifyImage(void)
1017 {
1018 const DeviceInterface &vk = m_context.getDeviceInterface();
1019 const VkDevice vkDevice = m_context.getDevice();
1020
1021 invalidateAlloc(vk, vkDevice, *m_outputBufferMemory);
1022 const tcu::ConstPixelBufferAccess resultAccess(mapVkFormat(VK_FORMAT_R32G32_UINT), m_renderSize.x(),
1023 m_renderSize.y(), 1u, m_outputBufferMemory->getHostPtr());
1024
1025 // Log result image
1026 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Result", "Result images")
1027 << tcu::TestLog::Image("Rendered", "Rendered image", resultAccess)
1028 << tcu::TestLog::EndImageSet;
1029
1030 // Check the unused image data hasn't changed.
1031 for (int y = 0; y < resultAccess.getHeight(); y++)
1032 for (int x = 0; x < resultAccess.getWidth(); x++)
1033 {
1034 tcu::UVec4 color = resultAccess.getPixelUint(x, y);
1035 if (color.x() != m_testParams.activeInputAttachmentCount)
1036 return tcu::TestStatus::fail("Wrong attachment count");
1037 if (color.y() != m_testParams.activeInputAttachmentCount)
1038 return tcu::TestStatus::fail("Wrong active attachment count");
1039 }
1040
1041 return tcu::TestStatus::pass("Pass");
1042 }
1043
1044 } // namespace
1045
createRenderPassUnusedAttachmentSparseFillingTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)1046 tcu::TestCaseGroup *createRenderPassUnusedAttachmentSparseFillingTests(tcu::TestContext &testCtx,
1047 const SharedGroupParams groupParams)
1048 {
1049 // Unused attachment tests
1050 de::MovePtr<tcu::TestCaseGroup> unusedAttTests(new tcu::TestCaseGroup(testCtx, "attachment_sparse_filling"));
1051
1052 const std::vector<uint32_t> activeInputAttachmentCount{1u, 3u, 7u, 15u, 31u, 63u, 127u};
1053
1054 for (std::size_t attachmentNdx = 0; attachmentNdx < activeInputAttachmentCount.size(); ++attachmentNdx)
1055 {
1056 TestParams testParams{groupParams, activeInputAttachmentCount[attachmentNdx]};
1057 unusedAttTests->addChild(new InputAttachmentSparseFillingTest(
1058 testCtx, std::string("input_attachment_") + de::toString(activeInputAttachmentCount[attachmentNdx]),
1059 testParams));
1060 }
1061
1062 return unusedAttTests.release();
1063 }
1064
1065 } // namespace renderpass
1066
1067 } // namespace vkt
1068