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