1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2019 The Khronos Group Inc.
6 * Copyright (c) 2019 Valve Corporation.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Tests vkCmdClearAttachments with unused attachments.
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktRenderPassUnusedClearAttachmentTests.hpp"
26 #include "pipeline/vktPipelineImageUtil.hpp"
27 #include "vktRenderPassTestsUtil.hpp"
28 #include "vkQueryUtil.hpp"
29 #include "vkRefUtil.hpp"
30 #include "vkCmdUtil.hpp"
31 #include "vkObjUtil.hpp"
32 #include "vkImageUtil.hpp"
33 #include "tcuTextureUtil.hpp"
34 #include <sstream>
35 #include <functional>
36 #include <vector>
37 #include <string>
38 #include <memory>
39
40 namespace vkt
41 {
42 namespace renderpass
43 {
44
45 namespace
46 {
47
48 constexpr size_t COLOR_ATTACHMENTS_NUMBER = 4; // maxColorAttachments is guaranteed to be at least 4.
49 constexpr VkFormat FORMAT_COLOR = VK_FORMAT_R8G8B8A8_UNORM;
50 constexpr VkFormat FORMAT_DEPTH = VK_FORMAT_D32_SFLOAT;
51 constexpr VkFormat FORMAT_STENCIL = VK_FORMAT_S8_UINT;
52 constexpr VkFormat FORMAT_DEPTH_STENCIL = VK_FORMAT_D32_SFLOAT_S8_UINT;
53 const bool DE_BOOL_VALUES[] = {false, true};
54
55 enum DepthStencilType
56 {
57 DEPTH_STENCIL_NONE = 0,
58 DEPTH_STENCIL_DEPTH_ONLY = 1,
59 DEPTH_STENCIL_STENCIL_ONLY = 2,
60 DEPTH_STENCIL_BOTH = 3,
61 DEPTH_STENCIL_MAX_ENUM = 4
62 };
63
getFormatBriefName(VkFormat format)64 std::string getFormatBriefName(VkFormat format)
65 {
66 switch (format)
67 {
68 case VK_FORMAT_D32_SFLOAT:
69 return "d32";
70 case VK_FORMAT_S8_UINT:
71 return "s8";
72 case VK_FORMAT_D32_SFLOAT_S8_UINT:
73 return "d32s8";
74 default:
75 break;
76 }
77
78 return "";
79 }
80
depthStencilTypeName(DepthStencilType type,VkFormat format)81 std::string depthStencilTypeName(DepthStencilType type, VkFormat format)
82 {
83 DE_ASSERT(type >= DEPTH_STENCIL_NONE && type < DEPTH_STENCIL_MAX_ENUM);
84
85 const std::string formatName = getFormatBriefName(format);
86
87 switch (type)
88 {
89 case DEPTH_STENCIL_NONE:
90 return "nods";
91 case DEPTH_STENCIL_DEPTH_ONLY:
92 return "depthonly_" + formatName;
93 case DEPTH_STENCIL_STENCIL_ONLY:
94 return "stencilonly_" + formatName;
95 case DEPTH_STENCIL_BOTH:
96 return "depthstencil_" + formatName;
97 default:
98 return "UNKNOWN"; // Unreachable.
99 }
100
101 return "UNKNOWN"; // Unreachable.
102 }
103
getClearAspectMask(DepthStencilType type)104 VkImageAspectFlags getClearAspectMask(DepthStencilType type)
105 {
106 VkImageAspectFlags aspectMask = 0u;
107
108 if (type == DEPTH_STENCIL_DEPTH_ONLY || type == DEPTH_STENCIL_BOTH)
109 aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
110
111 if (type == DEPTH_STENCIL_STENCIL_ONLY || type == DEPTH_STENCIL_BOTH)
112 aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
113
114 return aspectMask;
115 }
116
getFormatAspectMask(VkFormat format)117 VkImageAspectFlags getFormatAspectMask(VkFormat format)
118 {
119 const auto order = mapVkFormat(format).order;
120 VkImageAspectFlags aspectMask = 0u;
121
122 if (tcu::hasDepthComponent(order))
123 aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
124
125 if (tcu::hasStencilComponent(order))
126 aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
127
128 if (!aspectMask)
129 aspectMask |= VK_IMAGE_ASPECT_COLOR_BIT;
130
131 return aspectMask;
132 }
133
getFormats(DepthStencilType type)134 std::vector<VkFormat> getFormats(DepthStencilType type)
135 {
136 DE_ASSERT(type >= DEPTH_STENCIL_NONE && type < DEPTH_STENCIL_MAX_ENUM);
137
138 std::vector<VkFormat> formats;
139
140 if (type != DEPTH_STENCIL_NONE)
141 formats.push_back(FORMAT_DEPTH_STENCIL);
142 else
143 formats.push_back(VK_FORMAT_UNDEFINED);
144
145 if (type == DEPTH_STENCIL_DEPTH_ONLY)
146 formats.push_back(FORMAT_DEPTH);
147 else if (type == DEPTH_STENCIL_STENCIL_ONLY)
148 formats.push_back(FORMAT_STENCIL);
149
150 return formats;
151 }
152
isDepthOnly(DepthStencilType type)153 bool isDepthOnly(DepthStencilType type)
154 {
155 return (type == DEPTH_STENCIL_DEPTH_ONLY);
156 }
157
isStencilOnly(DepthStencilType type)158 bool isStencilOnly(DepthStencilType type)
159 {
160 return (type == DEPTH_STENCIL_STENCIL_ONLY);
161 }
162
hasDepthStencil(DepthStencilType type)163 bool hasDepthStencil(DepthStencilType type)
164 {
165 return (type != DEPTH_STENCIL_NONE);
166 }
167
168 struct TestParams
169 {
TestParamsvkt::renderpass::__anon0918147e0111::TestParams170 TestParams(size_t numColorAttachments, DepthStencilType depthStencilType_, bool depthStencilUsed_,
171 VkFormat depthStencilFormat_, const SharedGroupParams groupParams_)
172 : colorUsed(numColorAttachments, false)
173 , depthStencilType(depthStencilType_)
174 , depthStencilUsed(depthStencilUsed_)
175 , depthStencilFormat(depthStencilFormat_)
176 , groupParams(groupParams_)
177 {
178 }
179
180 std::vector<bool> colorUsed;
181 DepthStencilType depthStencilType;
182 bool depthStencilUsed;
183 VkFormat depthStencilFormat;
184 const SharedGroupParams groupParams;
185 };
186
187 class UnusedClearAttachmentTestInstance : public vkt::TestInstance
188 {
189 public:
190 UnusedClearAttachmentTestInstance(Context &context, const TestParams &testParams);
~UnusedClearAttachmentTestInstance(void)191 virtual ~UnusedClearAttachmentTestInstance(void)
192 {
193 }
194 virtual tcu::TestStatus iterate(void);
195 template <typename RenderpassSubpass>
196 void createCommandBuffer(const DeviceInterface &vk, VkDevice vkDevice);
197
198 #ifndef CTS_USES_VULKANSC
199 void createCommandBufferDynamicRendering(const DeviceInterface &vk, VkDevice vkDevice);
200 #endif // CTS_USES_VULKANSC
201
202 private:
203 static constexpr uint32_t kImageWidth = 32;
204 static constexpr uint32_t kImageHeight = 32;
205 const tcu::UVec2 m_renderSize = {kImageWidth, kImageHeight};
206
207 VkClearValue m_initialColor;
208 VkClearValue m_initialColorDepth;
209 VkClearValue m_clearColor;
210 VkClearValue m_clearColorDepth;
211
212 const TestParams m_testParams;
213
214 std::vector<Move<VkImage>> m_colorImages;
215 std::vector<de::MovePtr<Allocation>> m_colorImageAllocs;
216 std::vector<Move<VkImageView>> m_colorAttachmentViews;
217
218 Move<VkImage> m_depthImage;
219 de::MovePtr<Allocation> m_depthImageAlloc;
220 Move<VkImageView> m_depthAttachmentView;
221
222 Move<VkRenderPass> m_renderPass;
223 Move<VkFramebuffer> m_framebuffer;
224 Move<VkShaderModule> m_vertexShaderModule;
225 Move<VkShaderModule> m_fragmentShaderModule;
226 Move<VkDescriptorSetLayout> m_descriptorSetLayout;
227 Move<VkPipelineLayout> m_pipelineLayout;
228 Move<VkPipeline> m_graphicsPipeline;
229 Move<VkCommandPool> m_cmdPool;
230 Move<VkCommandBuffer> m_cmdBuffer;
231 Move<VkCommandBuffer> m_secCmdBuffer;
232 };
233
234 class UnusedClearAttachmentTest : public vkt::TestCase
235 {
236 public:
UnusedClearAttachmentTest(tcu::TestContext & testContext,const std::string & name,const TestParams & testParams)237 UnusedClearAttachmentTest(tcu::TestContext &testContext, const std::string &name, const TestParams &testParams)
238 : vkt::TestCase(testContext, name)
239 , m_testParams(testParams)
240 {
241 }
~UnusedClearAttachmentTest(void)242 virtual ~UnusedClearAttachmentTest(void)
243 {
244 }
245 virtual void initPrograms(SourceCollections &sourceCollections) const;
246 virtual TestInstance *createInstance(Context &context) const;
247 virtual void checkSupport(Context &context) const;
248
249 private:
250 const TestParams m_testParams;
251 };
252
checkFormatSupported(Context & context,VkFormat format,VkImageUsageFlags usage)253 void checkFormatSupported(Context &context, VkFormat format, VkImageUsageFlags usage)
254 {
255 VkResult result;
256 VkImageFormatProperties properties;
257
258 result = context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(
259 context.getPhysicalDevice(), format, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, usage, 0, &properties);
260
261 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
262 {
263 std::ostringstream msg;
264 msg << "Format " << format << " not supported for usage flags 0x" << std::hex << usage;
265 TCU_THROW(NotSupportedError, msg.str());
266 }
267
268 VK_CHECK(result);
269 }
270
checkSupport(Context & context) const271 void UnusedClearAttachmentTest::checkSupport(Context &context) const
272 {
273 // Check for renderpass2 extension if used
274 if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
275 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
276
277 // Check for dynamic_rendering extension if used
278 if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
279 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
280
281 // Check support for the needed color, depth and stencil formats.
282 if (!m_testParams.colorUsed.empty())
283 checkFormatSupported(context, FORMAT_COLOR, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
284
285 if (hasDepthStencil(m_testParams.depthStencilType))
286 checkFormatSupported(context, m_testParams.depthStencilFormat, VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
287 }
288
createInstance(Context & context) const289 TestInstance *UnusedClearAttachmentTest::createInstance(Context &context) const
290 {
291 return new UnusedClearAttachmentTestInstance(context, m_testParams);
292 }
293
294 // These shaders are needed to create the graphics pipeline, but they will not be actually used because we will not draw anything.
initPrograms(SourceCollections & sourceCollections) const295 void UnusedClearAttachmentTest::initPrograms(SourceCollections &sourceCollections) const
296 {
297 // Vertex shader.
298 sourceCollections.glslSources.add("vert_shader") << glu::VertexSource("#version 450\n"
299 "precision highp float;\n"
300 "layout(location = 0) in vec4 position;\n"
301 "layout(location = 0) out vec4 vtxColor;\n"
302 "void main (void)\n"
303 "{\n"
304 "\tgl_Position = position;\n"
305 "\tvtxColor = vec4(0.5, 0.5, 0.5, 1.0);\n"
306 "}\n");
307
308 // Fragment shader.
309 std::ostringstream fragmentSource;
310
311 fragmentSource << "#version 450\n"
312 << "precision highp float;\n"
313 << "layout(location = 0) in vec4 vtxColor;\n";
314
315 for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
316 {
317 if (m_testParams.colorUsed[i])
318 fragmentSource << "layout(location = " << i << ") out vec4 fragColor" << i << ";\n";
319 }
320
321 fragmentSource << "void main (void)\n"
322 << "{\n";
323
324 for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
325 {
326 if (m_testParams.colorUsed[i])
327 fragmentSource << "\tfragColor" << i << " = vtxColor;\n";
328 }
329
330 fragmentSource << "}\n";
331
332 sourceCollections.glslSources.add("frag_shader") << glu::FragmentSource(fragmentSource.str());
333 }
334
335 // Create a render pass for this use case.
336 template <typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep,
337 typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vk,VkDevice vkDevice,const TestParams testParams)338 Move<VkRenderPass> createRenderPass(const DeviceInterface &vk, VkDevice vkDevice, const TestParams testParams)
339 {
340 const VkImageAspectFlags colorAspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
341 const VkImageAspectFlags dsClearAspectMask = getClearAspectMask(testParams.depthStencilType);
342 const bool isDepthStencil = hasDepthStencil(testParams.depthStencilType);
343
344 // Create attachment descriptions.
345 const AttachmentDesc attachmentDescription(
346 DE_NULL, // const void* pNext
347 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
348 FORMAT_COLOR, // VkFormat format
349 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
350 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp
351 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp
352 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp
353 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp
354 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout
355 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
356 );
357 std::vector<AttachmentDesc> attachmentDescriptions(testParams.colorUsed.size(), attachmentDescription);
358
359 if (isDepthStencil)
360 {
361 const bool depthOnly = isDepthOnly(testParams.depthStencilType);
362 const bool stencilOnly = isStencilOnly(testParams.depthStencilType);
363 const VkAttachmentLoadOp depthLoadOp =
364 (stencilOnly ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_LOAD);
365 const VkAttachmentStoreOp depthStoreOp =
366 (stencilOnly ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE);
367 const VkAttachmentLoadOp stencilLoadOp =
368 (depthOnly ? VK_ATTACHMENT_LOAD_OP_DONT_CARE : VK_ATTACHMENT_LOAD_OP_LOAD);
369 const VkAttachmentStoreOp stencilStoreOp =
370 (depthOnly ? VK_ATTACHMENT_STORE_OP_DONT_CARE : VK_ATTACHMENT_STORE_OP_STORE);
371
372 attachmentDescriptions.emplace_back(
373 nullptr, // const void* pNext
374 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
375 testParams.depthStencilFormat, // VkFormat format
376 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
377 depthLoadOp, // VkAttachmentLoadOp loadOp
378 depthStoreOp, // VkAttachmentStoreOp storeOp
379 stencilLoadOp, // VkAttachmentLoadOp stencilLoadOp
380 stencilStoreOp, // VkAttachmentStoreOp stencilStoreOp
381 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout
382 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout
383 );
384 }
385
386 // Mark attachments as used or not depending on the test parameters.
387 std::vector<AttachmentRef> attachmentReferences;
388 for (size_t i = 0; i < testParams.colorUsed.size(); ++i)
389 {
390 attachmentReferences.push_back(
391 AttachmentRef(DE_NULL, // const void* pNext
392 (testParams.colorUsed[i] ? static_cast<uint32_t>(i) :
393 VK_ATTACHMENT_UNUSED), // uint32_t attachment
394 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout
395 colorAspectMask // VkImageAspectFlags aspectMask
396 ));
397 }
398
399 std::unique_ptr<AttachmentRef> depthAttachmentRef;
400 if (isDepthStencil)
401 {
402 depthAttachmentRef.reset(new AttachmentRef(
403 DE_NULL,
404 (testParams.depthStencilUsed ? static_cast<uint32_t>(testParams.colorUsed.size()) : VK_ATTACHMENT_UNUSED),
405 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, dsClearAspectMask));
406 }
407
408 // Create subpass description with the previous color attachment references.
409 const SubpassDesc subpassDescription(
410 DE_NULL,
411 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
412 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
413 0u, // uint32_t viewMask
414 0u, // uint32_t inputAttachmentCount
415 DE_NULL, // const VkAttachmentReference* pInputAttachments
416 static_cast<uint32_t>(attachmentReferences.size()), // uint32_t colorAttachmentCount
417 (attachmentReferences.empty() ?
418 DE_NULL :
419 attachmentReferences.data()), // const VkAttachmentReference* pColorAttachments
420 DE_NULL, // const VkAttachmentReference* pResolveAttachments
421 (depthAttachmentRef ? depthAttachmentRef.get() :
422 DE_NULL), // const VkAttachmentReference* pDepthStencilAttachment
423 0u, // uint32_t preserveAttachmentCount
424 DE_NULL // const uint32_t* pPreserveAttachments
425 );
426
427 const RenderPassCreateInfo renderPassInfo(
428 DE_NULL, // const void* pNext
429 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
430 static_cast<uint32_t>(attachmentDescriptions.size()), // uint32_t attachmentCount
431 (attachmentDescriptions.empty() ?
432 DE_NULL :
433 attachmentDescriptions.data()), // const VkAttachmentDescription* pAttachments
434 1u, // uint32_t subpassCount
435 &subpassDescription, // const VkSubpassDescription* pSubpasses
436 0u, // uint32_t dependencyCount
437 DE_NULL, // const VkSubpassDependency* pDependencies
438 0u, // uint32_t correlatedViewMaskCount
439 DE_NULL // const uint32_t* pCorrelatedViewMasks
440 );
441
442 return renderPassInfo.createRenderPass(vk, vkDevice);
443 }
444
UnusedClearAttachmentTestInstance(Context & context,const TestParams & testParams)445 UnusedClearAttachmentTestInstance::UnusedClearAttachmentTestInstance(Context &context, const TestParams &testParams)
446 : vkt::TestInstance(context)
447 , m_testParams(testParams)
448 {
449 // Initial color for all images.
450 m_initialColor.color.float32[0] = 0.0f;
451 m_initialColor.color.float32[1] = 0.0f;
452 m_initialColor.color.float32[2] = 0.0f;
453 m_initialColor.color.float32[3] = 1.0f;
454
455 m_initialColorDepth.depthStencil.depth = 1.0f;
456 m_initialColorDepth.depthStencil.stencil = 0u;
457
458 // Clear color for used attachments.
459 m_clearColor.color.float32[0] = 1.0f;
460 m_clearColor.color.float32[1] = 1.0f;
461 m_clearColor.color.float32[2] = 1.0f;
462 m_clearColor.color.float32[3] = 1.0f;
463
464 m_clearColorDepth.depthStencil.depth = 0.0f;
465 m_clearColorDepth.depthStencil.stencil = 255u;
466
467 const DeviceInterface &vk = m_context.getDeviceInterface();
468 const VkDevice vkDevice = m_context.getDevice();
469 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
470 SimpleAllocator memAlloc(
471 vk, vkDevice,
472 getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
473 const VkComponentMapping componentMapping = {VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY,
474 VK_COMPONENT_SWIZZLE_IDENTITY, VK_COMPONENT_SWIZZLE_IDENTITY};
475
476 // Create color images.
477 {
478 const VkImageCreateInfo colorImageParams = {
479 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
480 DE_NULL, // const void* pNext;
481 0u, // VkImageCreateFlags flags;
482 VK_IMAGE_TYPE_2D, // VkImageType imageType;
483 FORMAT_COLOR, // VkFormat format;
484 {kImageWidth, kImageHeight, 1u}, // VkExtent3D extent;
485 1u, // uint32_t mipLevels;
486 1u, // uint32_t arrayLayers;
487 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
488 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
489 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
490 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
491 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
492 1u, // uint32_t queueFamilyIndexCount;
493 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
494 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
495 };
496
497 const VkImageCreateInfo depthImageParams = {
498 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
499 DE_NULL, // const void* pNext;
500 0u, // VkImageCreateFlags flags;
501 VK_IMAGE_TYPE_2D, // VkImageType imageType;
502 m_testParams.depthStencilFormat, // VkFormat format;
503 {kImageWidth, kImageHeight, 1u}, // VkExtent3D extent;
504 1u, // uint32_t mipLevels;
505 1u, // uint32_t arrayLayers;
506 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
507 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
508 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
509 VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
510 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
511 1u, // uint32_t queueFamilyIndexCount;
512 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
513 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
514 };
515
516 for (size_t i = 0; i < testParams.colorUsed.size(); ++i)
517 {
518 // Create, allocate and bind image memory.
519 m_colorImages.emplace_back(createImage(vk, vkDevice, &colorImageParams));
520 m_colorImageAllocs.emplace_back(memAlloc.allocate(
521 getImageMemoryRequirements(vk, vkDevice, *m_colorImages.back()), MemoryRequirement::Any));
522 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImages.back(), m_colorImageAllocs.back()->getMemory(),
523 m_colorImageAllocs.back()->getOffset()));
524
525 // Create image view.
526 {
527 const VkImageViewCreateInfo colorAttachmentViewParams = {
528 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
529 DE_NULL, // const void* pNext;
530 0u, // VkImageViewCreateFlags flags;
531 *m_colorImages.back(), // VkImage image;
532 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
533 FORMAT_COLOR, // VkFormat format;
534 componentMapping, // VkChannelMapping channels;
535 {VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u} // VkImageSubresourceRange subresourceRange;
536 };
537
538 m_colorAttachmentViews.emplace_back(createImageView(vk, vkDevice, &colorAttachmentViewParams));
539 }
540
541 // Clear image and leave it prepared to be used as a color attachment.
542 {
543 const VkImageAspectFlags aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
544 Move<VkCommandPool> cmdPool;
545 Move<VkCommandBuffer> cmdBuffer;
546
547 // Create command pool and buffer
548 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
549 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
550
551 // From undefined layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
552 const VkImageMemoryBarrier preImageBarrier = {
553 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
554 DE_NULL, // const void* pNext;
555 0u, // VkAccessFlags srcAccessMask;
556 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
557 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
558 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
559 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
560 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
561 *m_colorImages.back(), // VkImage image;
562 {
563 // VkImageSubresourceRange subresourceRange;
564 aspectMask, // VkImageAspect aspect;
565 0u, // uint32_t baseMipLevel;
566 1u, // uint32_t mipLevels;
567 0u, // uint32_t baseArraySlice;
568 1u // uint32_t arraySize;
569 }};
570
571 // From VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL.
572 const VkImageMemoryBarrier postImageBarrier = {
573 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
574 DE_NULL, // const void* pNext;
575 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
576 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
577 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
578 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
579 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
580 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
581 *m_colorImages.back(), // VkImage image;
582 {
583 // VkImageSubresourceRange subresourceRange;
584 aspectMask, // VkImageAspect aspect;
585 0u, // uint32_t baseMipLevel;
586 1u, // uint32_t mipLevels;
587 0u, // uint32_t baseArraySlice;
588 1u // uint32_t arraySize;
589 }};
590
591 const VkImageSubresourceRange clearRange = {
592 aspectMask, // VkImageAspectFlags aspectMask;
593 0u, // uint32_t baseMipLevel;
594 1u, // uint32_t levelCount;
595 0u, // uint32_t baseArrayLayer;
596 1u // uint32_t layerCount;
597 };
598
599 // Clear image and transfer layout.
600 beginCommandBuffer(vk, *cmdBuffer);
601 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
602 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
603 (const VkBufferMemoryBarrier *)DE_NULL, 1, &preImageBarrier);
604 vk.cmdClearColorImage(*cmdBuffer, *m_colorImages.back(), VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
605 &m_initialColor.color, 1, &clearRange);
606 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
607 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
608 (const VkBufferMemoryBarrier *)DE_NULL, 1, &postImageBarrier);
609 endCommandBuffer(vk, *cmdBuffer);
610
611 submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), cmdBuffer.get());
612 }
613 }
614
615 if (hasDepthStencil(m_testParams.depthStencilType))
616 {
617 const VkImageAspectFlags clearAspectMask = getClearAspectMask(m_testParams.depthStencilType);
618 const VkImageAspectFlags formatAspectMask = getFormatAspectMask(m_testParams.depthStencilFormat);
619
620 // Create, allocate and bind image memory.
621 m_depthImage = createImage(vk, vkDevice, &depthImageParams);
622 m_depthImageAlloc =
623 memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_depthImage), MemoryRequirement::Any);
624 VK_CHECK(vk.bindImageMemory(vkDevice, *m_depthImage, m_depthImageAlloc->getMemory(),
625 m_depthImageAlloc->getOffset()));
626
627 // Create image view.
628 {
629 const VkImageViewCreateInfo depthAttachmentViewParams = {
630 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
631 DE_NULL, // const void* pNext;
632 0u, // VkImageViewCreateFlags flags;
633 *m_depthImage, // VkImage image;
634 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
635 m_testParams.depthStencilFormat, // VkFormat format;
636 componentMapping, // VkChannelMapping channels;
637 {clearAspectMask, 0u, 1u, 0u, 1u} // VkImageSubresourceRange subresourceRange;
638 };
639
640 m_depthAttachmentView = createImageView(vk, vkDevice, &depthAttachmentViewParams);
641 }
642
643 // Clear image and leave it prepared to be used as a depth/stencil attachment.
644 {
645 Move<VkCommandPool> cmdPool;
646 Move<VkCommandBuffer> cmdBuffer;
647
648 // Create command pool and buffer
649 cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
650 cmdBuffer = allocateCommandBuffer(vk, vkDevice, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
651
652 // From undefined layout to VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL.
653 const VkImageMemoryBarrier preImageBarrier = {
654 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
655 DE_NULL, // const void* pNext;
656 0u, // VkAccessFlags srcAccessMask;
657 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask;
658 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
659 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout newLayout;
660 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
661 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
662 *m_depthImage, // VkImage image;
663 {
664 // VkImageSubresourceRange subresourceRange;
665 formatAspectMask, // VkImageAspect aspect;
666 0u, // uint32_t baseMipLevel;
667 1u, // uint32_t mipLevels;
668 0u, // uint32_t baseArraySlice;
669 1u // uint32_t arraySize;
670 }};
671
672 // From VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL to VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL.
673 const VkImageMemoryBarrier postImageBarrier = {
674 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
675 DE_NULL, // const void* pNext;
676 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
677 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags dstAccessMask;
678 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
679 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout;
680 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
681 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
682 *m_depthImage, // VkImage image;
683 {
684 // VkImageSubresourceRange subresourceRange;
685 formatAspectMask, // VkImageAspect aspect;
686 0u, // uint32_t baseMipLevel;
687 1u, // uint32_t mipLevels;
688 0u, // uint32_t baseArraySlice;
689 1u // uint32_t arraySize;
690 }};
691
692 const VkImageSubresourceRange clearRange = {
693 clearAspectMask, // VkImageAspectFlags aspectMask;
694 0u, // uint32_t baseMipLevel;
695 1u, // uint32_t levelCount;
696 0u, // uint32_t baseArrayLayer;
697 1u // uint32_t layerCount;
698 };
699
700 // Clear image and transfer layout.
701 beginCommandBuffer(vk, *cmdBuffer);
702 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
703 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
704 (const VkBufferMemoryBarrier *)DE_NULL, 1, &preImageBarrier);
705 vk.cmdClearDepthStencilImage(*cmdBuffer, *m_depthImage, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
706 &m_initialColorDepth.depthStencil, 1, &clearRange);
707 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
708 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 0,
709 (const VkBufferMemoryBarrier *)DE_NULL, 1, &postImageBarrier);
710 endCommandBuffer(vk, *cmdBuffer);
711
712 submitCommandsAndWait(vk, vkDevice, m_context.getUniversalQueue(), cmdBuffer.get());
713 }
714 }
715 }
716
717 // Create render pass when dynamic_rendering is not tested
718 if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
719 m_renderPass = createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1,
720 SubpassDependency1, RenderPassCreateInfo1>(vk, vkDevice, testParams);
721 else if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
722 m_renderPass = createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2,
723 SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice, testParams);
724
725 // Create framebuffer
726 if (testParams.groupParams->renderingType != RENDERING_TYPE_DYNAMIC_RENDERING)
727 {
728 std::vector<VkImageView> imageViews;
729
730 for (auto &movePtr : m_colorAttachmentViews)
731 imageViews.push_back(movePtr.get());
732
733 if (hasDepthStencil(m_testParams.depthStencilType))
734 imageViews.push_back(m_depthAttachmentView.get());
735
736 const VkFramebufferCreateInfo framebufferParams = {
737 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
738 DE_NULL, // const void* pNext;
739 0u, // VkFramebufferCreateFlags flags;
740 *m_renderPass, // VkRenderPass renderPass;
741 static_cast<uint32_t>(imageViews.size()), // uint32_t attachmentCount;
742 (imageViews.empty() ? DE_NULL : imageViews.data()), // const VkImageView* pAttachments;
743 kImageWidth, // uint32_t width;
744 kImageHeight, // uint32_t height;
745 1u // uint32_t layers;
746 };
747
748 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
749 }
750
751 // Create pipeline layout for subpass 0.
752 {
753 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutParams = {
754 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
755 DE_NULL, // const void* pNext
756 0u, // VkDescriptorSetLayoutCreateFlags flags
757 0u, // uint32_t bindingCount
758 DE_NULL // const VkDescriptorSetLayoutBinding* pBindings
759 };
760 m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams);
761
762 const VkPipelineLayoutCreateInfo pipelineLayoutParams = {
763 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
764 DE_NULL, // const void* pNext;
765 0u, // VkPipelineLayoutCreateFlags flags;
766 1u, // uint32_t setLayoutCount;
767 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
768 0u, // uint32_t pushConstantRangeCount;
769 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
770 };
771
772 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
773 }
774
775 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert_shader"), 0);
776 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag_shader"), 0);
777
778 // Create pipeline.
779 {
780 const std::vector<VkViewport> viewports(1, makeViewport(m_renderSize));
781 const std::vector<VkRect2D> scissors(1, makeRect2D(m_renderSize));
782
783 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState = {
784 VK_FALSE, // VkBool32 blendEnable
785 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcColorBlendFactor
786 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor
787 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
788 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor
789 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor
790 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
791 VK_COLOR_COMPONENT_R_BIT // VkColorComponentFlags colorWriteMask
792 | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT};
793
794 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates;
795 for (size_t i = 0; i < testParams.colorUsed.size(); ++i)
796 colorBlendAttachmentStates.push_back(colorBlendAttachmentState);
797
798 const VkPipelineColorBlendStateCreateInfo colorBlendStateCreateInfo = {
799 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
800 DE_NULL, // const void* pNext
801 0u, // VkPipelineColorBlendStateCreateFlags flags
802 VK_FALSE, // VkBool32 logicOpEnable
803 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp
804 static_cast<uint32_t>(
805 colorBlendAttachmentStates.size()), // uint32_t attachmentCount
806 (colorBlendAttachmentStates.empty() ?
807 DE_NULL :
808 colorBlendAttachmentStates.data()), // const VkPipelineColorBlendAttachmentState* pAttachments
809 {0.0f, 0.0f, 0.0f, 0.0f} // float blendConstants[4]
810 };
811
812 void *pNext = DE_NULL;
813 #ifndef CTS_USES_VULKANSC
814 const std::vector<VkFormat> colorAttachmentFormats(testParams.colorUsed.size(), FORMAT_COLOR);
815 const bool hasDepth = m_testParams.depthStencilType == DEPTH_STENCIL_BOTH ||
816 m_testParams.depthStencilType == DEPTH_STENCIL_DEPTH_ONLY;
817 const bool hasStencil = m_testParams.depthStencilType == DEPTH_STENCIL_BOTH ||
818 m_testParams.depthStencilType == DEPTH_STENCIL_STENCIL_ONLY;
819 VkPipelineRenderingCreateInfoKHR renderingCreateInfo{
820 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
821 DE_NULL,
822 0u,
823 static_cast<uint32_t>(colorAttachmentFormats.size()),
824 colorAttachmentFormats.data(),
825 (hasDepth ? m_testParams.depthStencilFormat : vk::VK_FORMAT_UNDEFINED),
826 (hasStencil ? m_testParams.depthStencilFormat : vk::VK_FORMAT_UNDEFINED),
827 };
828
829 if (testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
830 pNext = &renderingCreateInfo;
831 #endif // CTS_USES_VULKANSC
832
833 m_graphicsPipeline = makeGraphicsPipeline(
834 vk, // const DeviceInterface& vk
835 vkDevice, // const VkDevice device
836 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout
837 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule
838 DE_NULL, // const VkShaderModule tessellationControlModule
839 DE_NULL, // const VkShaderModule tessellationEvalModule
840 DE_NULL, // const VkShaderModule geometryShaderModule
841 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule
842 *m_renderPass, // const VkRenderPass renderPass
843 viewports, // const std::vector<VkViewport>& viewports
844 scissors, // const std::vector<VkRect2D>& scissors
845 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
846 0u, // const uint32_t subpass
847 0u, // const uint32_t patchControlPoints
848 DE_NULL, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
849 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
850 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
851 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
852 &colorBlendStateCreateInfo, // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
853 DE_NULL, // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo
854 pNext); // const void* pNext
855 }
856
857 // Create command pool
858 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
859
860 // Create command buffer
861 if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
862 createCommandBuffer<RenderpassSubpass1>(vk, vkDevice);
863 else if (testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
864 createCommandBuffer<RenderpassSubpass2>(vk, vkDevice);
865 else
866 {
867 #ifndef CTS_USES_VULKANSC
868 createCommandBufferDynamicRendering(vk, vkDevice);
869 #endif // CTS_USES_VULKANSC
870 }
871 }
872
873 template <typename RenderpassSubpass>
createCommandBuffer(const DeviceInterface & vk,VkDevice vkDevice)874 void UnusedClearAttachmentTestInstance::createCommandBuffer(const DeviceInterface &vk, VkDevice vkDevice)
875 {
876 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
877
878 const VkClearRect clearRect = {
879 {
880 // VkRect2D rect;
881 {
882 0,
883 0,
884 }, // VkOffset2D offset;
885 {kImageWidth, kImageHeight} // VkExtent2D extent;
886 },
887 0u, // uint32_t baseArrayLayer;
888 1u // uint32_t layerCount;
889 };
890
891 std::vector<VkClearAttachment> clearAttachments;
892 for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
893 {
894 const VkClearAttachment clearAttachment = {
895 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
896 static_cast<uint32_t>(i), // uint32_t colorAttachment;
897 m_clearColor // VkClearValue clearValue;
898 };
899 clearAttachments.push_back(clearAttachment);
900 }
901
902 if (hasDepthStencil(m_testParams.depthStencilType))
903 {
904 const VkClearAttachment clearAttachment = {
905 getClearAspectMask(m_testParams.depthStencilType), // VkImageAspectFlags aspectMask;
906 0u, // uint32_t colorAttachment;
907 m_clearColorDepth // VkClearValue clearValue;
908 };
909 clearAttachments.push_back(clearAttachment);
910 }
911
912 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
913
914 VkRect2D renderArea = makeRect2D(m_renderSize);
915
916 const VkRenderPassBeginInfo renderPassBeginInfo{
917 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
918 DE_NULL, // const void* pNext;
919 *m_renderPass, // VkRenderPass renderPass;
920 *m_framebuffer, // VkFramebuffer framebuffer;
921 renderArea, // VkRect2D renderArea;
922 0u, // uint32_t clearValueCount;
923 DE_NULL // const VkClearValue* pClearValues;
924 };
925
926 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
927 RenderpassSubpass::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfo, &subpassBeginInfo);
928
929 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
930 if (!clearAttachments.empty())
931 {
932 vk.cmdClearAttachments(*m_cmdBuffer, static_cast<uint32_t>(clearAttachments.size()), clearAttachments.data(),
933 1u, &clearRect);
934 }
935
936 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
937 RenderpassSubpass::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
938
939 endCommandBuffer(vk, *m_cmdBuffer);
940 }
941
942 #ifndef CTS_USES_VULKANSC
createCommandBufferDynamicRendering(const DeviceInterface & vk,VkDevice vkDevice)943 void UnusedClearAttachmentTestInstance::createCommandBufferDynamicRendering(const DeviceInterface &vk,
944 VkDevice vkDevice)
945 {
946 const VkClearRect clearRect{
947 {
948 // VkRect2D rect;
949 {
950 0,
951 0,
952 }, // VkOffset2D offset;
953 {kImageWidth, kImageHeight} // VkExtent2D extent;
954 },
955 0u, // uint32_t baseArrayLayer;
956 1u // uint32_t layerCount;
957 };
958
959 std::vector<VkClearAttachment> clearAttachments;
960 for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
961 {
962 const VkClearAttachment clearAttachment = {
963 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask;
964 static_cast<uint32_t>(i), // uint32_t colorAttachment;
965 m_clearColor // VkClearValue clearValue;
966 };
967 clearAttachments.push_back(clearAttachment);
968 }
969
970 if (m_testParams.depthStencilUsed)
971 {
972 const VkClearAttachment clearAttachment = {
973 getClearAspectMask(m_testParams.depthStencilType), // VkImageAspectFlags aspectMask;
974 0u, // uint32_t colorAttachment;
975 m_clearColorDepth // VkClearValue clearValue;
976 };
977 clearAttachments.push_back(clearAttachment);
978 }
979
980 VkRect2D renderArea = makeRect2D(m_renderSize);
981 std::vector<VkRenderingAttachmentInfoKHR> colorAttachments;
982 for (size_t i = 0; i < m_colorAttachmentViews.size(); ++i)
983 {
984 colorAttachments.push_back({
985 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
986 DE_NULL, // const void* pNext;
987 (m_testParams.colorUsed[i]) ? *m_colorAttachmentViews[i] : 0, // VkImageView imageView;
988 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
989 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
990 DE_NULL, // VkImageView resolveImageView;
991 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
992 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
993 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
994 m_clearColor // VkClearValue clearValue;
995 });
996 }
997
998 VkRenderingAttachmentInfoKHR depthAttachment{
999 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
1000 DE_NULL, // const void* pNext;
1001 (m_testParams.depthStencilUsed) ? *m_depthAttachmentView : 0, // VkImageView imageView;
1002 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
1003 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
1004 DE_NULL, // VkImageView resolveImageView;
1005 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
1006 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
1007 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1008 m_clearColorDepth // VkClearValue clearValue;
1009 };
1010
1011 const bool hasDepth = (m_testParams.depthStencilType == DEPTH_STENCIL_BOTH ||
1012 m_testParams.depthStencilType == DEPTH_STENCIL_DEPTH_ONLY) &&
1013 m_testParams.depthStencilUsed;
1014 const bool hasStencil = (m_testParams.depthStencilType == DEPTH_STENCIL_BOTH ||
1015 m_testParams.depthStencilType == DEPTH_STENCIL_STENCIL_ONLY) &&
1016 m_testParams.depthStencilUsed;
1017
1018 std::vector<VkFormat> colorAttachmentFormats(m_testParams.colorUsed.size(), VK_FORMAT_UNDEFINED);
1019 for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
1020 if (m_testParams.colorUsed[i])
1021 colorAttachmentFormats[i] = FORMAT_COLOR;
1022
1023 VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo{
1024 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
1025 DE_NULL, // const void* pNext;
1026 0u, // VkRenderingFlagsKHR flags;
1027 0u, // uint32_t viewMask;
1028 static_cast<uint32_t>(colorAttachmentFormats.size()), // uint32_t colorAttachmentCount;
1029 colorAttachmentFormats.data(), // const VkFormat* pColorAttachmentFormats;
1030 hasDepth ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat;
1031 hasStencil ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat;
1032 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
1033 };
1034
1035 const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
1036 VkCommandBufferBeginInfo commandBufBeginParams{
1037 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
1038 DE_NULL, // const void* pNext;
1039 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
1040 &bufferInheritanceInfo};
1041
1042 VkRenderingInfoKHR renderingInfo{
1043 VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
1044 DE_NULL,
1045 0u, // VkRenderingFlagsKHR flags;
1046 renderArea, // VkRect2D renderArea;
1047 1u, // uint32_t layerCount;
1048 0u, // uint32_t viewMask;
1049 static_cast<uint32_t>(colorAttachments.size()), // uint32_t colorAttachmentCount;
1050 colorAttachments.empty() ? DE_NULL :
1051 colorAttachments.data(), // const VkRenderingAttachmentInfoKHR* pColorAttachments;
1052 hasDepth ? &depthAttachment : DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
1053 hasStencil ? &depthAttachment : DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
1054 };
1055
1056 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1057
1058 if (m_testParams.groupParams->useSecondaryCmdBuffer)
1059 {
1060 m_secCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
1061
1062 // record secondary command buffer
1063 if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1064 {
1065 inheritanceRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
1066 vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams);
1067 vk.cmdBeginRendering(*m_secCmdBuffer, &renderingInfo);
1068 }
1069 else
1070 {
1071 commandBufBeginParams.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
1072 vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams);
1073 }
1074
1075 vk.cmdBindPipeline(*m_secCmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1076 if (!clearAttachments.empty())
1077 {
1078 vk.cmdClearAttachments(*m_secCmdBuffer, static_cast<uint32_t>(clearAttachments.size()),
1079 clearAttachments.data(), 1u, &clearRect);
1080 }
1081
1082 if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1083 vk.cmdEndRendering(*m_secCmdBuffer);
1084 endCommandBuffer(vk, *m_secCmdBuffer);
1085
1086 // record primary command buffer
1087 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1088 if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1089 {
1090 renderingInfo.flags = vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
1091 vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
1092 }
1093 vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
1094 if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1095 vk.cmdEndRendering(*m_cmdBuffer);
1096 endCommandBuffer(vk, *m_cmdBuffer);
1097 }
1098 else
1099 {
1100 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1101 vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
1102
1103 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
1104 if (!clearAttachments.empty())
1105 {
1106 vk.cmdClearAttachments(*m_cmdBuffer, static_cast<uint32_t>(clearAttachments.size()),
1107 clearAttachments.data(), 1u, &clearRect);
1108 }
1109
1110 vk.cmdEndRendering(*m_cmdBuffer);
1111 endCommandBuffer(vk, *m_cmdBuffer);
1112 }
1113 }
1114 #endif // CTS_USES_VULKANSC
1115
iterate(void)1116 tcu::TestStatus UnusedClearAttachmentTestInstance::iterate(void)
1117 {
1118 const DeviceInterface &vk = m_context.getDeviceInterface();
1119 const VkDevice vkDevice = m_context.getDevice();
1120 const VkQueue queue = m_context.getUniversalQueue();
1121 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
1122 SimpleAllocator allocator(
1123 vk, vkDevice,
1124 getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1125
1126 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1127
1128 // Read result images.
1129 std::vector<de::MovePtr<tcu::TextureLevel>> imagePixels;
1130 for (size_t i = 0; i < m_testParams.colorUsed.size(); ++i)
1131 imagePixels.emplace_back(pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator,
1132 *m_colorImages[i], FORMAT_COLOR, m_renderSize)
1133 .release());
1134
1135 // Verify pixel colors match.
1136 for (size_t i = 0; i < imagePixels.size(); ++i)
1137 {
1138 const tcu::ConstPixelBufferAccess &imageAccess = imagePixels[i]->getAccess();
1139 const float *refColor = (m_testParams.colorUsed[i] ? m_clearColor.color.float32 : m_initialColor.color.float32);
1140
1141 #ifdef CTS_USES_VULKANSC
1142 if (m_context.getTestContext().getCommandLine().isSubProcess())
1143 #endif // CTS_USES_VULKANSC
1144 {
1145 for (int y = 0; y < imageAccess.getHeight(); ++y)
1146 for (int x = 0; x < imageAccess.getWidth(); ++x)
1147 {
1148 const tcu::Vec4 color = imageAccess.getPixel(x, y);
1149
1150 for (uint32_t cpnt = 0; cpnt < 4; ++cpnt)
1151 if (de::abs(color[cpnt] - refColor[cpnt]) > 0.01f)
1152 {
1153 std::ostringstream msg;
1154
1155 msg << "Attachment " << i << " with mismatched pixel (" << x << ", " << y
1156 << "): expecting pixel value [";
1157 for (uint32_t j = 0; j < 4; ++j)
1158 msg << ((j == 0) ? "" : ", ") << refColor[j];
1159 msg << "] and found [";
1160 for (uint32_t j = 0; j < 4; ++j)
1161 msg << ((j == 0) ? "" : ", ") << color[j];
1162 msg << "]";
1163
1164 return tcu::TestStatus::fail(msg.str());
1165 }
1166 }
1167 }
1168 }
1169
1170 if (hasDepthStencil(m_testParams.depthStencilType))
1171 {
1172 const bool depthOnly = isDepthOnly(m_testParams.depthStencilType);
1173 const bool stencilOnly = isStencilOnly(m_testParams.depthStencilType);
1174
1175 if (!stencilOnly)
1176 {
1177 de::MovePtr<tcu::TextureLevel> depthPixels =
1178 pipeline::readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage,
1179 m_testParams.depthStencilFormat, m_renderSize);
1180 const tcu::ConstPixelBufferAccess &depthAccess = depthPixels->getAccess();
1181 const float refDepth = (m_testParams.depthStencilUsed ? m_clearColorDepth.depthStencil.depth :
1182 m_initialColorDepth.depthStencil.depth);
1183
1184 #ifdef CTS_USES_VULKANSC
1185 if (m_context.getTestContext().getCommandLine().isSubProcess())
1186 #endif // CTS_USES_VULKANSC
1187 {
1188 for (int y = 0; y < depthAccess.getHeight(); ++y)
1189 for (int x = 0; x < depthAccess.getWidth(); ++x)
1190 {
1191 const float value = depthAccess.getPixDepth(x, y);
1192 if (de::abs(value - refDepth) > 0.001f)
1193 {
1194 std::ostringstream msg;
1195
1196 msg << "Depth/stencil attachment with mismatched depth value at pixel (" << x << ", " << y
1197 << "): expected value " << refDepth << " and found " << value;
1198 return tcu::TestStatus::fail(msg.str());
1199 }
1200 }
1201 }
1202 }
1203
1204 if (!depthOnly)
1205 {
1206 // Note read*Attachment leaves the attachment in the VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL layout, so the current layout
1207 // depends on if we have previously read the depth aspect or not.
1208 const VkImageLayout currentLayout =
1209 (stencilOnly ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1210 de::MovePtr<tcu::TextureLevel> stencilPixels =
1211 pipeline::readStencilAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *m_depthImage,
1212 m_testParams.depthStencilFormat, m_renderSize, currentLayout);
1213 const tcu::ConstPixelBufferAccess &stencilAccess = stencilPixels->getAccess();
1214 const uint32_t refStencil = (m_testParams.depthStencilUsed ? m_clearColorDepth.depthStencil.stencil :
1215 m_initialColorDepth.depthStencil.stencil);
1216
1217 #ifdef CTS_USES_VULKANSC
1218 if (m_context.getTestContext().getCommandLine().isSubProcess())
1219 #endif // CTS_USES_VULKANSC
1220 {
1221 for (int y = 0; y < stencilAccess.getHeight(); ++y)
1222 for (int x = 0; x < stencilAccess.getWidth(); ++x)
1223 {
1224 const int value = stencilAccess.getPixStencil(x, y);
1225 if (value < 0 || static_cast<uint32_t>(value) != refStencil)
1226 {
1227 std::ostringstream msg;
1228
1229 msg << "Depth/stencil attachment with mismatched stencil value at pixel (" << x << ", " << y
1230 << "): expected value " << refStencil << " and found " << value;
1231 return tcu::TestStatus::fail(msg.str());
1232 }
1233 }
1234 }
1235 }
1236 }
1237
1238 return tcu::TestStatus::pass("Pass");
1239 }
1240
1241 using CallbackFunction = std::function<void(const std::vector<bool> &)>;
1242
runCallbackOnCombination(std::vector<bool> & array,size_t current_index,CallbackFunction callback)1243 void runCallbackOnCombination(std::vector<bool> &array, size_t current_index, CallbackFunction callback)
1244 {
1245 DE_ASSERT(current_index < array.size());
1246 for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(DE_BOOL_VALUES); ++i)
1247 {
1248 array[current_index] = DE_BOOL_VALUES[i];
1249 if (current_index == array.size() - 1)
1250 callback(array);
1251 else
1252 runCallbackOnCombination(array, current_index + 1, callback);
1253 }
1254 }
1255
runCallbackOnCombination(std::vector<bool> & array,CallbackFunction callback)1256 void runCallbackOnCombination(std::vector<bool> &array, CallbackFunction callback)
1257 {
1258 runCallbackOnCombination(array, 0, callback);
1259 }
1260
getUsed(bool value)1261 std::string getUsed(bool value)
1262 {
1263 return (value ? "used" : "unused");
1264 }
1265
getCombName(const std::vector<bool> & array)1266 std::string getCombName(const std::vector<bool> &array)
1267 {
1268 std::ostringstream name;
1269 for (size_t i = 0; i < array.size(); ++i)
1270 name << ((i == 0) ? "" : "_") << "color" << getUsed(array[i]);
1271 return name.str();
1272 }
1273
1274 } // namespace
1275
createRenderPassUnusedClearAttachmentTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)1276 tcu::TestCaseGroup *createRenderPassUnusedClearAttachmentTests(tcu::TestContext &testCtx,
1277 const SharedGroupParams groupParams)
1278 {
1279 // Unused attachments with vkCmdClearAttachments
1280 de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "unused_clear_attachments"));
1281
1282 for (int depthStencilType = 0; depthStencilType < DEPTH_STENCIL_MAX_ENUM; ++depthStencilType)
1283 {
1284 const DepthStencilType dsType = static_cast<DepthStencilType>(depthStencilType);
1285 const auto dsFormats = getFormats(dsType);
1286
1287 for (const auto dsFormat : dsFormats)
1288 {
1289 for (size_t i = 0; i < DE_LENGTH_OF_ARRAY(DE_BOOL_VALUES); ++i)
1290 {
1291 const bool depthStencilUse = DE_BOOL_VALUES[i];
1292
1293 if (groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING && dsType != DEPTH_STENCIL_NONE &&
1294 !depthStencilUse && groupParams->useSecondaryCmdBuffer &&
1295 !groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
1296 {
1297 // In dynamic rendering, we cannot have D/S format set for attachment in secondary command buffer,
1298 // while having no attachment in rendering info in primary command buffer.
1299 //
1300 // Spec:
1301 // If vkCmdExecuteCommands is being called within a render pass instance begun with vkCmdBeginRendering and
1302 // the VkRenderingInfo::pDepthAttachment->imageView parameter to vkCmdBeginRendering was VK_NULL_HANDLE,
1303 // the value of the depthAttachmentFormat member of the VkCommandBufferInheritanceRenderingInfo structure included
1304 // in the pNext chain of VkCommandBufferBeginInfo::pInheritanceInfo used to begin recording each element of
1305 // pCommandBuffers must be VK_FORMAT_UNDEFINED
1306 continue;
1307 }
1308
1309 const std::string dsCase = depthStencilTypeName(dsType, dsFormat);
1310 std::vector<TestParams> testTypes;
1311
1312 if (hasDepthStencil(dsType))
1313 testTypes.emplace_back(0, dsType, depthStencilUse, dsFormat, groupParams); // No color attachments.
1314 testTypes.emplace_back(1, dsType, depthStencilUse, dsFormat, groupParams); // Single color attachment.
1315 testTypes.emplace_back(COLOR_ATTACHMENTS_NUMBER, dsType, depthStencilUse, dsFormat,
1316 groupParams); // Multiple color attachments.
1317
1318 for (auto ¶ms : testTypes)
1319 {
1320 if (!params.colorUsed.empty())
1321 {
1322 runCallbackOnCombination(params.colorUsed,
1323 [&](const std::vector<bool> &array)
1324 {
1325 std::string name = getCombName(array) + "_" + dsCase;
1326 if (hasDepthStencil(dsType))
1327 name += std::string("_") + getUsed(depthStencilUse);
1328 testGroup->addChild(
1329 new UnusedClearAttachmentTest(testCtx, name, params));
1330 });
1331 }
1332 else
1333 {
1334 std::string name = dsCase + "_" + getUsed(depthStencilUse);
1335 testGroup->addChild(new UnusedClearAttachmentTest(testCtx, name, params));
1336 }
1337 }
1338
1339 if (!hasDepthStencil(dsType))
1340 break;
1341 }
1342 }
1343 }
1344
1345 return testGroup.release();
1346 }
1347
1348 } // namespace renderpass
1349 } // namespace vkt
1350