1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * -----------------------------
4 *
5 * Copyright (c) 2020 Google Inc.
6 * Copyright (c) 2020 The Khronos Group Inc.
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 for multiple color or depth clears within a render pass
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktDrawMultipleClearsWithinRenderPass.hpp"
26
27 #include "vktTestGroupUtil.hpp"
28 #include "vktTestCaseUtil.hpp"
29 #include "vktDrawCreateInfoUtil.hpp"
30 #include "vktDrawBufferObjectUtil.hpp"
31 #include "vktDrawImageObjectUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkCmdUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkQueryUtil.hpp"
39 #include "tcuTextureUtil.hpp"
40 #include "tcuCommandLine.hpp"
41 #include "vktDrawTestCaseUtil.hpp"
42
43 #include "deStringUtil.hpp"
44
45 #include <cmath>
46 #include <vector>
47 #include <string>
48 #include <sstream>
49
50 namespace vkt
51 {
52 namespace Draw
53 {
54 namespace
55 {
56 using namespace vk;
57 using de::SharedPtr;
58 using std::abs;
59 using std::ostringstream;
60 using std::string;
61 using std::vector;
62 using tcu::Vec4;
63
64 const uint32_t WIDTH = 400;
65 const uint32_t HEIGHT = 300;
66
67 enum struct Topology
68 {
69 TRIANGLE_STRIP = 0,
70 TRIANGLES,
71 TRIANGLE
72 };
73
74 const Topology topologiesToTest[] = {Topology::TRIANGLE_STRIP, Topology::TRIANGLES, Topology::TRIANGLE};
75
76 struct FormatPair
77 {
78 VkFormat colorFormat;
79 VkFormat depthFormat;
80 };
81
82 const FormatPair formatsToTest[] = {
83 {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_UNDEFINED}, {VK_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_UNDEFINED},
84 {VK_FORMAT_UNDEFINED, VK_FORMAT_D32_SFLOAT}, {VK_FORMAT_UNDEFINED, VK_FORMAT_D16_UNORM},
85 {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_D32_SFLOAT}, {VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_D16_UNORM},
86 {VK_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_D32_SFLOAT}, {VK_FORMAT_R8G8B8A8_SNORM, VK_FORMAT_D16_UNORM},
87 };
88
89 const Vec4 verticesTriangleStrip[] = {
90 Vec4(-1.0f, -1.0f, 0.0f, 1.0f), // 0 -- 2
91 Vec4(-1.0f, 1.0f, 0.0f, 1.0f), // | / |
92 Vec4(1.0f, -1.0f, 0.0f, 1.0f), // | / |
93 Vec4(1.0f, 1.0f, 0.0f, 1.0f) // 1 -- 3
94 };
95 const Vec4 verticesTriangles[] = {
96 Vec4(-1.0f, -1.0f, 0.0f, 1.0f), // 0 - 1
97 Vec4(-1.0f, 1.0f, 0.0f, 1.0f), // | /
98 Vec4(1.0f, -1.0f, 0.0f, 1.0f), // 2
99 Vec4(1.0f, -1.0f, 0.0f, 1.0f), // 4
100 Vec4(-1.0f, 1.0f, 0.0f, 1.0f), // / |
101 Vec4(1.0f, 1.0f, 0.0f, 1.0f) // 3 - 5
102 };
103 const Vec4 verticesBigTriangle[] = {
104 Vec4(-1.0f, -1.0f, 0.0f, 1.0f), // 0 - 2
105 Vec4(-1.0f, 3.0f, 0.0f, 1.0f), // | /
106 Vec4(3.0f, -1.0f, 0.0f, 1.0f), // 1
107 };
108
109 const uint32_t TOPOLOGY_MAX_VERTICES_COUNT = 6;
110 const uint32_t TEST_MAX_STEPS_COUNT = 3;
111
112 struct Vertices
113 {
114 const char *testNameSuffix;
115 VkPrimitiveTopology topology;
116 uint32_t verticesCount;
117 const Vec4 *vertices;
118 };
119
120 const Vertices verticesByTopology[] = {
121 {"_triangle_strip", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP, DE_LENGTH_OF_ARRAY(verticesTriangleStrip),
122 verticesTriangleStrip},
123 {"_triangles", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, DE_LENGTH_OF_ARRAY(verticesTriangles), verticesTriangles},
124 {"_big_triangle", VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, DE_LENGTH_OF_ARRAY(verticesBigTriangle),
125 verticesBigTriangle}};
126
127 enum struct ClearOp
128 {
129 LOAD = 0,
130 DRAW,
131 CLEAR
132 };
133
134 struct ClearStep
135 {
136 ClearOp clearOp;
137 Vec4 color;
138 float depth;
139 };
140
141 struct TestParams
142 {
143 VkFormat colorFormat;
144 VkFormat depthFormat;
145 Topology topology;
146 Vec4 expectedColor;
147 float colorEpsilon;
148 float expectedDepth;
149 float depthEpsilon;
150 uint32_t repeatCount;
151 bool enableBlend;
152 const SharedGroupParams groupParams;
153 vector<ClearStep> steps;
154 };
155
156 class MultipleClearsTest : public TestInstance
157 {
158 public:
159 MultipleClearsTest(Context &context, const TestParams ¶ms);
160 virtual tcu::TestStatus iterate(void);
161
162 private:
163 void preRenderCommands(VkCommandBuffer cmdBuffer) const;
164 void beginLegacyRender(VkCommandBuffer cmdBuffer) const;
165 void drawCommands(VkCommandBuffer cmdBuffer) const;
166
167 #ifndef CTS_USES_VULKANSC
168 void beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags = 0u) const;
169 void beginDynamicRender(VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags = 0u) const;
170 #endif // CTS_USES_VULKANSC
171
172 SharedPtr<Image> m_colorTargetImage;
173 SharedPtr<Image> m_depthTargetImage;
174 Move<VkImageView> m_colorTargetView;
175 Move<VkImageView> m_depthTargetView;
176 SharedPtr<Buffer> m_vertexBuffer;
177 Move<VkRenderPass> m_renderPass;
178 Move<VkFramebuffer> m_framebuffer;
179 Move<VkPipelineLayout> m_pipelineLayout;
180 Move<VkPipeline> m_pipeline;
181
182 const TestParams m_params;
183 Vec4 m_vertices[TOPOLOGY_MAX_VERTICES_COUNT * TEST_MAX_STEPS_COUNT];
184 };
185
MultipleClearsTest(Context & context,const TestParams & params)186 MultipleClearsTest::MultipleClearsTest(Context &context, const TestParams ¶ms)
187 : TestInstance(context)
188 , m_params(params)
189 {
190 const DeviceInterface &vk = m_context.getDeviceInterface();
191 const VkDevice device = m_context.getDevice();
192 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
193 const bool hasColor = m_params.colorFormat != VK_FORMAT_UNDEFINED;
194 const bool hasDepth = m_params.depthFormat != VK_FORMAT_UNDEFINED;
195
196 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
197 // Vertex data
198 const auto &vertexData = verticesByTopology[(size_t)m_params.topology];
199 {
200 DE_ASSERT(vertexData.verticesCount <= TOPOLOGY_MAX_VERTICES_COUNT);
201 const size_t verticesCount = vertexData.verticesCount;
202 const VkDeviceSize dataSize = verticesCount * sizeof(Vec4);
203 const VkDeviceSize totalDataSize = m_params.steps.size() * dataSize;
204 DE_ASSERT(totalDataSize <= sizeof(m_vertices));
205
206 for (size_t i = 0; i < m_params.steps.size(); ++i)
207 {
208 const size_t start = i * verticesCount;
209 deMemcpy(&m_vertices[start], vertexData.vertices, static_cast<size_t>(dataSize));
210 for (size_t j = 0; j < verticesCount; ++j)
211 m_vertices[start + j][2] = m_params.steps[i].depth;
212 }
213 m_vertexBuffer =
214 Buffer::createAndAlloc(vk, device, BufferCreateInfo(totalDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
215 m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
216 deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), m_vertices, static_cast<std::size_t>(totalDataSize));
217 flushMappedMemoryRange(vk, device, m_vertexBuffer->getBoundMemory().getMemory(),
218 m_vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
219 }
220
221 if (hasColor)
222 {
223 const VkImageUsageFlags targetImageUsageFlags =
224 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
225 const ImageCreateInfo targetImageCreateInfo(VK_IMAGE_TYPE_2D, m_params.colorFormat, {WIDTH, HEIGHT, 1u}, 1u, 1u,
226 VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
227 targetImageUsageFlags);
228 m_colorTargetImage =
229 Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), queueFamilyIndex);
230 const ImageViewCreateInfo colorTargetViewInfo(m_colorTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D,
231 m_params.colorFormat);
232 m_colorTargetView = createImageView(vk, device, &colorTargetViewInfo);
233 }
234
235 if (hasDepth)
236 {
237 const VkImageUsageFlags depthImageUsageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
238 VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
239 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
240 const ImageCreateInfo depthImageCreateInfo(VK_IMAGE_TYPE_2D, m_params.depthFormat, {WIDTH, HEIGHT, 1u}, 1u, 1u,
241 VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL,
242 depthImageUsageFlags);
243 m_depthTargetImage =
244 Image::createAndAlloc(vk, device, depthImageCreateInfo, m_context.getDefaultAllocator(), queueFamilyIndex);
245 const ImageViewCreateInfo depthTargetViewInfo(m_depthTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D,
246 m_params.depthFormat);
247 m_depthTargetView = createImageView(vk, device, &depthTargetViewInfo);
248 }
249
250 // Render pass
251 if (!m_params.groupParams->useDynamicRendering)
252 {
253 RenderPassCreateInfo renderPassCreateInfo;
254 if (hasColor)
255 {
256 renderPassCreateInfo.addAttachment(
257 AttachmentDescription(m_params.colorFormat, // format
258 VK_SAMPLE_COUNT_1_BIT, // samples
259 VK_ATTACHMENT_LOAD_OP_LOAD, // loadOp
260 VK_ATTACHMENT_STORE_OP_STORE, // storeOp
261 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
262 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
263 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // initialLayout
264 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); // finalLayout
265 }
266 if (hasDepth)
267 {
268 renderPassCreateInfo.addAttachment(
269 AttachmentDescription(m_params.depthFormat, // format
270 VK_SAMPLE_COUNT_1_BIT, // samples
271 VK_ATTACHMENT_LOAD_OP_LOAD, // loadOp
272 VK_ATTACHMENT_STORE_OP_STORE, // storeOp
273 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
274 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
275 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // initialLayout
276 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); // finalLayout
277 }
278 const VkAttachmentReference colorAttachmentReference =
279 hasColor ? makeAttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) : AttachmentReference();
280 const VkAttachmentReference depthAttachmentReference =
281 hasDepth ? makeAttachmentReference(hasColor ? 1u : 0u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) :
282 AttachmentReference();
283 renderPassCreateInfo.addSubpass(
284 SubpassDescription(VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
285 (VkSubpassDescriptionFlags)0, // flags
286 0u, // inputAttachmentCount
287 DE_NULL, // inputAttachments
288 hasColor ? 1 : 0, // colorAttachmentCount
289 hasColor ? &colorAttachmentReference : DE_NULL, // colorAttachments
290 DE_NULL, // resolveAttachments
291 depthAttachmentReference, // depthStencilAttachment
292 0u, // preserveAttachmentCount
293 DE_NULL)); // preserveAttachments
294 m_renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
295
296 std::vector<VkImageView> attachments;
297 if (hasColor)
298 attachments.push_back(*m_colorTargetView);
299 if (hasDepth)
300 attachments.push_back(*m_depthTargetView);
301 const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
302 m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
303 }
304
305 // Vertex input
306 const VkVertexInputBindingDescription vertexInputBindingDescription = {
307 0u, // uint32_t binding;
308 sizeof(Vec4), // uint32_t stride;
309 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
310 };
311
312 const VkVertexInputAttributeDescription vertexInputAttributeDescription = {
313 0u, // uint32_t location;
314 0u, // uint32_t binding;
315 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
316 0u // uint32_t offset;
317 };
318
319 const PipelineCreateInfo::VertexInputState vertexInputState =
320 PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription, 1, &vertexInputAttributeDescription);
321
322 // Graphics pipeline
323 const Unique<VkShaderModule> vertexModule(
324 createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
325 const Unique<VkShaderModule> fragmentModule(
326 createShaderModule(vk, device, m_context.getBinaryCollection().get(hasColor ? "frag" : "frag_depthonly"), 0));
327
328 const VkPushConstantRange pcRange =
329 vk::VkPushConstantRange{VkShaderStageFlagBits::VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(ClearStep::color)};
330 const PipelineLayoutCreateInfo pipelineLayoutCreateInfo(0u, DE_NULL, 1u, &pcRange);
331 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
332
333 const VkRect2D scissor = makeRect2D(WIDTH, HEIGHT);
334 const VkViewport viewport = makeViewport(WIDTH, HEIGHT);
335
336 const auto vkCbAttachmentState = makePipelineColorBlendAttachmentState(
337 m_params.enableBlend ? VK_TRUE : VK_FALSE, // VkBool32 blendEnable
338 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor
339 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor
340 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
341 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor
342 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor
343 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
344 VK_COLOR_COMPONENT_R_BIT | // VkColorComponentFlags colorWriteMask
345 VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT);
346 PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
347 pipelineCreateInfo.addShader(
348 PipelineCreateInfo::PipelineShaderStage(*vertexModule, "main", VK_SHADER_STAGE_VERTEX_BIT));
349 pipelineCreateInfo.addShader(
350 PipelineCreateInfo::PipelineShaderStage(*fragmentModule, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
351 pipelineCreateInfo.addState(PipelineCreateInfo::VertexInputState(vertexInputState));
352 pipelineCreateInfo.addState(PipelineCreateInfo::InputAssemblerState(vertexData.topology));
353 pipelineCreateInfo.addState(PipelineCreateInfo::ColorBlendState(1, &vkCbAttachmentState));
354 pipelineCreateInfo.addState(
355 PipelineCreateInfo::ViewportState(1, std::vector<VkViewport>(1, viewport), std::vector<VkRect2D>(1, scissor)));
356 pipelineCreateInfo.addState(
357 PipelineCreateInfo::DepthStencilState(hasDepth, hasDepth, VK_COMPARE_OP_ALWAYS, VK_FALSE, VK_FALSE));
358 pipelineCreateInfo.addState(PipelineCreateInfo::RasterizerState());
359 pipelineCreateInfo.addState(PipelineCreateInfo::MultiSampleState());
360
361 #ifndef CTS_USES_VULKANSC
362 vk::VkPipelineRenderingCreateInfoKHR renderingCreateInfo{VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
363 DE_NULL,
364 0u,
365 hasColor,
366 (hasColor ? &m_params.colorFormat : DE_NULL),
367 m_params.depthFormat,
368 VK_FORMAT_UNDEFINED};
369
370 if (m_params.groupParams->useDynamicRendering)
371 pipelineCreateInfo.pNext = &renderingCreateInfo;
372 #endif // CTS_USES_VULKANSC
373
374 m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
375 }
376
preRenderCommands(VkCommandBuffer cmdBuffer) const377 void MultipleClearsTest::preRenderCommands(VkCommandBuffer cmdBuffer) const
378 {
379 const DeviceInterface &vk = m_context.getDeviceInterface();
380 if (m_params.colorFormat)
381 initialTransitionColor2DImage(vk, cmdBuffer, m_colorTargetImage->object(),
382 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
383 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
384 if (m_params.depthFormat)
385 initialTransitionDepth2DImage(
386 vk, cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
387 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
388 }
389
beginLegacyRender(VkCommandBuffer cmdBuffer) const390 void MultipleClearsTest::beginLegacyRender(VkCommandBuffer cmdBuffer) const
391 {
392 const DeviceInterface &vk = m_context.getDeviceInterface();
393 const VkRect2D renderArea = makeRect2D(0, 0, WIDTH, HEIGHT);
394
395 if (!m_params.steps.empty() && m_params.steps[0].clearOp == ClearOp::LOAD)
396 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, m_params.steps[0].color,
397 m_params.steps[0].depth, 0);
398 else
399 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea);
400 }
401
drawCommands(vk::VkCommandBuffer cmdBuffer) const402 void MultipleClearsTest::drawCommands(vk::VkCommandBuffer cmdBuffer) const
403 {
404 const DeviceInterface &vk = m_context.getDeviceInterface();
405
406 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
407 {
408 const VkDeviceSize offset = 0;
409 const VkBuffer buffer = m_vertexBuffer->object();
410 vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &buffer, &offset);
411 }
412
413 for (uint32_t i = 0; i < m_params.repeatCount; ++i)
414 for (size_t stepIndex = 0; stepIndex < m_params.steps.size(); ++stepIndex)
415 {
416 const auto &step = m_params.steps[stepIndex];
417
418 // ClearOp::LOAD only supported for first step
419 DE_ASSERT(stepIndex == 0 || step.clearOp != ClearOp::LOAD);
420
421 const Vec4 &color = step.color;
422 const float depth = step.depth;
423
424 switch (step.clearOp)
425 {
426 case ClearOp::LOAD:
427 break;
428 case ClearOp::DRAW:
429 {
430 const auto &vertexData = verticesByTopology[(size_t)m_params.topology];
431 const uint32_t verticesCount = vertexData.verticesCount;
432 vk.cmdPushConstants(cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(color),
433 color.getPtr());
434 vk.cmdDraw(cmdBuffer, verticesCount, 1, static_cast<uint32_t>(verticesCount * stepIndex), 0);
435 }
436 break;
437 case ClearOp::CLEAR:
438 {
439 vector<VkClearAttachment> clearAttachments;
440 if (m_params.colorFormat != VK_FORMAT_UNDEFINED)
441 {
442 const VkClearAttachment clearAttachment{
443 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
444 static_cast<uint32_t>(clearAttachments.size()), // uint32_t colorAttachment
445 makeClearValueColor(color) // VkClearValue clearValue
446 };
447 clearAttachments.push_back(clearAttachment);
448 }
449 if (m_params.depthFormat != VK_FORMAT_UNDEFINED)
450 {
451 const VkClearAttachment clearAttachment{
452 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask
453 static_cast<uint32_t>(clearAttachments.size()), // uint32_t colorAttachment
454 makeClearValueDepthStencil(depth, 0) // VkClearValue clearValue
455 };
456 clearAttachments.push_back(clearAttachment);
457 }
458 const VkClearRect clearRect{
459 makeRect2D(WIDTH, HEIGHT), // VkRect2D rect
460 0, // uint32_t baseArrayLayer
461 1 // uint32_t layerCount
462 };
463 vk.cmdClearAttachments(cmdBuffer, static_cast<uint32_t>(clearAttachments.size()),
464 clearAttachments.data(), 1, &clearRect);
465 }
466 break;
467 default:
468 break;
469 }
470 }
471 }
472
473 #ifndef CTS_USES_VULKANSC
beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer,VkRenderingFlagsKHR renderingFlags) const474 void MultipleClearsTest::beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags) const
475 {
476 VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo{
477 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
478 DE_NULL, // const void* pNext;
479 renderingFlags, // VkRenderingFlagsKHR flags;
480 0u, // uint32_t viewMask;
481 (m_params.colorFormat != VK_FORMAT_UNDEFINED), // uint32_t colorAttachmentCount;
482 &m_params.colorFormat, // const VkFormat* pColorAttachmentFormats;
483 m_params.depthFormat, // VkFormat depthAttachmentFormat;
484 VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat;
485 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
486 };
487
488 const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
489
490 VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
491 if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
492 usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
493
494 const VkCommandBufferBeginInfo commandBufBeginParams{
495 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
496 DE_NULL, // const void* pNext;
497 usageFlags, // VkCommandBufferUsageFlags flags;
498 &bufferInheritanceInfo};
499
500 const DeviceInterface &vk = m_context.getDeviceInterface();
501 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &commandBufBeginParams));
502 }
503
beginDynamicRender(VkCommandBuffer cmdBuffer,VkRenderingFlagsKHR renderingFlags) const504 void MultipleClearsTest::beginDynamicRender(VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags) const
505 {
506 const DeviceInterface &vk = m_context.getDeviceInterface();
507 const VkRect2D renderArea = makeRect2D(0, 0, WIDTH, HEIGHT);
508
509 VkClearValue clearColorValue = makeClearValueColor(tcu::Vec4(0.0f));
510 VkClearValue clearDepthValue = makeClearValueDepthStencil(0.0f, 0u);
511 if (!m_params.steps.empty() && m_params.steps[0].clearOp == ClearOp::LOAD)
512 {
513 clearColorValue = makeClearValueColor(m_params.steps[0].color);
514 clearDepthValue = makeClearValueDepthStencil(m_params.steps[0].depth, 0u);
515 }
516
517 vk::VkRenderingAttachmentInfoKHR colorAttachment{
518 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
519 DE_NULL, // const void* pNext;
520 *m_colorTargetView, // VkImageView imageView;
521 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
522 vk::VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
523 DE_NULL, // VkImageView resolveImageView;
524 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
525 vk::VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
526 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
527 clearColorValue // VkClearValue clearValue;
528 };
529
530 vk::VkRenderingAttachmentInfoKHR depthAttachment{
531 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
532 DE_NULL, // const void* pNext;
533 *m_depthTargetView, // VkImageView imageView;
534 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
535 vk::VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
536 DE_NULL, // VkImageView resolveImageView;
537 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
538 vk::VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
539 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
540 clearDepthValue // VkClearValue clearValue;
541 };
542
543 const bool hasColor = m_params.colorFormat != VK_FORMAT_UNDEFINED;
544 const bool hasDepth = m_params.depthFormat != VK_FORMAT_UNDEFINED;
545
546 vk::VkRenderingInfoKHR renderingInfo{
547 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
548 DE_NULL,
549 renderingFlags, // VkRenderingFlagsKHR flags;
550 renderArea, // VkRect2D renderArea;
551 1u, // uint32_t layerCount;
552 0u, // uint32_t viewMask;
553 hasColor, // uint32_t colorAttachmentCount;
554 (hasColor ? &colorAttachment : DE_NULL), // const VkRenderingAttachmentInfoKHR* pColorAttachments;
555 (hasDepth ? &depthAttachment : DE_NULL), // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
556 DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
557 };
558
559 vk.cmdBeginRendering(cmdBuffer, &renderingInfo);
560 }
561 #endif // CTS_USES_VULKANSC
562
iterate(void)563 tcu::TestStatus MultipleClearsTest::iterate(void)
564 {
565 const DeviceInterface &vk = m_context.getDeviceInterface();
566 const VkDevice device = m_context.getDevice();
567 const VkQueue queue = m_context.getUniversalQueue();
568 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
569
570 const CmdPoolCreateInfo cmdPoolCreateInfo(queueFamilyIndex);
571 const Unique<VkCommandPool> cmdPool(createCommandPool(vk, device, &cmdPoolCreateInfo));
572 const Unique<VkCommandBuffer> cmdBuffer(
573 allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
574 Move<VkCommandBuffer> secCmdBuffer;
575
576 const bool hasColor = m_params.colorFormat != VK_FORMAT_UNDEFINED;
577 const bool hasDepth = m_params.depthFormat != VK_FORMAT_UNDEFINED;
578
579 #ifndef CTS_USES_VULKANSC
580 if (m_params.groupParams->useSecondaryCmdBuffer)
581 {
582 secCmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
583
584 // record secondary command buffer
585 if (m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
586 {
587 beginSecondaryCmdBuffer(*secCmdBuffer, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
588 beginDynamicRender(*secCmdBuffer);
589 }
590 else
591 beginSecondaryCmdBuffer(*secCmdBuffer);
592
593 drawCommands(*secCmdBuffer);
594
595 if (m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
596 endRendering(vk, *secCmdBuffer);
597
598 endCommandBuffer(vk, *secCmdBuffer);
599
600 // record primary command buffer
601 beginCommandBuffer(vk, *cmdBuffer, 0u);
602 preRenderCommands(*cmdBuffer);
603
604 if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
605 beginDynamicRender(*cmdBuffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
606
607 vk.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer);
608
609 if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
610 endRendering(vk, *cmdBuffer);
611 }
612 else if (m_params.groupParams->useDynamicRendering)
613 {
614 beginCommandBuffer(vk, *cmdBuffer);
615 preRenderCommands(*cmdBuffer);
616 beginDynamicRender(*cmdBuffer);
617 drawCommands(*cmdBuffer);
618 endRendering(vk, *cmdBuffer);
619 }
620 #endif // CTS_USES_VULKANSC
621
622 if (!m_params.groupParams->useDynamicRendering)
623 {
624 beginCommandBuffer(vk, *cmdBuffer);
625 preRenderCommands(*cmdBuffer);
626 beginLegacyRender(*cmdBuffer);
627 drawCommands(*cmdBuffer);
628 endRenderPass(vk, *cmdBuffer);
629 }
630
631 if (hasDepth)
632 {
633 const VkMemoryBarrier memBarrier = {VK_STRUCTURE_TYPE_MEMORY_BARRIER, DE_NULL, VK_ACCESS_TRANSFER_WRITE_BIT,
634 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
635 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT};
636 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 0,
637 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
638 }
639 if (hasColor)
640 {
641 const VkMemoryBarrier memBarrier = {VK_STRUCTURE_TYPE_MEMORY_BARRIER, DE_NULL, VK_ACCESS_TRANSFER_WRITE_BIT,
642 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT};
643 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
644 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
645 }
646
647 if (hasColor)
648 transition2DImage(vk, *cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_ASPECT_COLOR_BIT,
649 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
650 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT,
651 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_HOST_BIT);
652 if (hasDepth)
653 transition2DImage(vk, *cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_ASPECT_DEPTH_BIT,
654 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
655 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT,
656 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_HOST_BIT);
657
658 endCommandBuffer(vk, *cmdBuffer);
659 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
660
661 VK_CHECK(vk.queueWaitIdle(queue));
662
663 if (hasColor)
664 {
665 const auto resultImage = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
666 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, {0, 0, 0}, WIDTH,
667 HEIGHT, VK_IMAGE_ASPECT_COLOR_BIT);
668
669 #ifdef CTS_USES_VULKANSC
670 if (m_context.getTestContext().getCommandLine().isSubProcess())
671 #endif // CTS_USES_VULKANSC
672 {
673 for (int z = 0; z < resultImage.getDepth(); ++z)
674 for (int y = 0; y < resultImage.getHeight(); ++y)
675 for (int x = 0; x < resultImage.getWidth(); ++x)
676 {
677 const Vec4 difference = m_params.expectedColor - resultImage.getPixel(x, y, z);
678 if (abs(difference.x()) >= m_params.colorEpsilon ||
679 abs(difference.y()) >= m_params.colorEpsilon ||
680 abs(difference.z()) >= m_params.colorEpsilon)
681 {
682 ostringstream msg;
683 msg << "Color value mismatch, expected: " << m_params.expectedColor
684 << ", got: " << resultImage.getPixel(x, y, z) << " at "
685 << "(" << x << ", " << y << ", " << z << ")";
686 return tcu::TestStatus::fail(msg.str());
687 }
688 }
689 }
690 }
691 if (hasDepth)
692 {
693 const auto resultImage = m_depthTargetImage->readSurface(queue, m_context.getDefaultAllocator(),
694 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, {0, 0, 0}, WIDTH,
695 HEIGHT, VK_IMAGE_ASPECT_DEPTH_BIT);
696
697 #ifdef CTS_USES_VULKANSC
698 if (m_context.getTestContext().getCommandLine().isSubProcess())
699 #endif // CTS_USES_VULKANSC
700 {
701 for (int z = 0; z < resultImage.getDepth(); ++z)
702 for (int y = 0; y < resultImage.getHeight(); ++y)
703 for (int x = 0; x < resultImage.getWidth(); ++x)
704 {
705 const float difference = m_params.expectedDepth - resultImage.getPixDepth(x, y, z);
706 if (abs(difference) >= m_params.depthEpsilon)
707 {
708 ostringstream msg;
709 msg << "Depth value mismatch, expected: " << m_params.expectedDepth
710 << ", got: " << resultImage.getPixDepth(x, y, z) << " at "
711 << "(" << x << ", " << y << ", " << z << ")";
712 return tcu::TestStatus::fail(msg.str());
713 }
714 }
715 }
716 }
717 return tcu::TestStatus::pass("Pass");
718 }
719
720 class MultipleClearsWithinRenderPassTest : public TestCase
721 {
722 public:
MultipleClearsWithinRenderPassTest(tcu::TestContext & testCtx,const string & name,const TestParams & params)723 MultipleClearsWithinRenderPassTest(tcu::TestContext &testCtx, const string &name, const TestParams ¶ms)
724 : TestCase(testCtx, name)
725 , m_params(params)
726 {
727 DE_ASSERT(m_params.steps.size() <= static_cast<size_t>(TEST_MAX_STEPS_COUNT));
728 }
729
initPrograms(SourceCollections & programCollection) const730 virtual void initPrograms(SourceCollections &programCollection) const
731 {
732 {
733 ostringstream src;
734 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
735 << "\n"
736 << "layout(location = 0) in vec4 in_position;\n"
737 << "\n"
738 << "out gl_PerVertex {\n"
739 << " vec4 gl_Position;\n"
740 << "};\n"
741 << "\n"
742 << "void main(void)\n"
743 << "{\n"
744 << " gl_Position = in_position;\n"
745 << "}\n";
746 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
747 }
748 {
749 ostringstream src;
750 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
751 << "\n"
752 << "layout(push_constant) uniform Color { vec4 color; } u_color;\n"
753 << "layout(location = 0) out vec4 out_color;\n"
754 << "\n"
755 << "void main(void)\n"
756 << "{\n"
757 << " out_color = u_color.color;\n"
758 << "}\n";
759 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
760 }
761 {
762 ostringstream src;
763 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
764 << "\n"
765 << "layout(push_constant) uniform Color { vec4 color; } u_color;\n"
766 << "\n"
767 << "void main(void)\n"
768 << "{\n"
769 << "}\n";
770 programCollection.glslSources.add("frag_depthonly") << glu::FragmentSource(src.str());
771 }
772 }
773
checkSupport(Context & context) const774 virtual void checkSupport(Context &context) const
775 {
776 VkImageFormatProperties imageFormatProperties;
777 const auto &vki = context.getInstanceInterface();
778 const auto &vkd = context.getPhysicalDevice();
779 if (m_params.colorFormat != VK_FORMAT_UNDEFINED)
780 {
781 const auto colorUsage =
782 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
783 if (vki.getPhysicalDeviceImageFormatProperties(vkd, m_params.colorFormat, VK_IMAGE_TYPE_2D,
784 VK_IMAGE_TILING_OPTIMAL, colorUsage, 0u,
785 &imageFormatProperties) != VK_SUCCESS)
786 TCU_THROW(NotSupportedError, "Color format not supported");
787
788 vk::VkFormatProperties formatProperties;
789 vki.getPhysicalDeviceFormatProperties(vkd, m_params.colorFormat, &formatProperties);
790 if ((formatProperties.optimalTilingFeatures & VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT) == 0)
791 TCU_THROW(NotSupportedError, "Color format not supported");
792 }
793 if (m_params.depthFormat != VK_FORMAT_UNDEFINED)
794 {
795 const auto depthUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
796 VK_IMAGE_USAGE_TRANSFER_DST_BIT;
797 if (vki.getPhysicalDeviceImageFormatProperties(vkd, m_params.depthFormat, VK_IMAGE_TYPE_2D,
798 VK_IMAGE_TILING_OPTIMAL, depthUsage, 0u,
799 &imageFormatProperties) != VK_SUCCESS)
800 TCU_THROW(NotSupportedError, "Depth format not supported");
801 }
802
803 if (m_params.groupParams->useDynamicRendering)
804 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
805 }
806
createInstance(Context & context) const807 virtual TestInstance *createInstance(Context &context) const
808 {
809 return new MultipleClearsTest(context, m_params);
810 }
811
812 private:
813 const TestParams m_params;
814 };
815
816 } // namespace
817
MultipleClearsWithinRenderPassTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)818 MultipleClearsWithinRenderPassTests::MultipleClearsWithinRenderPassTests(tcu::TestContext &testCtx,
819 const SharedGroupParams groupParams)
820 : TestCaseGroup(testCtx, "multiple_clears_within_render_pass")
821 , m_groupParams(groupParams)
822 {
823 }
824
~MultipleClearsWithinRenderPassTests()825 MultipleClearsWithinRenderPassTests::~MultipleClearsWithinRenderPassTests()
826 {
827 }
828
init()829 void MultipleClearsWithinRenderPassTests::init()
830 {
831 for (const auto &formatPair : formatsToTest)
832 {
833 ostringstream formatSuffix;
834 if (formatPair.colorFormat != VK_FORMAT_UNDEFINED)
835 formatSuffix << "_c" << de::toLower(string(getFormatName(formatPair.colorFormat)).substr(9));
836 if (formatPair.depthFormat != VK_FORMAT_UNDEFINED)
837 formatSuffix << "_d" << de::toLower(string(getFormatName(formatPair.depthFormat)).substr(9));
838 for (const auto &topology : topologiesToTest)
839 {
840 // reduce number of tests for dynamic rendering cases where secondary command buffer is used
841 if (m_groupParams->useSecondaryCmdBuffer && (topology != Topology::TRIANGLE_STRIP))
842 continue;
843
844 const string testNameSuffix = formatSuffix.str() + verticesByTopology[(uint32_t)topology].testNameSuffix;
845 {
846 const TestParams params{formatPair.colorFormat, // VkFormat colorFormat;
847 formatPair.depthFormat, // VkFormat depthFormat;
848 topology, // Topology topology;
849 Vec4(0.0f, 0.5f, 0.5f, 1.0f), // Vec4 expectedColor;
850 0.01f, // float colorEpsilon;
851 0.9f, // float expectedDepth;
852 0.01f, // float depthEpsilon;
853 1u, // uint32_t repeatCount;
854 true, // bool enableBlend;
855 m_groupParams, // SharedGroupParams groupParams;
856 { // vector<ClearStep> steps;
857 {ClearOp::LOAD, Vec4(1.0f, 0.0f, 0.0f, 1.0f), 0.7f},
858 {ClearOp::CLEAR, Vec4(0.0f, 1.0f, 0.0f, 1.0f), 0.3f},
859 {ClearOp::DRAW, Vec4(0.0f, 0.0f, 1.0f, 0.5f), 0.9f}}};
860 // Multiple clears within same render pass, methods: load, clear, draw
861 addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "load_clear_draw" + testNameSuffix, params));
862 }
863 {
864 const TestParams params{formatPair.colorFormat, // VkFormat format;
865 formatPair.depthFormat, // VkFormat depthFormat;
866 topology, // Topology topology;
867 Vec4(0.0f, 0.5f, 0.5f, 1.0f), // Vec4 expectedColor;
868 0.01f, // float colorEpsilon;
869 0.9f, // float expectedDepth;
870 0.01f, // float depthEpsilon;
871 1u, // uint32_t repeatCount;
872 true, // bool enableBlend;
873 m_groupParams, // SharedGroupParams groupParams;
874 { // vector<ClearStep> steps;
875 {ClearOp::DRAW, Vec4(1.0f, 0.0f, 0.0f, 1.0f), 0.7f},
876 {ClearOp::CLEAR, Vec4(0.0f, 1.0f, 0.0f, 1.0f), 0.3f},
877 {ClearOp::DRAW, Vec4(0.0f, 0.0f, 1.0f, 0.5f), 0.9f}}};
878 // Multiple clears within same render pass, methods: draw, clear, draw
879 addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "draw_clear_draw" + testNameSuffix, params));
880 }
881 {
882 const TestParams params{formatPair.colorFormat, // VkFormat format;
883 formatPair.depthFormat, // VkFormat depthFormat;
884 topology, // Topology topology;
885 Vec4(0.0f, 0.5f, 0.5f, 1.0f), // Vec4 expectedColor;
886 0.01f, // float colorEpsilon;
887 0.9f, // float expectedDepth;
888 0.01f, // float depthEpsilon;
889 1u, // uint32_t repeatCount;
890 true, // bool enableBlend;
891 m_groupParams, // SharedGroupParams groupParams;
892 { // vector<ClearStep> steps;
893 {ClearOp::CLEAR, Vec4(1.0f, 0.0f, 0.0f, 1.0f), 0.7f},
894 {ClearOp::CLEAR, Vec4(0.0f, 1.0f, 0.0f, 1.0f), 0.3f},
895 {ClearOp::DRAW, Vec4(0.0f, 0.0f, 1.0f, 0.5f), 0.9f}}};
896 // Multiple clears within same render pass, methods: clear, clear, draw
897 addChild(
898 new MultipleClearsWithinRenderPassTest(m_testCtx, "clear_clear_draw" + testNameSuffix, params));
899 }
900 {
901 const TestParams params{formatPair.colorFormat, // VkFormat format;
902 formatPair.depthFormat, // VkFormat depthFormat;
903 topology, // Topology topology;
904 Vec4(0.0f, 1.0f, 0.0f, 1.0f), // Vec4 expectedColor;
905 0.01f, // float colorEpsilon;
906 0.9f, // float expectedDepth;
907 0.01f, // float depthEpsilon;
908 1u, // uint32_t repeatCount;
909 false, // bool enableBlend;
910 m_groupParams, // SharedGroupParams groupParams;
911 { // vector<ClearStep> steps;
912 {ClearOp::LOAD, Vec4(1.0f, 0.0f, 0.0f, 1.0f), 0.3f},
913 {ClearOp::CLEAR, Vec4(0.0f, 1.0f, 0.0f, 1.0f), 0.9f}}};
914 // Multiple clears within same render pass, methods: load, clear
915 addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "load_clear" + testNameSuffix, params));
916 }
917 {
918 const TestParams params{formatPair.colorFormat, // VkFormat format;
919 formatPair.depthFormat, // VkFormat depthFormat;
920 topology, // Topology topology;
921 Vec4(0.0f, 1.0f, 0.0f, 1.0f), // Vec4 expectedColor;
922 0.01f, // float colorEpsilon;
923 0.9f, // float expectedDepth;
924 0.01f, // float depthEpsilon;
925 1u, // uint32_t repeatCount;
926 false, // bool enableBlend;
927 m_groupParams, // SharedGroupParams groupParams;
928 { // vector<ClearStep> steps;
929 {ClearOp::DRAW, Vec4(1.0f, 0.0f, 0.0f, 1.0f), 0.3f},
930 {ClearOp::CLEAR, Vec4(0.0f, 1.0f, 0.0f, 1.0f), 0.9f}}};
931 // Multiple clears within same render pass, methods: draw, clear
932 addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "draw_clear" + testNameSuffix, params));
933 }
934 {
935 const TestParams params{formatPair.colorFormat, // VkFormat format;
936 formatPair.depthFormat, // VkFormat depthFormat;
937 topology, // Topology topology;
938 Vec4(0.0f, 1.0f, 0.0f, 1.0f), // Vec4 expectedColor;
939 0.01f, // float colorEpsilon;
940 0.9f, // float expectedDepth;
941 0.01f, // float depthEpsilon;
942 1u, // uint32_t repeatCount;
943 false, // bool enableBlend;
944 m_groupParams, // SharedGroupParams groupParams;
945 { // vector<ClearStep> steps;
946 {ClearOp::CLEAR, Vec4(1.0f, 0.0f, 0.0f, 1.0f), 0.3f},
947 {ClearOp::CLEAR, Vec4(0.0f, 1.0f, 0.0f, 1.0f), 0.9f}}};
948 // Multiple clears within same render pass, methods: clear, clear
949 addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "clear_clear" + testNameSuffix, params));
950 }
951 }
952 }
953 }
954 } // namespace Draw
955 } // namespace vkt
956