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