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