1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * -----------------------------
5 * Copyright (c) 2020 Google Inc.
6 * Copyright (c) 2020 The Khronos Group Inc.
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 * \brief Tests for multiple color or depth clears within a render pass
23 *//*--------------------------------------------------------------------*/
25 #include "vktDrawMultipleClearsWithinRenderPass.hpp"
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"
43 #include "deStringUtil.hpp"
62 using std::ostringstream;
64 const deUint32 WIDTH = 400;
65 const deUint32 HEIGHT = 300;
74 const Topology topologiesToTest[] =
76 Topology::TRIANGLE_STRIP,
87 const FormatPair formatsToTest[] =
89 { VK_FORMAT_R8G8B8A8_UNORM , VK_FORMAT_UNDEFINED },
90 { VK_FORMAT_R8G8B8A8_SNORM , VK_FORMAT_UNDEFINED },
91 { VK_FORMAT_UNDEFINED , VK_FORMAT_D32_SFLOAT },
92 { VK_FORMAT_UNDEFINED , VK_FORMAT_D16_UNORM },
93 { VK_FORMAT_R8G8B8A8_UNORM , VK_FORMAT_D32_SFLOAT },
94 { VK_FORMAT_R8G8B8A8_UNORM , VK_FORMAT_D16_UNORM },
95 { VK_FORMAT_R8G8B8A8_SNORM , VK_FORMAT_D32_SFLOAT },
96 { VK_FORMAT_R8G8B8A8_SNORM , VK_FORMAT_D16_UNORM },
99 const Vec4 verticesTriangleStrip[] =
101 Vec4(-1.0f, -1.0f, 0.0f, 1.0f), // 0 -- 2
102 Vec4(-1.0f, 1.0f, 0.0f, 1.0f), // | / |
103 Vec4( 1.0f, -1.0f, 0.0f, 1.0f), // | / |
104 Vec4( 1.0f, 1.0f, 0.0f, 1.0f) // 1 -- 3
106 const Vec4 verticesTriangles[] =
108 Vec4(-1.0f, -1.0f, 0.0f, 1.0f), // 0 - 1
109 Vec4(-1.0f, 1.0f, 0.0f, 1.0f), // | /
110 Vec4( 1.0f, -1.0f, 0.0f, 1.0f), // 2
111 Vec4( 1.0f, -1.0f, 0.0f, 1.0f), // 4
112 Vec4(-1.0f, 1.0f, 0.0f, 1.0f), // / |
113 Vec4( 1.0f, 1.0f, 0.0f, 1.0f) // 3 - 5
115 const Vec4 verticesBigTriangle[] =
117 Vec4(-1.0f, -1.0f, 0.0f, 1.0f), // 0 - 2
118 Vec4(-1.0f, 3.0f, 0.0f, 1.0f), // | /
119 Vec4( 3.0f, -1.0f, 0.0f, 1.0f), // 1
122 const deUint32 TOPOLOGY_MAX_VERTICES_COUNT = 6;
123 const deUint32 TEST_MAX_STEPS_COUNT = 3;
127 const char* testNameSuffix;
128 VkPrimitiveTopology topology;
129 deUint32 verticesCount;
130 const Vec4* vertices;
133 const Vertices verticesByTopology[] =
137 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP,
138 DE_LENGTH_OF_ARRAY(verticesTriangleStrip),
139 verticesTriangleStrip
143 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
144 DE_LENGTH_OF_ARRAY(verticesTriangles),
149 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
150 DE_LENGTH_OF_ARRAY(verticesBigTriangle),
171 VkFormat colorFormat;
172 VkFormat depthFormat;
178 deUint32 repeatCount;
180 const SharedGroupParams groupParams;
181 vector<ClearStep> steps;
184 class MultipleClearsTest : public TestInstance
187 MultipleClearsTest (Context& context, const TestParams& params);
188 virtual tcu::TestStatus iterate (void);
191 void preRenderCommands (VkCommandBuffer cmdBuffer) const;
192 void beginLegacyRender (VkCommandBuffer cmdBuffer) const;
193 void drawCommands (VkCommandBuffer cmdBuffer) const;
195 #ifndef CTS_USES_VULKANSC
196 void beginSecondaryCmdBuffer (VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags = 0u) const;
197 void beginDynamicRender (VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags = 0u) const;
198 #endif // CTS_USES_VULKANSC
200 SharedPtr<Image> m_colorTargetImage;
201 SharedPtr<Image> m_depthTargetImage;
202 Move<VkImageView> m_colorTargetView;
203 Move<VkImageView> m_depthTargetView;
204 SharedPtr<Buffer> m_vertexBuffer;
205 Move<VkRenderPass> m_renderPass;
206 Move<VkFramebuffer> m_framebuffer;
207 Move<VkPipelineLayout> m_pipelineLayout;
208 Move<VkPipeline> m_pipeline;
210 const TestParams m_params;
211 Vec4 m_vertices[TOPOLOGY_MAX_VERTICES_COUNT * TEST_MAX_STEPS_COUNT];
214 MultipleClearsTest::MultipleClearsTest (Context &context, const TestParams& params)
215 : TestInstance(context)
218 const DeviceInterface& vk = m_context.getDeviceInterface();
219 const VkDevice device = m_context.getDevice();
220 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
221 const bool hasColor = m_params.colorFormat != VK_FORMAT_UNDEFINED;
222 const bool hasDepth = m_params.depthFormat != VK_FORMAT_UNDEFINED;
224 DescriptorSetLayoutBuilder descriptorSetLayoutBuilder;
226 const auto& vertexData = verticesByTopology[(size_t)m_params.topology];
228 DE_ASSERT(vertexData.verticesCount <= TOPOLOGY_MAX_VERTICES_COUNT);
229 const size_t verticesCount = vertexData.verticesCount;
230 const VkDeviceSize dataSize = verticesCount * sizeof(Vec4);
231 const VkDeviceSize totalDataSize = m_params.steps.size() * dataSize;
232 DE_ASSERT(totalDataSize <= sizeof(m_vertices));
234 for(size_t i = 0; i < m_params.steps.size(); ++i)
236 const size_t start = i * verticesCount;
237 deMemcpy(&m_vertices[start], vertexData.vertices, static_cast<size_t>(dataSize));
238 for(size_t j = 0; j < verticesCount; ++j)
239 m_vertices[start + j][2] = m_params.steps[i].depth;
241 m_vertexBuffer = Buffer::createAndAlloc(vk, device, BufferCreateInfo(totalDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT),
242 m_context.getDefaultAllocator(), MemoryRequirement::HostVisible);
243 deMemcpy(m_vertexBuffer->getBoundMemory().getHostPtr(), m_vertices, static_cast<std::size_t>(totalDataSize));
244 flushMappedMemoryRange(vk, device, m_vertexBuffer->getBoundMemory().getMemory(), m_vertexBuffer->getBoundMemory().getOffset(), VK_WHOLE_SIZE);
249 const VkImageUsageFlags targetImageUsageFlags = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
250 const ImageCreateInfo targetImageCreateInfo (VK_IMAGE_TYPE_2D, m_params.colorFormat, { WIDTH, HEIGHT, 1u }, 1u, 1u, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, targetImageUsageFlags);
251 m_colorTargetImage = Image::createAndAlloc(vk, device, targetImageCreateInfo, m_context.getDefaultAllocator(), queueFamilyIndex);
252 const ImageViewCreateInfo colorTargetViewInfo (m_colorTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_params.colorFormat);
253 m_colorTargetView = createImageView(vk, device, &colorTargetViewInfo);
258 const VkImageUsageFlags depthImageUsageFlags = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
259 const ImageCreateInfo depthImageCreateInfo (VK_IMAGE_TYPE_2D, m_params.depthFormat, { WIDTH, HEIGHT, 1u }, 1u, 1u, VK_SAMPLE_COUNT_1_BIT, VK_IMAGE_TILING_OPTIMAL, depthImageUsageFlags);
260 m_depthTargetImage = Image::createAndAlloc(vk, device, depthImageCreateInfo, m_context.getDefaultAllocator(), queueFamilyIndex);
261 const ImageViewCreateInfo depthTargetViewInfo (m_depthTargetImage->object(), VK_IMAGE_VIEW_TYPE_2D, m_params.depthFormat);
262 m_depthTargetView = createImageView(vk, device, &depthTargetViewInfo);
266 if (!m_params.groupParams->useDynamicRendering)
268 RenderPassCreateInfo renderPassCreateInfo;
271 renderPassCreateInfo.addAttachment(AttachmentDescription(
272 m_params.colorFormat, // format
273 VK_SAMPLE_COUNT_1_BIT, // samples
274 VK_ATTACHMENT_LOAD_OP_LOAD, // loadOp
275 VK_ATTACHMENT_STORE_OP_STORE, // storeOp
276 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
277 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
278 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // initialLayout
279 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL)); // finalLayout
283 renderPassCreateInfo.addAttachment(AttachmentDescription(
284 m_params.depthFormat, // format
285 VK_SAMPLE_COUNT_1_BIT, // samples
286 VK_ATTACHMENT_LOAD_OP_LOAD, // loadOp
287 VK_ATTACHMENT_STORE_OP_STORE, // storeOp
288 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
289 VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
290 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // initialLayout
291 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL)); // finalLayout
293 const VkAttachmentReference colorAttachmentReference = hasColor ? makeAttachmentReference(0u, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) : AttachmentReference();
294 const VkAttachmentReference depthAttachmentReference = hasDepth ? makeAttachmentReference(hasColor ? 1u : 0u, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL) : AttachmentReference();
295 renderPassCreateInfo.addSubpass(SubpassDescription(
296 VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
297 (VkSubpassDescriptionFlags)0, // flags
298 0u, // inputAttachmentCount
299 DE_NULL, // inputAttachments
300 hasColor ? 1 : 0, // colorAttachmentCount
301 hasColor ? &colorAttachmentReference : DE_NULL, // colorAttachments
302 DE_NULL, // resolveAttachments
303 depthAttachmentReference, // depthStencilAttachment
304 0u, // preserveAttachmentCount
305 DE_NULL)); // preserveAttachments
306 m_renderPass = createRenderPass(vk, device, &renderPassCreateInfo);
308 std::vector<VkImageView> attachments;
310 attachments.push_back(*m_colorTargetView);
312 attachments.push_back(*m_depthTargetView);
313 const FramebufferCreateInfo framebufferCreateInfo(*m_renderPass, attachments, WIDTH, HEIGHT, 1);
314 m_framebuffer = createFramebuffer(vk, device, &framebufferCreateInfo);
318 const VkVertexInputBindingDescription vertexInputBindingDescription =
320 0u, // uint32_t binding;
321 sizeof(Vec4), // uint32_t stride;
322 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
325 const VkVertexInputAttributeDescription vertexInputAttributeDescription =
327 0u, // uint32_t location;
328 0u, // uint32_t binding;
329 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
330 0u // uint32_t offset;
333 const PipelineCreateInfo::VertexInputState vertexInputState = PipelineCreateInfo::VertexInputState(1, &vertexInputBindingDescription,
334 1, &vertexInputAttributeDescription);
337 const Unique<VkShaderModule> vertexModule (createShaderModule(vk, device, m_context.getBinaryCollection().get("vert"), 0));
338 const Unique<VkShaderModule> fragmentModule (createShaderModule(vk, device, m_context.getBinaryCollection().get(hasColor ? "frag" : "frag_depthonly"), 0));
340 const VkPushConstantRange pcRange = vk::VkPushConstantRange { VkShaderStageFlagBits::VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(ClearStep::color) };
341 const PipelineLayoutCreateInfo pipelineLayoutCreateInfo (0u, DE_NULL, 1u, &pcRange);
342 m_pipelineLayout = createPipelineLayout(vk, device, &pipelineLayoutCreateInfo);
344 const VkRect2D scissor = makeRect2D(WIDTH, HEIGHT);
345 const VkViewport viewport = makeViewport(WIDTH, HEIGHT);
347 const auto vkCbAttachmentState = makePipelineColorBlendAttachmentState(
348 m_params.enableBlend ? VK_TRUE : VK_FALSE, // VkBool32 blendEnable
349 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor
350 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor
351 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
352 VK_BLEND_FACTOR_ZERO, // VkBlendFactor srcAlphaBlendFactor
353 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor
354 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
355 VK_COLOR_COMPONENT_R_BIT | // VkColorComponentFlags colorWriteMask
356 VK_COLOR_COMPONENT_G_BIT |
357 VK_COLOR_COMPONENT_B_BIT |
358 VK_COLOR_COMPONENT_A_BIT);
359 PipelineCreateInfo pipelineCreateInfo(*m_pipelineLayout, *m_renderPass, 0, (VkPipelineCreateFlags)0);
360 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*vertexModule, "main", VK_SHADER_STAGE_VERTEX_BIT));
361 pipelineCreateInfo.addShader(PipelineCreateInfo::PipelineShaderStage(*fragmentModule, "main", VK_SHADER_STAGE_FRAGMENT_BIT));
362 pipelineCreateInfo.addState (PipelineCreateInfo::VertexInputState (vertexInputState));
363 pipelineCreateInfo.addState (PipelineCreateInfo::InputAssemblerState(vertexData.topology));
364 pipelineCreateInfo.addState (PipelineCreateInfo::ColorBlendState (1, &vkCbAttachmentState));
365 pipelineCreateInfo.addState (PipelineCreateInfo::ViewportState (1, std::vector<VkViewport>(1, viewport), std::vector<VkRect2D>(1, scissor)));
366 pipelineCreateInfo.addState (PipelineCreateInfo::DepthStencilState (hasDepth, hasDepth, VK_COMPARE_OP_ALWAYS, VK_FALSE, VK_FALSE));
367 pipelineCreateInfo.addState (PipelineCreateInfo::RasterizerState ());
368 pipelineCreateInfo.addState (PipelineCreateInfo::MultiSampleState ());
370 #ifndef CTS_USES_VULKANSC
371 vk::VkPipelineRenderingCreateInfoKHR renderingCreateInfo
373 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
377 (hasColor ? &m_params.colorFormat : DE_NULL),
378 m_params.depthFormat,
382 if (m_params.groupParams->useDynamicRendering)
383 pipelineCreateInfo.pNext = &renderingCreateInfo;
384 #endif // CTS_USES_VULKANSC
386 m_pipeline = createGraphicsPipeline(vk, device, DE_NULL, &pipelineCreateInfo);
389 void MultipleClearsTest::preRenderCommands(VkCommandBuffer cmdBuffer) const
391 const DeviceInterface& vk = m_context.getDeviceInterface();
392 if (m_params.colorFormat)
393 initialTransitionColor2DImage(vk, cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT);
394 if (m_params.depthFormat)
395 initialTransitionDepth2DImage(vk, cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
398 void MultipleClearsTest::beginLegacyRender(VkCommandBuffer cmdBuffer) const
400 const DeviceInterface& vk = m_context.getDeviceInterface();
401 const VkRect2D renderArea = makeRect2D(0, 0, WIDTH, HEIGHT);
403 if (!m_params.steps.empty() && m_params.steps[0].clearOp == ClearOp::LOAD)
404 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea, m_params.steps[0].color, m_params.steps[0].depth, 0);
406 beginRenderPass(vk, cmdBuffer, *m_renderPass, *m_framebuffer, renderArea);
409 void MultipleClearsTest::drawCommands(vk::VkCommandBuffer cmdBuffer) const
411 const DeviceInterface& vk = m_context.getDeviceInterface();
413 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipeline);
415 const VkDeviceSize offset = 0;
416 const VkBuffer buffer = m_vertexBuffer->object();
417 vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &buffer, &offset);
420 for (deUint32 i = 0; i < m_params.repeatCount; ++i)
421 for (size_t stepIndex = 0; stepIndex < m_params.steps.size(); ++stepIndex)
423 const auto& step = m_params.steps[stepIndex];
425 // ClearOp::LOAD only supported for first step
426 DE_ASSERT(stepIndex == 0 || step.clearOp != ClearOp::LOAD);
428 const Vec4& color = step.color;
429 const float depth = step.depth;
437 const auto& vertexData = verticesByTopology[(size_t)m_params.topology];
438 const deUint32 verticesCount = vertexData.verticesCount;
439 vk.cmdPushConstants(cmdBuffer, *m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(color), color.getPtr());
440 vk.cmdDraw(cmdBuffer, verticesCount, 1, static_cast<deUint32>(verticesCount * stepIndex), 0);
445 vector<VkClearAttachment> clearAttachments;
446 if (m_params.colorFormat != VK_FORMAT_UNDEFINED)
448 const VkClearAttachment clearAttachment
450 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask
451 static_cast<deUint32>(clearAttachments.size()), // uint32_t colorAttachment
452 makeClearValueColor(color) // VkClearValue clearValue
454 clearAttachments.push_back(clearAttachment);
456 if (m_params.depthFormat != VK_FORMAT_UNDEFINED)
458 const VkClearAttachment clearAttachment
460 VK_IMAGE_ASPECT_DEPTH_BIT, // VkImageAspectFlags aspectMask
461 static_cast<deUint32>(clearAttachments.size()), // uint32_t colorAttachment
462 makeClearValueDepthStencil(depth, 0) // VkClearValue clearValue
464 clearAttachments.push_back(clearAttachment);
466 const VkClearRect clearRect
468 makeRect2D(WIDTH, HEIGHT), // VkRect2D rect
469 0, // uint32_t baseArrayLayer
470 1 // uint32_t layerCount
472 vk.cmdClearAttachments(cmdBuffer, static_cast<deUint32>(clearAttachments.size()), clearAttachments.data(), 1, &clearRect);
481 #ifndef CTS_USES_VULKANSC
482 void MultipleClearsTest::beginSecondaryCmdBuffer(VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags) const
484 VkCommandBufferInheritanceRenderingInfoKHR inheritanceRenderingInfo
486 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO_KHR, // VkStructureType sType;
487 DE_NULL, // const void* pNext;
488 renderingFlags, // VkRenderingFlagsKHR flags;
489 0u, // uint32_t viewMask;
490 (m_params.colorFormat != VK_FORMAT_UNDEFINED), // uint32_t colorAttachmentCount;
491 &m_params.colorFormat, // const VkFormat* pColorAttachmentFormats;
492 m_params.depthFormat, // VkFormat depthAttachmentFormat;
493 VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat;
494 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
497 const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
499 VkCommandBufferUsageFlags usageFlags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT;
500 if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
501 usageFlags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
503 const VkCommandBufferBeginInfo commandBufBeginParams
505 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
506 DE_NULL, // const void* pNext;
507 usageFlags, // VkCommandBufferUsageFlags flags;
508 &bufferInheritanceInfo
511 const DeviceInterface& vk = m_context.getDeviceInterface();
512 VK_CHECK(vk.beginCommandBuffer(cmdBuffer, &commandBufBeginParams));
515 void MultipleClearsTest::beginDynamicRender(VkCommandBuffer cmdBuffer, VkRenderingFlagsKHR renderingFlags) const
517 const DeviceInterface& vk = m_context.getDeviceInterface();
518 const VkRect2D renderArea = makeRect2D(0, 0, WIDTH, HEIGHT);
520 VkClearValue clearColorValue = makeClearValueColor(tcu::Vec4(0.0f));
521 VkClearValue clearDepthValue = makeClearValueDepthStencil(0.0f, 0u);
522 if (!m_params.steps.empty() && m_params.steps[0].clearOp == ClearOp::LOAD)
524 clearColorValue = makeClearValueColor(m_params.steps[0].color);
525 clearDepthValue = makeClearValueDepthStencil(m_params.steps[0].depth, 0u);
528 vk::VkRenderingAttachmentInfoKHR colorAttachment
530 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
531 DE_NULL, // const void* pNext;
532 *m_colorTargetView, // VkImageView imageView;
533 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
534 vk::VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
535 DE_NULL, // VkImageView resolveImageView;
536 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
537 vk::VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
538 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
539 clearColorValue // VkClearValue clearValue;
542 vk::VkRenderingAttachmentInfoKHR depthAttachment
544 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType;
545 DE_NULL, // const void* pNext;
546 *m_depthTargetView, // VkImageView imageView;
547 vk::VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
548 vk::VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
549 DE_NULL, // VkImageView resolveImageView;
550 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
551 vk::VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
552 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
553 clearDepthValue // VkClearValue clearValue;
556 const bool hasColor = m_params.colorFormat != VK_FORMAT_UNDEFINED;
557 const bool hasDepth = m_params.depthFormat != VK_FORMAT_UNDEFINED;
559 vk::VkRenderingInfoKHR renderingInfo
561 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR,
563 renderingFlags, // VkRenderingFlagsKHR flags;
564 renderArea, // VkRect2D renderArea;
565 1u, // deUint32 layerCount;
566 0u, // deUint32 viewMask;
567 hasColor, // deUint32 colorAttachmentCount;
568 (hasColor ? &colorAttachment : DE_NULL), // const VkRenderingAttachmentInfoKHR* pColorAttachments;
569 (hasDepth ? &depthAttachment : DE_NULL), // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
570 DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
573 vk.cmdBeginRendering(cmdBuffer, &renderingInfo);
575 #endif // CTS_USES_VULKANSC
577 tcu::TestStatus MultipleClearsTest::iterate (void)
579 const DeviceInterface& vk = m_context.getDeviceInterface();
580 const VkDevice device = m_context.getDevice();
581 const VkQueue queue = m_context.getUniversalQueue();
582 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
584 const CmdPoolCreateInfo cmdPoolCreateInfo (queueFamilyIndex);
585 const Unique<VkCommandPool> cmdPool (createCommandPool(vk, device, &cmdPoolCreateInfo));
586 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
587 Move<VkCommandBuffer> secCmdBuffer;
589 const bool hasColor = m_params.colorFormat != VK_FORMAT_UNDEFINED;
590 const bool hasDepth = m_params.depthFormat != VK_FORMAT_UNDEFINED;
592 #ifndef CTS_USES_VULKANSC
593 if (m_params.groupParams->useSecondaryCmdBuffer)
595 secCmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
597 // record secondary command buffer
598 if (m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
600 beginSecondaryCmdBuffer(*secCmdBuffer, VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT);
601 beginDynamicRender(*secCmdBuffer);
604 beginSecondaryCmdBuffer(*secCmdBuffer);
606 drawCommands(*secCmdBuffer);
608 if (m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
609 endRendering(vk, *secCmdBuffer);
611 endCommandBuffer(vk, *secCmdBuffer);
613 // record primary command buffer
614 beginCommandBuffer(vk, *cmdBuffer, 0u);
615 preRenderCommands(*cmdBuffer);
617 if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
618 beginDynamicRender(*cmdBuffer, VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
620 vk.cmdExecuteCommands(*cmdBuffer, 1u, &*secCmdBuffer);
622 if (!m_params.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
623 endRendering(vk, *cmdBuffer);
625 else if (m_params.groupParams->useDynamicRendering)
627 beginCommandBuffer(vk, *cmdBuffer);
628 preRenderCommands(*cmdBuffer);
629 beginDynamicRender(*cmdBuffer);
630 drawCommands(*cmdBuffer);
631 endRendering(vk, *cmdBuffer);
633 #endif // CTS_USES_VULKANSC
635 if (!m_params.groupParams->useDynamicRendering)
637 beginCommandBuffer(vk, *cmdBuffer);
638 preRenderCommands(*cmdBuffer);
639 beginLegacyRender(*cmdBuffer);
640 drawCommands(*cmdBuffer);
641 endRenderPass(vk, *cmdBuffer);
646 const VkMemoryBarrier memBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER, DE_NULL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT };
647 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
651 const VkMemoryBarrier memBarrier = { VK_STRUCTURE_TYPE_MEMORY_BARRIER, DE_NULL, VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT };
652 vk.cmdPipelineBarrier(*cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0, 1, &memBarrier, 0, DE_NULL, 0, DE_NULL);
656 transition2DImage(vk, *cmdBuffer, m_colorTargetImage->object(), VK_IMAGE_ASPECT_COLOR_BIT,
657 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
658 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT,
659 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, VK_PIPELINE_STAGE_HOST_BIT);
661 transition2DImage(vk, *cmdBuffer, m_depthTargetImage->object(), VK_IMAGE_ASPECT_DEPTH_BIT,
662 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
663 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, VK_ACCESS_MEMORY_READ_BIT,
664 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_HOST_BIT);
666 endCommandBuffer(vk, *cmdBuffer);
667 submitCommandsAndWait(vk, device, queue, *cmdBuffer);
669 VK_CHECK(vk.queueWaitIdle(queue));
673 const auto resultImage = m_colorTargetImage->readSurface(queue, m_context.getDefaultAllocator(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { 0, 0, 0 }, WIDTH, HEIGHT, VK_IMAGE_ASPECT_COLOR_BIT);
675 #ifdef CTS_USES_VULKANSC
676 if (m_context.getTestContext().getCommandLine().isSubProcess())
677 #endif // CTS_USES_VULKANSC
679 for(int z = 0; z < resultImage.getDepth(); ++z)
680 for(int y = 0; y < resultImage.getHeight(); ++y)
681 for(int x = 0; x < resultImage.getWidth(); ++x)
683 const Vec4 difference = m_params.expectedColor - resultImage.getPixel(x,y,z);
684 if (abs(difference.x()) >= m_params.colorEpsilon || abs(difference.y()) >= m_params.colorEpsilon || abs(difference.z()) >= m_params.colorEpsilon)
687 msg << "Color value mismatch, expected: " << m_params.expectedColor << ", got: " << resultImage.getPixel(x,y,z) << " at " << "(" << x << ", " << y << ", " << z << ")";
688 return tcu::TestStatus::fail(msg.str());
695 const auto resultImage = m_depthTargetImage->readSurface(queue, m_context.getDefaultAllocator(), VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, { 0, 0, 0 }, WIDTH, HEIGHT, VK_IMAGE_ASPECT_DEPTH_BIT);
697 #ifdef CTS_USES_VULKANSC
698 if (m_context.getTestContext().getCommandLine().isSubProcess())
699 #endif // CTS_USES_VULKANSC
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)
705 const float difference = m_params.expectedDepth - resultImage.getPixDepth(x,y,z);
706 if (abs(difference) >= m_params.depthEpsilon)
709 msg << "Depth value mismatch, expected: " << m_params.expectedDepth << ", got: " << resultImage.getPixDepth(x,y,z) << " at " << "(" << x << ", " << y << ", " << z << ")";
710 return tcu::TestStatus::fail(msg.str());
715 return tcu::TestStatus::pass("Pass");
718 class MultipleClearsWithinRenderPassTest : public TestCase
721 MultipleClearsWithinRenderPassTest (tcu::TestContext& testCtx, const string& name, const string& description, const TestParams& params)
722 : TestCase(testCtx, name, description)
725 DE_ASSERT(m_params.steps.size() <= static_cast<size_t>(TEST_MAX_STEPS_COUNT));
728 virtual void initPrograms (SourceCollections& programCollection) const
732 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
734 << "layout(location = 0) in vec4 in_position;\n"
736 << "out gl_PerVertex {\n"
737 << " vec4 gl_Position;\n"
740 << "void main(void)\n"
742 << " gl_Position = in_position;\n"
744 programCollection.glslSources.add("vert") << glu::VertexSource(src.str());
748 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
750 << "layout(push_constant) uniform Color { vec4 color; } u_color;\n"
751 << "layout(location = 0) out vec4 out_color;\n"
753 << "void main(void)\n"
755 << " out_color = u_color.color;\n"
757 programCollection.glslSources.add("frag") << glu::FragmentSource(src.str());
761 src << glu::getGLSLVersionDeclaration(glu::GLSL_VERSION_450) << "\n"
763 << "layout(push_constant) uniform Color { vec4 color; } u_color;\n"
765 << "void main(void)\n"
768 programCollection.glslSources.add("frag_depthonly") << glu::FragmentSource(src.str());
772 virtual void checkSupport (Context& context) const
774 VkImageFormatProperties imageFormatProperties;
775 const auto& vki = context.getInstanceInterface();
776 const auto& vkd = context.getPhysicalDevice();
777 if (m_params.colorFormat != VK_FORMAT_UNDEFINED)
779 const auto colorUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
780 if (vki.getPhysicalDeviceImageFormatProperties(vkd, m_params.colorFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, colorUsage, 0u, &imageFormatProperties) != VK_SUCCESS)
781 TCU_THROW(NotSupportedError, "Color format not supported");
783 if (m_params.depthFormat != VK_FORMAT_UNDEFINED)
785 const auto depthUsage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
786 if (vki.getPhysicalDeviceImageFormatProperties(vkd, m_params.depthFormat, VK_IMAGE_TYPE_2D, VK_IMAGE_TILING_OPTIMAL, depthUsage, 0u, &imageFormatProperties) != VK_SUCCESS)
787 TCU_THROW(NotSupportedError, "Depth format not supported");
790 if (m_params.groupParams->useDynamicRendering)
791 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
794 virtual TestInstance* createInstance (Context& context) const
796 return new MultipleClearsTest(context, m_params);
800 const TestParams m_params;
805 MultipleClearsWithinRenderPassTests::MultipleClearsWithinRenderPassTests (tcu::TestContext &testCtx, const SharedGroupParams groupParams)
806 : TestCaseGroup (testCtx, "multiple_clears_within_render_pass", "Tests for multiple clears within render pass")
807 , m_groupParams (groupParams)
811 MultipleClearsWithinRenderPassTests::~MultipleClearsWithinRenderPassTests ()
815 void MultipleClearsWithinRenderPassTests::init ()
817 for(const auto &formatPair : formatsToTest)
819 ostringstream formatSuffix;
820 if (formatPair.colorFormat != VK_FORMAT_UNDEFINED)
821 formatSuffix << "_c" << de::toLower(string(getFormatName(formatPair.colorFormat)).substr(9));
822 if (formatPair.depthFormat != VK_FORMAT_UNDEFINED)
823 formatSuffix << "_d" << de::toLower(string(getFormatName(formatPair.depthFormat)).substr(9));
824 for(const auto &topology : topologiesToTest)
826 // reduce number of tests for dynamic rendering cases where secondary command buffer is used
827 if (m_groupParams->useSecondaryCmdBuffer && (topology != Topology::TRIANGLE_STRIP))
830 const string testNameSuffix = formatSuffix.str() + verticesByTopology[(deUint32)topology].testNameSuffix;
832 const TestParams params
834 formatPair.colorFormat, // VkFormat colorFormat;
835 formatPair.depthFormat, // VkFormat depthFormat;
836 topology, // Topology topology;
837 Vec4(0.0f, 0.5f, 0.5f, 1.0f), // Vec4 expectedColor;
838 0.01f, // float colorEpsilon;
839 0.9f, // float expectedDepth;
840 0.01f, // float depthEpsilon;
841 1u, // deUint32 repeatCount;
842 true, // bool enableBlend;
843 m_groupParams, // SharedGroupParams groupParams;
844 { // vector<ClearStep> steps;
845 { ClearOp::LOAD , Vec4(1.0f, 0.0f, 0.0f, 1.0f) , 0.7f },
846 { ClearOp::CLEAR , Vec4(0.0f, 1.0f, 0.0f, 1.0f) , 0.3f },
847 { ClearOp::DRAW , Vec4(0.0f, 0.0f, 1.0f, 0.5f) , 0.9f }
850 addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "load_clear_draw" + testNameSuffix, "Multiple clears within same render pass, methods: load, clear, draw", params));
853 const TestParams params
855 formatPair.colorFormat, // VkFormat format;
856 formatPair.depthFormat, // VkFormat depthFormat;
857 topology, // Topology topology;
858 Vec4(0.0f, 0.5f, 0.5f, 1.0f), // Vec4 expectedColor;
859 0.01f, // float colorEpsilon;
860 0.9f, // float expectedDepth;
861 0.01f, // float depthEpsilon;
862 1u, // deUint32 repeatCount;
863 true, // bool enableBlend;
864 m_groupParams, // SharedGroupParams groupParams;
865 { // vector<ClearStep> steps;
866 { ClearOp::DRAW , Vec4(1.0f, 0.0f, 0.0f, 1.0f) , 0.7f },
867 { ClearOp::CLEAR , Vec4(0.0f, 1.0f, 0.0f, 1.0f) , 0.3f },
868 { ClearOp::DRAW , Vec4(0.0f, 0.0f, 1.0f, 0.5f) , 0.9f }
871 addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "draw_clear_draw" + testNameSuffix, "Multiple clears within same render pass, methods: draw, clear, draw", params));
874 const TestParams params
876 formatPair.colorFormat, // VkFormat format;
877 formatPair.depthFormat, // VkFormat depthFormat;
878 topology, // Topology topology;
879 Vec4(0.0f, 0.5f, 0.5f, 1.0f), // Vec4 expectedColor;
880 0.01f, // float colorEpsilon;
881 0.9f, // float expectedDepth;
882 0.01f, // float depthEpsilon;
883 1u, // deUint32 repeatCount;
884 true, // bool enableBlend;
885 m_groupParams, // SharedGroupParams groupParams;
886 { // vector<ClearStep> steps;
887 { ClearOp::CLEAR , Vec4(1.0f, 0.0f, 0.0f, 1.0f) , 0.7f },
888 { ClearOp::CLEAR , Vec4(0.0f, 1.0f, 0.0f, 1.0f) , 0.3f },
889 { ClearOp::DRAW , Vec4(0.0f, 0.0f, 1.0f, 0.5f) , 0.9f }
892 addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "clear_clear_draw" + testNameSuffix, "Multiple clears within same render pass, methods: clear, clear, draw", params));
895 const TestParams params
897 formatPair.colorFormat, // VkFormat format;
898 formatPair.depthFormat, // VkFormat depthFormat;
899 topology, // Topology topology;
900 Vec4(0.0f, 1.0f, 0.0f, 1.0f), // Vec4 expectedColor;
901 0.01f, // float colorEpsilon;
902 0.9f, // float expectedDepth;
903 0.01f, // float depthEpsilon;
904 1u, // deUint32 repeatCount;
905 false, // bool enableBlend;
906 m_groupParams, // SharedGroupParams groupParams;
907 { // vector<ClearStep> steps;
908 { ClearOp::LOAD , Vec4(1.0f, 0.0f, 0.0f, 1.0f) , 0.3f },
909 { ClearOp::CLEAR , Vec4(0.0f, 1.0f, 0.0f, 1.0f) , 0.9f }
912 addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "load_clear" + testNameSuffix, "Multiple clears within same render pass, methods: load, clear", params));
915 const TestParams params
917 formatPair.colorFormat, // VkFormat format;
918 formatPair.depthFormat, // VkFormat depthFormat;
919 topology, // Topology topology;
920 Vec4(0.0f, 1.0f, 0.0f, 1.0f), // Vec4 expectedColor;
921 0.01f, // float colorEpsilon;
922 0.9f, // float expectedDepth;
923 0.01f, // float depthEpsilon;
924 1u, // deUint32 repeatCount;
925 false, // bool enableBlend;
926 m_groupParams, // SharedGroupParams groupParams;
927 { // vector<ClearStep> steps;
928 { ClearOp::DRAW , Vec4(1.0f, 0.0f, 0.0f, 1.0f) , 0.3f },
929 { ClearOp::CLEAR , Vec4(0.0f, 1.0f, 0.0f, 1.0f) , 0.9f }
932 addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "draw_clear" + testNameSuffix, "Multiple clears within same render pass, methods: draw, clear", params));
935 const TestParams params
937 formatPair.colorFormat, // VkFormat format;
938 formatPair.depthFormat, // VkFormat depthFormat;
939 topology, // Topology topology;
940 Vec4(0.0f, 1.0f, 0.0f, 1.0f), // Vec4 expectedColor;
941 0.01f, // float colorEpsilon;
942 0.9f, // float expectedDepth;
943 0.01f, // float depthEpsilon;
944 1u, // deUint32 repeatCount;
945 false, // bool enableBlend;
946 m_groupParams, // SharedGroupParams groupParams;
947 { // vector<ClearStep> steps;
948 { ClearOp::CLEAR , Vec4(1.0f, 0.0f, 0.0f, 1.0f) , 0.3f },
949 { ClearOp::CLEAR , Vec4(0.0f, 1.0f, 0.0f, 1.0f) , 0.9f }
952 addChild(new MultipleClearsWithinRenderPassTest(m_testCtx, "clear_clear" + testNameSuffix, "Multiple clears within same render pass, methods: clear, clear", params));