1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2021 The Khronos Group Inc.
6 * Copyright (c) 2021 Google 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 load and store op "none"
23 *//*--------------------------------------------------------------------*/
25 #include "vktRenderPassLoadStoreOpNoneTests.hpp"
26 #include "pipeline/vktPipelineImageUtil.hpp"
27 #include "vktTestCase.hpp"
28 #include "vkImageUtil.hpp"
29 #include "vkMemUtil.hpp"
30 #include "vkPrograms.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkCmdUtil.hpp"
34 #include "vkRefUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkObjUtil.hpp"
37 #include "tcuImageCompare.hpp"
38 #include "tcuPlatform.hpp"
39 #include "tcuTestLog.hpp"
40 #include "deStringUtil.hpp"
41 #include "deUniquePtr.hpp"
42 #include "deRandom.hpp"
59 ATTACHMENT_INIT_PRE = 1,
60 ATTACHMENT_INIT_CMD_CLEAR = 2
65 ATTACHMENT_USAGE_UNDEFINED = 0,
66 ATTACHMENT_USAGE_COLOR = 1,
67 ATTACHMENT_USAGE_DEPTH = 2,
68 ATTACHMENT_USAGE_STENCIL = 4,
69 ATTACHMENT_USAGE_INPUT = 8,
70 ATTACHMENT_USAGE_WRITE_OFF = 16,
71 ATTACHMENT_USAGE_DEPTH_STENCIL = ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_STENCIL
74 struct AttachmentParams
77 VkAttachmentLoadOp loadOp;
78 VkAttachmentStoreOp storeOp;
94 std::vector<AttachmentRef> attachmentRefs;
100 std::vector<AttachmentParams> attachments;
101 std::vector<SubpassParams> subpasses;
102 RenderPassType renderPassType;
113 inline de::SharedPtr<vk::Move<T> > makeSharedPtr(vk::Move<T> move)
115 return de::SharedPtr<vk::Move<T> >(new vk::Move<T>(move));
118 std::vector<Vertex4RGBA> createQuad (void)
120 std::vector<Vertex4RGBA> vertices;
122 const float size = 1.0f;
123 const tcu::Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
124 const tcu::Vec4 blue (0.0f, 0.0f, 1.0f, 1.0f);
125 const Vertex4RGBA lowerLeftVertexRed = {tcu::Vec4(-size, -size, 0.0f, 1.0f), red};
126 const Vertex4RGBA lowerRightVertexRed = {tcu::Vec4(size, -size, 0.0f, 1.0f), red};
127 const Vertex4RGBA upperLeftVertexRed = {tcu::Vec4(-size, size, 0.0f, 1.0f), red};
128 const Vertex4RGBA upperRightVertexRed = {tcu::Vec4(size, size, 0.0f, 1.0f), red};
129 const Vertex4RGBA lowerLeftVertexBlue = {tcu::Vec4(-size, -size, 0.0f, 1.0f), blue};
130 const Vertex4RGBA lowerRightVertexBlue = {tcu::Vec4(size, -size, 0.0f, 1.0f), blue};
131 const Vertex4RGBA upperLeftVertexBlue = {tcu::Vec4(-size, size, 0.0f, 1.0f), blue};
132 const Vertex4RGBA upperRightVertexBlue = {tcu::Vec4(size, size, 0.0f, 1.0f), blue};
134 vertices.push_back(lowerLeftVertexRed);
135 vertices.push_back(lowerRightVertexRed);
136 vertices.push_back(upperLeftVertexRed);
137 vertices.push_back(upperLeftVertexRed);
138 vertices.push_back(lowerRightVertexRed);
139 vertices.push_back(upperRightVertexRed);
141 vertices.push_back(lowerLeftVertexBlue);
142 vertices.push_back(lowerRightVertexBlue);
143 vertices.push_back(upperLeftVertexBlue);
144 vertices.push_back(upperLeftVertexBlue);
145 vertices.push_back(lowerRightVertexBlue);
146 vertices.push_back(upperRightVertexBlue);
151 deUint32 getFirstUsage (deUint32 attachmentIdx, const std::vector<SubpassParams>& subpasses)
153 for (const auto& subpass : subpasses)
154 for (const auto& ref : subpass.attachmentRefs)
155 if (ref.idx == attachmentIdx)
158 return ATTACHMENT_USAGE_UNDEFINED;
161 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
162 Move<VkRenderPass> createRenderPass (const DeviceInterface& vk,
164 const TestParams testParams)
166 const VkImageAspectFlags aspectMask = testParams.renderPassType == RENDERPASS_TYPE_LEGACY ? 0 : VK_IMAGE_ASPECT_COLOR_BIT;
167 const VkImageAspectFlags depthStencilAspectMask = testParams.renderPassType == RENDERPASS_TYPE_LEGACY ? 0 : VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
168 std::vector<AttachmentDesc> attachmentDescriptions;
169 std::vector<SubpassDesc> subpassDescriptions;
173 std::vector<AttachmentRef> colorAttachmentRefs;
174 std::vector<AttachmentRef> depthStencilAttachmentRefs;
175 std::vector<AttachmentRef> inputAttachmentRefs;
178 std::vector<Refs> subpassRefs;
179 bool hasInputAttachment = false;
181 for (size_t i = 0; i < testParams.attachments.size(); i++)
183 VkImageLayout initialLayout;
184 VkImageLayout finalLayout;
187 if (testParams.attachments[i].usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
189 format = VK_FORMAT_D24_UNORM_S8_UINT;
193 // Color and input attachments.
194 format = VK_FORMAT_R8G8B8A8_UNORM;
197 // Search for the first reference to determine the initial layout.
198 deUint32 firstUsage = getFirstUsage((deUint32)i, testParams.subpasses);
200 // No subpasses using this attachment. Use the usage flags of the attachment.
201 if (firstUsage == ATTACHMENT_USAGE_UNDEFINED)
202 firstUsage = testParams.attachments[i].usage;
204 if (firstUsage & ATTACHMENT_USAGE_COLOR)
205 initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
206 else if (firstUsage & ATTACHMENT_USAGE_DEPTH_STENCIL)
207 initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
210 DE_ASSERT(firstUsage & ATTACHMENT_USAGE_INPUT);
211 initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
214 // Set final layout to transfer src if it's being verified. Otherwise
215 // just use the initial layout as it's known to be supported by
217 if (testParams.attachments[i].verifyInner || testParams.attachments[i].verifyOuter)
218 finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
220 finalLayout = initialLayout;
222 const AttachmentDesc attachmentDesc =
224 DE_NULL, // const void* pNext
225 (VkAttachmentDescriptionFlags) 0, // VkAttachmentDescriptionFlags flags
226 format, // VkFormat format
227 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
228 testParams.attachments[i].loadOp, // VkAttachmentLoadOp loadOp
229 testParams.attachments[i].storeOp, // VkAttachmentStoreOp storeOp
230 testParams.attachments[i].loadOp, // VkAttachmentLoadOp stencilLoadOp
231 testParams.attachments[i].storeOp, // VkAttachmentStoreOp stencilStoreOp
232 initialLayout, // VkImageLayout initialLayout
233 finalLayout // VkImageLayout finalLayout
236 attachmentDescriptions.push_back(attachmentDesc);
239 for (const auto& subpass : testParams.subpasses)
241 subpassRefs.push_back({});
242 auto& refs = subpassRefs.back();
244 for (const auto& ref : subpass.attachmentRefs)
246 VkImageLayout layout;
248 if (ref.usage & ATTACHMENT_USAGE_COLOR)
250 layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
251 refs.colorAttachmentRefs.push_back({DE_NULL, ref.idx, layout, aspectMask});
253 else if (ref.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
255 layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
256 refs.depthStencilAttachmentRefs.push_back({DE_NULL, ref.idx, layout, depthStencilAspectMask});
260 DE_ASSERT(ref.usage & ATTACHMENT_USAGE_INPUT);
261 layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
262 refs.inputAttachmentRefs.push_back({DE_NULL, ref.idx, layout, aspectMask});
263 hasInputAttachment = true;
267 const SubpassDesc subpassDescription =
270 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
271 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
272 0u, // deUint32 viewMask
273 (deUint32)refs.inputAttachmentRefs.size(), // deUint32 inputAttachmentCount
274 refs.inputAttachmentRefs.empty() ? DE_NULL : refs.inputAttachmentRefs.data(), // const VkAttachmentReference* pInputAttachments
275 (deUint32)refs.colorAttachmentRefs.size(), // deUint32 colorAttachmentCount
276 refs.colorAttachmentRefs.empty() ? DE_NULL : refs.colorAttachmentRefs.data(), // const VkAttachmentReference* pColorAttachments
277 DE_NULL, // const VkAttachmentReference* pResolveAttachments
278 refs.depthStencilAttachmentRefs.empty() ? DE_NULL : refs.depthStencilAttachmentRefs.data(), // const VkAttachmentReference* pDepthStencilAttachment
279 0u, // deUint32 preserveAttachmentCount
280 DE_NULL // const deUint32* pPreserveAttachments
283 subpassDescriptions.push_back(subpassDescription);
286 // Dependency of color attachment of subpass 0 to input attachment of subpass 1.
287 // Determined later if it's being used.
288 const SubpassDep subpassDependency =
290 DE_NULL, // const void* pNext
291 0u, // uint32_t srcSubpass
292 1u, // uint32_t dstSubpass
293 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
294 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask
295 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
296 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask
297 VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags
298 0u // deInt32 viewOffset
301 const RenderPassCreateInfo renderPassInfo =
303 DE_NULL, // const void* pNext
304 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
305 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount
306 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments
307 (deUint32)subpassDescriptions.size(), // deUint32 subpassCount
308 subpassDescriptions.data(), // const VkSubpassDescription* pSubpasses
309 hasInputAttachment ? 1u : 0u, // deUint32 dependencyCount
310 hasInputAttachment ? &subpassDependency : DE_NULL, // const VkSubpassDependency* pDependencies
311 0u, // deUint32 correlatedViewMaskCount
312 DE_NULL // const deUint32* pCorrelatedViewMasks
315 return renderPassInfo.createRenderPass(vk, vkDevice);
318 class LoadStoreOpNoneTest : public vkt::TestCase
321 LoadStoreOpNoneTest (tcu::TestContext& testContext,
322 const std::string& name,
323 const std::string& description,
324 const TestParams& testParams);
325 virtual ~LoadStoreOpNoneTest (void);
326 virtual void initPrograms (SourceCollections& sourceCollections) const;
327 virtual void checkSupport (Context& context) const;
328 virtual TestInstance* createInstance (Context& context) const;
330 const TestParams m_testParams;
333 class LoadStoreOpNoneTestInstance : public vkt::TestInstance
336 LoadStoreOpNoneTestInstance (Context& context,
337 const TestParams& testParams);
338 virtual ~LoadStoreOpNoneTestInstance (void);
339 virtual tcu::TestStatus iterate (void);
340 template<typename RenderpassSubpass>
341 void createCommandBuffer (const DeviceInterface& vk,
343 std::vector<Move<VkDescriptorSet>>& descriptorSets,
344 std::vector<Move<VkPipelineLayout>>& pipelineLayouts,
345 std::vector<Move<VkPipeline>>& pipelines);
347 TestParams m_testParams;
349 const tcu::UVec2 m_imageSize;
350 const tcu::UVec2 m_renderSize;
352 Move<VkDescriptorPool> m_descriptorPool;
353 Move<VkRenderPass> m_renderPass;
354 Move<VkFramebuffer> m_framebuffer;
356 Move<VkBuffer> m_vertexBuffer;
357 std::vector<Vertex4RGBA> m_vertices;
358 de::MovePtr<Allocation> m_vertexBufferAlloc;
360 Move<VkCommandPool> m_cmdPool;
361 Move<VkCommandBuffer> m_cmdBuffer;
364 LoadStoreOpNoneTest::LoadStoreOpNoneTest (tcu::TestContext& testContext,
365 const std::string& name,
366 const std::string& description,
367 const TestParams& testParams)
368 : vkt::TestCase (testContext, name, description)
369 , m_testParams(testParams)
373 LoadStoreOpNoneTest::~LoadStoreOpNoneTest (void)
377 TestInstance* LoadStoreOpNoneTest::createInstance (Context& context) const
379 return new LoadStoreOpNoneTestInstance(context, m_testParams);
382 void LoadStoreOpNoneTest::checkSupport (Context& ctx) const
384 // Check for renderpass2 extension if used.
385 if (m_testParams.renderPassType == RENDERPASS_TYPE_RENDERPASS2)
386 ctx.requireDeviceFunctionality("VK_KHR_create_renderpass2");
388 ctx.requireDeviceFunctionality("VK_EXT_load_store_op_none");
391 void LoadStoreOpNoneTest::initPrograms (SourceCollections& sourceCollections) const
393 std::ostringstream fragmentSource;
395 sourceCollections.glslSources.add("color_vert") << glu::VertexSource(
397 "layout(location = 0) in highp vec4 position;\n"
398 "layout(location = 1) in highp vec4 color;\n"
399 "layout(location = 0) out highp vec4 vtxColor;\n"
402 " gl_Position = position;\n"
403 " vtxColor = color;\n"
406 sourceCollections.glslSources.add("color_frag") << glu::FragmentSource(
408 "layout(location = 0) in highp vec4 vtxColor;\n"
409 "layout(location = 0) out highp vec4 fragColor;\n"
412 " fragColor = vtxColor;\n"
413 " gl_FragDepth = 1.0;\n"
416 sourceCollections.glslSources.add("color_frag_blend") << glu::FragmentSource(
418 "layout(location = 0) in highp vec4 vtxColor;\n"
419 "layout(location = 0) out highp vec4 fragColor;\n"
422 " fragColor = vec4(vtxColor.rgb, 0.5);\n"
423 " gl_FragDepth = 1.0;\n"
426 sourceCollections.glslSources.add("color_frag_input") << glu::FragmentSource(
428 "layout(location = 0) in highp vec4 vtxColor;\n"
429 "layout(location = 0) out highp vec4 fragColor;\n"
430 "layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput inputColor;"
433 " fragColor = subpassLoad(inputColor) + vtxColor;\n"
434 " gl_FragDepth = 1.0;\n"
438 LoadStoreOpNoneTestInstance::LoadStoreOpNoneTestInstance (Context& context,
439 const TestParams& testParams)
440 : vkt::TestInstance (context)
441 , m_testParams (testParams)
442 , m_imageSize (32u, 32u)
443 , m_renderSize (27u, 19u)
444 , m_vertices (createQuad())
448 LoadStoreOpNoneTestInstance::~LoadStoreOpNoneTestInstance (void)
452 template<typename RenderpassSubpass>
453 void LoadStoreOpNoneTestInstance::createCommandBuffer (const DeviceInterface& vk,
455 std::vector<Move<VkDescriptorSet>>& descriptorSets,
456 std::vector<Move<VkPipelineLayout>>& pipelineLayouts,
457 std::vector<Move<VkPipeline>>& pipelines)
459 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
460 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
462 const VkDeviceSize vertexBufferOffset = 0;
464 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
466 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
468 const VkRenderPassBeginInfo renderPassBeginInfo =
470 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
471 DE_NULL, // const void* pNext
472 *m_renderPass, // VkRenderPass renderPass
473 *m_framebuffer, // VkFramebuffer framebuffer
474 makeRect2D(m_renderSize), // VkRect2D renderArea
475 0u, // uint32_t clearValueCount
476 DE_NULL // const VkClearValue* pClearValues
478 RenderpassSubpass::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfo, &subpassBeginInfo);
480 // Add clear commands for selected attachments
481 std::vector<VkClearAttachment> clearAttachments;
482 deUint32 colorAttIdx = 0u;
483 for (const auto& att : m_testParams.attachments)
485 if (att.init & ATTACHMENT_INIT_CMD_CLEAR)
487 if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
489 clearAttachments.push_back({VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT, 0u,
490 makeClearValueDepthStencil(0.25, 64)});
494 clearAttachments.push_back({VK_IMAGE_ASPECT_COLOR_BIT, colorAttIdx++,
495 makeClearValueColorF32(0.0f, 0.0f, 0.5f, 1.0f)});
499 if (!clearAttachments.empty())
501 VkClearRect rect = { makeRect2D(m_renderSize), 0u, 1u };
502 vk.cmdClearAttachments(*m_cmdBuffer, (deUint32) clearAttachments.size(), clearAttachments.data(), 1u, &rect);
505 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
507 deUint32 descriptorSetIdx = 0u;
508 deUint32 vertexOffset = 0u;
509 for (size_t i = 0; i < m_testParams.subpasses.size(); i++)
512 vk.cmdNextSubpass(*m_cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
514 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelines[i]);
516 bool hasInput = false;
517 for (const auto &ref : m_testParams.subpasses[i].attachmentRefs)
518 if (ref.usage & ATTACHMENT_USAGE_INPUT)
522 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayouts[i], 0, 1,
523 &descriptorSets[descriptorSetIdx++].get(), 0, DE_NULL);
525 for (deUint32 d = 0; d < m_testParams.subpasses[i].numDraws; d++)
527 vk.cmdDraw(*m_cmdBuffer, 6u, 1, vertexOffset, 0);
531 RenderpassSubpass::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
532 endCommandBuffer(vk, *m_cmdBuffer);
535 tcu::TestStatus LoadStoreOpNoneTestInstance::iterate (void)
537 const DeviceInterface& vk = m_context.getDeviceInterface();
538 const VkDevice vkDevice = m_context.getDevice();
539 const VkQueue queue = m_context.getUniversalQueue();
540 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
541 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
542 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
544 std::vector<Move<VkImage>> attachmentImages;
545 std::vector<de::MovePtr<Allocation>> attachmentImageAllocs;
546 std::vector<Move<VkImageView>> imageViews;
547 std::vector<Move<VkPipeline>> pipelines;
549 for (const auto& att : m_testParams.attachments)
552 VkImageUsageFlags usage = 0;
553 VkImageAspectFlags aspectFlags;
555 if (att.verifyInner || att.verifyOuter) usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
556 if (att.init & ATTACHMENT_INIT_PRE) usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
557 if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
559 format = VK_FORMAT_D24_UNORM_S8_UINT;
560 aspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT;
561 usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
565 // Color and input attachments.
566 format = VK_FORMAT_R8G8B8A8_UNORM;
567 aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
569 if (att.usage & ATTACHMENT_USAGE_COLOR)
570 usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
571 if (att.usage & ATTACHMENT_USAGE_INPUT)
572 usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
575 const VkImageCreateInfo imageParams =
577 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
578 DE_NULL, // const void* pNext
579 0u, // VkImageCreateFlags flags
580 VK_IMAGE_TYPE_2D, // VkImageType imageType
581 format, // VkFormat format
582 { m_imageSize.x(), m_imageSize.y(), 1u }, // VkExtent3D extent
583 1u, // deUint32 mipLevels
584 1u, // deUint32 arrayLayers
585 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples
586 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
587 usage, // VkImageUsageFlags usage
588 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
589 1u, // deUint32 queueFamilyIndexCount
590 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices
591 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
594 attachmentImages.push_back(createImage(vk, vkDevice, &imageParams));
596 // Allocate and bind image memory.
597 attachmentImageAllocs.push_back(memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *attachmentImages.back()), MemoryRequirement::Any));
598 VK_CHECK(vk.bindImageMemory(vkDevice, *attachmentImages.back(), attachmentImageAllocs.back()->getMemory(), attachmentImageAllocs.back()->getOffset()));
600 // Create image view.
601 const VkImageViewCreateInfo imageViewParams =
603 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
604 DE_NULL, // const void* pNext
605 0u, // VkImageViewCreateFlags flags
606 *attachmentImages.back(), // VkImage image
607 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
608 format, // VkFormat format
609 componentMappingRGBA, // VkChannelMapping channels
610 { aspectFlags, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange
613 imageViews.push_back(createImageView(vk, vkDevice, &imageViewParams));
615 if (att.init & ATTACHMENT_INIT_PRE)
617 // Preinitialize image
618 deUint32 firstUsage = getFirstUsage((deUint32)attachmentImages.size() - 1, m_testParams.subpasses);
619 if (firstUsage == ATTACHMENT_USAGE_UNDEFINED)
620 firstUsage = att.usage;
622 if (firstUsage & ATTACHMENT_USAGE_DEPTH_STENCIL)
624 clearDepthStencilImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), 0.5f, 128u,
625 VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
626 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
630 clearColorImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f),
631 VK_IMAGE_LAYOUT_UNDEFINED, firstUsage & ATTACHMENT_USAGE_COLOR ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
632 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
637 // Create render pass.
638 if (m_testParams.renderPassType == RENDERPASS_TYPE_LEGACY)
639 m_renderPass = createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vk, vkDevice, m_testParams);
641 m_renderPass = createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice, m_testParams);
643 // Create framebuffer.
645 std::vector<VkImageView> views;
646 for (const auto& view : imageViews)
647 views.push_back(*view);
649 const VkFramebufferCreateInfo framebufferParams =
651 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
652 DE_NULL, // const void* pNext
653 0u, // VkFramebufferCreateFlags flags
654 *m_renderPass, // VkRenderPass renderPass
655 (deUint32)views.size(), // deUint32 attachmentCount
656 views.data(), // const VkImageView* pAttachments
657 (deUint32)m_imageSize.x(), // deUint32 width
658 (deUint32)m_imageSize.y(), // deUint32 height
659 1u // deUint32 layers
662 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
665 // Create shader modules
666 Unique<VkShaderModule> vertexShaderModule (createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0));
667 Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0));
668 Unique<VkShaderModule> fragmentShaderModuleBlend (createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_blend"), 0));
669 Unique<VkShaderModule> fragmentShaderModuleInput (createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_input"), 0));
671 // Create descriptor pool. Prepare for using one input attachment at most.
673 const VkDescriptorPoolSize descriptorPoolSize =
675 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType type
676 1u // deUint32 descriptorCount
679 const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo =
681 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType
682 DE_NULL, // const void* pNext
683 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags
684 1u, // deUint32 maxSets
685 1u, // deUint32 poolSizeCount
686 &descriptorPoolSize // const VkDescriptorPoolSize* pPoolSizes
689 m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
692 std::vector<Move<VkDescriptorSetLayout>> descriptorSetLayouts;
693 std::vector<Move<VkDescriptorSet>> descriptorSets;
694 std::vector<Move<VkPipelineLayout>> pipelineLayouts;
696 for (const auto& subpass : m_testParams.subpasses)
698 deUint32 numInputAttachments = 0u;
699 bool noColorWrite = false;
700 bool depthTest = false;
701 bool stencilTest = false;
703 // Create pipeline layout.
705 std::vector<VkDescriptorSetLayoutBinding> layoutBindings;
707 for (const auto ref : subpass.attachmentRefs)
709 if (ref.usage & ATTACHMENT_USAGE_INPUT)
711 const VkDescriptorSetLayoutBinding layoutBinding =
713 0u, // deUint32 binding
714 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType
715 1u, // deUint32 descriptorCount
716 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags
717 DE_NULL // const VkSampler* pImmutableSamplers
720 layoutBindings.push_back(layoutBinding);
721 numInputAttachments++;
723 if (ref.usage & ATTACHMENT_USAGE_COLOR)
725 if (ref.usage & ATTACHMENT_USAGE_WRITE_OFF)
728 if (ref.usage & ATTACHMENT_USAGE_DEPTH)
730 if (!(ref.usage & ATTACHMENT_USAGE_WRITE_OFF))
733 if (ref.usage & ATTACHMENT_USAGE_STENCIL)
735 if (!(ref.usage & ATTACHMENT_USAGE_WRITE_OFF))
740 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutParams =
742 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
743 DE_NULL, // const void* pNext
744 0u, // VkDescriptorSetLayoutCreateFlags flags
745 (deUint32) layoutBindings.size(), // deUint32 bindingCount
746 layoutBindings.empty() ? DE_NULL : layoutBindings.data() // const VkDescriptorSetLayoutBinding* pBindings
748 descriptorSetLayouts.push_back(createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams));
750 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
752 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType
753 DE_NULL, // const void* pNext
754 0u, // VkPipelineLayoutCreateFlags flags
755 1u, // deUint32 setLayoutCount
756 &descriptorSetLayouts.back().get(), // const VkDescriptorSetLayout* pSetLayouts
757 0u, // deUint32 pushConstantRangeCount
758 DE_NULL // const VkPushConstantRange* pPushConstantRanges
761 pipelineLayouts.push_back(createPipelineLayout(vk, vkDevice, &pipelineLayoutParams));
764 // Update descriptor set if needed.
765 if (numInputAttachments > 0u)
767 // Assuming there's only one input attachment at most.
768 DE_ASSERT(numInputAttachments == 1u);
771 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
773 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
774 DE_NULL, // const void* pNext
775 *m_descriptorPool, // VkDescriptorPool descriptorPool
776 1u, // deUint32 descriptorSetCount
777 &descriptorSetLayouts.back().get(), // const VkDescriptorSetLayout* pSetLayouts
780 descriptorSets.push_back(allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo));
782 for (size_t i = 0; i < imageViews.size(); i++)
784 if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INPUT)
786 const VkDescriptorImageInfo inputImageInfo =
788 DE_NULL, // VkSampler sampler
789 *imageViews[i], // VkImageView imageView
790 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout
793 const VkWriteDescriptorSet descriptorWrite =
795 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
796 DE_NULL, // const void* pNext
797 *descriptorSets.back(), // VkDescriptorSet dstSet
798 0u, // deUint32 dstBinding
799 0u, // deUint32 dstArrayElement
800 1u, // deUint32 descriptorCount
801 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType
802 &inputImageInfo, // const VkDescriptorImageInfo* pImageInfo
803 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo
804 DE_NULL // const VkBufferView* pTexelBufferView
806 vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
813 const VkVertexInputBindingDescription vertexInputBindingDescription =
815 0u, // deUint32 binding
816 (deUint32)sizeof(Vertex4RGBA), // deUint32 strideInBytes
817 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate
820 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
823 0u, // deUint32 location
824 0u, // deUint32 binding
825 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
826 0u // deUint32 offset
829 1u, // deUint32 location
830 0u, // deUint32 binding
831 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
832 (deUint32)(sizeof(float) * 4), // deUint32 offset
836 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
838 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
839 DE_NULL, // const void* pNext
840 0u, // VkPipelineVertexInputStateCreateFlags flags
841 1u, // deUint32 vertexBindingDescriptionCount
842 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
843 2u, // deUint32 vertexAttributeDescriptionCount
844 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
847 const VkColorComponentFlags writeMask = noColorWrite ? 0 : VK_COLOR_COMPONENT_R_BIT // VkColorComponentFlags colorWriteMask
848 | VK_COLOR_COMPONENT_G_BIT
849 | VK_COLOR_COMPONENT_B_BIT
850 | VK_COLOR_COMPONENT_A_BIT;
852 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
854 m_testParams.alphaBlend, // VkBool32 blendEnable
855 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor
856 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor
857 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
858 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor
859 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor
860 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
861 writeMask // VkColorComponentFlags colorWriteMask
864 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
866 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
867 DE_NULL, // const void* pNext
868 0u, // VkPipelineColorBlendStateCreateFlags flags
869 VK_FALSE, // VkBool32 logicOpEnable
870 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp
871 1u, // deUint32 attachmentCount
872 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments
873 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4]
876 const VkStencilOpState stencilOpState =
878 VK_STENCIL_OP_KEEP, // VkStencilOp failOp
879 VK_STENCIL_OP_REPLACE, // VkStencilOp passOp
880 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp
881 VK_COMPARE_OP_GREATER, // VkCompareOp compareOp
882 0xff, // deUint32 compareMask
883 0xff, // deUint32 writeMask
884 0xff // deUint32 reference
887 const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
889 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
890 DE_NULL, // const void* pNext
891 0u, // VkPipelineDepthStencilStateCreateFlags flags
892 depthTest, // VkBool32 depthTestEnable
893 VK_TRUE, // VkBool32 depthWriteEnable
894 VK_COMPARE_OP_GREATER, // VkCompareOp depthCompareOp
895 VK_FALSE, // VkBool32 depthBoundsTestEnable
896 stencilTest, // VkBool32 stencilTestEnable
897 stencilOpState, // VkStencilOpState front
898 stencilOpState, // VkStencilOpState back
899 0.0f, // float minDepthBounds
900 1.0f, // float maxDepthBounds
903 const std::vector<VkViewport> viewports (1, makeViewport(m_imageSize));
904 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize));
905 VkShaderModule fragShader = *fragmentShaderModule;
907 if (numInputAttachments > 0u)
908 fragShader = *fragmentShaderModuleInput;
909 else if (m_testParams.alphaBlend)
910 fragShader = *fragmentShaderModuleBlend;
912 pipelines.push_back(makeGraphicsPipeline(
913 vk, // const DeviceInterface& vk
914 vkDevice, // const VkDevice device
915 *pipelineLayouts.back(), // const VkPipelineLayout pipelineLayout
916 *vertexShaderModule, // const VkShaderModule vertexShaderModule
917 DE_NULL, // const VkShaderModule tessellationControlModule
918 DE_NULL, // const VkShaderModule tessellationEvalModule
919 DE_NULL, // const VkShaderModule geometryShaderModule
920 fragShader, // const VkShaderModule fragmentShaderModule
921 *m_renderPass, // const VkRenderPass renderPass
922 viewports, // const std::vector<VkViewport>& viewports
923 scissors, // const std::vector<VkRect2D>& scissors
924 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
925 (deUint32)pipelines.size(), // const deUint32 subpass
926 0u, // const deUint32 patchControlPoints
927 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
928 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
929 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
930 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
931 &colorBlendStateParams)); // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
935 // Create vertex buffer.
937 const VkBufferCreateInfo vertexBufferParams =
939 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
940 DE_NULL, // const void* pNext
941 0u, // VkBufferCreateFlags flags
942 (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()), // VkDeviceSize size
943 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage
944 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
945 1u, // deUint32 queueFamilyIndexCount
946 &queueFamilyIndex // const deUint32* pQueueFamilyIndices
949 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
950 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
952 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
954 // Upload vertex data.
955 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
956 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
959 // Create command pool.
960 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
962 // Create command buffer.
963 if (m_testParams.renderPassType == RENDERPASS_TYPE_LEGACY)
964 createCommandBuffer<RenderpassSubpass1>(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines);
966 createCommandBuffer<RenderpassSubpass2>(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines);
969 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
973 // Verify selected attachments.
974 for (size_t i = 0; i < m_testParams.attachments.size(); i++)
976 if (m_testParams.attachments[i].verifyInner || m_testParams.attachments[i].verifyOuter)
978 de::MovePtr<tcu::TextureLevel> textureLevelResult;
980 SimpleAllocator allocator (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
982 if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_DEPTH)
984 textureLevelResult = pipeline::readDepthAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], VK_FORMAT_D24_UNORM_S8_UINT, m_imageSize, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
986 else if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_STENCIL)
988 textureLevelResult = pipeline::readStencilAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], VK_FORMAT_D24_UNORM_S8_UINT, m_imageSize, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
992 textureLevelResult = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i], VK_FORMAT_R8G8B8A8_UNORM, m_imageSize, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
995 const tcu::ConstPixelBufferAccess& access = textureLevelResult->getAccess();
997 // Log attachment contents
998 m_context.getTestContext().getLog() << tcu::TestLog::ImageSet("Attachment " + de::toString(i), "")
999 << tcu::TestLog::Image("Attachment " + de::toString(i), "", access)
1000 << tcu::TestLog::EndImageSet;
1002 for (int y = 0; y < access.getHeight(); y++)
1003 for (int x = 0; x < access.getWidth(); x++)
1005 const bool inner = x < (int)m_renderSize.x() && y < (int)m_renderSize.y();
1007 if (inner && !m_testParams.attachments[i].verifyInner)
1009 if (!inner && !m_testParams.attachments[i].verifyOuter)
1012 const tcu::Vec4 ref = inner ? m_testParams.attachments[i].innerRef : m_testParams.attachments[i].outerRef;
1013 const tcu::Vec4 p = access.getPixel(x, y);
1015 for (int c = 0; c < 4; c++)
1016 if (fabs(p[c] - ref[c]) > 0.01f)
1024 return tcu::TestStatus::pass("Pass");
1026 return tcu::TestStatus::fail("Fail");
1031 tcu::TestCaseGroup* createRenderPassLoadStoreOpNoneTests (tcu::TestContext& testCtx, const RenderPassType renderPassType)
1033 de::MovePtr<tcu::TestCaseGroup> opNoneTests (new tcu::TestCaseGroup(testCtx, "load_store_op_none", ""));
1035 const tcu::Vec4 red (1.0f, 0.0f, 0.0f, 1.0f);
1036 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
1037 const tcu::Vec4 magenta (1.0f, 0.0f, 1.0f, 1.0f);
1038 const tcu::Vec4 darkBlue (0.0f, 0.0f, 0.5f, 1.0f);
1039 const tcu::Vec4 blend (0.5f, 0.0f, 0.25f, 0.5f);
1040 const tcu::Vec4 depthInit (0.5f, 0.0f, 0.0f, 1.0f);
1041 const tcu::Vec4 depthFull (1.0f, 0.0f, 0.0f, 1.0f);
1042 const tcu::Vec4 stencilInit (128.0f, 0.0f, 0.0f, 1.0f);
1043 const tcu::Vec4 stencilFull (255.0f, 0.0f, 0.0f, 1.0f);
1045 // Preinitialize attachments 0 and 1 to green.
1046 // Subpass 0: draw a red rectangle inside attachment 0.
1047 // Subpass 1: use the attachment 0 as input and add blue channel to it resulting in magenta. Write the results to
1049 // After the render pass attachment 0 has undefined values inside the render area because of the shader writes with
1050 // store op 'none', but outside should still have the preinitialized value of green. Attachment 1 should have the
1051 // preinitialized green outside the render area and magenta inside.
1054 params.alphaBlend = false;
1055 params.renderPassType = renderPassType;
1056 params.attachments.push_back({ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT,
1057 VK_ATTACHMENT_LOAD_OP_LOAD,
1058 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1059 ATTACHMENT_INIT_PRE,
1062 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1063 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1064 VK_ATTACHMENT_STORE_OP_STORE,
1065 ATTACHMENT_INIT_PRE,
1068 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 1u});
1069 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u});
1071 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_load_store_op_none", "", params));
1074 // Preinitialize color attachment to green. Use a render pass with load and store ops none, but
1075 // disable color writes using an empty color mask. The color attachment image should have the original
1076 // preinitialized value after the render pass.
1079 params.alphaBlend = false;
1080 params.renderPassType = renderPassType;
1081 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1082 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1083 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1084 ATTACHMENT_INIT_PRE,
1087 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_WRITE_OFF}}, 1u});
1089 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none_write_off", "", params));
1092 // Preinitialize color attachment to green. Use a render pass with load and store ops none, and
1093 // write a rectange to the color buffer. The render area is undefined, but the outside area should
1094 // still have the preinitialized color.
1097 params.alphaBlend = false;
1098 params.renderPassType = renderPassType;
1099 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1100 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1101 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1102 ATTACHMENT_INIT_PRE,
1105 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 1u});
1107 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none", "", params));
1110 // Preinitialize color attachment to green. Use a subpass with no draw calls but instead
1111 // do an attachment clear command using dark blue color. Using load op none preserves the preinitialized
1112 // data and store op store causes the cleared blue render area to be present after the render pass.
1115 params.alphaBlend = false;
1116 params.renderPassType = renderPassType;
1117 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1118 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1119 VK_ATTACHMENT_STORE_OP_STORE,
1120 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1123 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 0u});
1125 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store", "", params));
1128 // Preinitialize color attachment to green. Use a subpass with a dark blue attachment clear followed
1129 // by an alpha blender draw. Load op is none preserves the preinitialized data and store op store
1130 // keeps the blended color inside the render area after the render pass.
1133 params.alphaBlend = true;
1134 params.renderPassType = renderPassType;
1135 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1136 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1137 VK_ATTACHMENT_STORE_OP_STORE,
1138 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1141 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 1u});
1143 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store_alphablend", "", params));
1146 // Preinitialize attachments 0 and 1 to green. Attachment 0 contents inside render area is undefined because load op 'none'.
1147 // Subpass 0: draw a red rectangle inside attachment 0 overwriting all undefined values.
1148 // Subpass 1: use the attachment 0 as input and add blue to it resulting in magenta. Write the results to attachment 1.
1149 // After the render pass attachment 0 contents inside the render area are undefined because of store op 'don't care',
1150 // but the outside area should still have the preinitialized content.
1151 // Attachment 1 should have the preinitialized green outside render area and magenta inside.
1154 params.alphaBlend = false;
1155 params.renderPassType = renderPassType;
1156 params.attachments.push_back({ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT,
1157 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1158 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1159 ATTACHMENT_INIT_PRE,
1162 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1163 VK_ATTACHMENT_LOAD_OP_LOAD,
1164 VK_ATTACHMENT_STORE_OP_STORE,
1165 ATTACHMENT_INIT_PRE,
1168 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}}, 1u});
1169 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u});
1171 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_dontcare", "", params));
1174 // Preinitialize attachment 0 (color) to green and attachment 1 (depth) to 0.5.
1175 // Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update
1176 // depth buffer to 1.0.
1177 // This is followed by another draw with a blue rectangle using the same depth of 1.0. This time
1178 // the depth test fails and nothing is written.
1179 // After the renderpass the red color should remain inside the render area of the color buffer.
1180 // Store op 'store' for depth buffer makes the written values undefined, but the pixels outside
1181 // render area should still contain the original value of 0.5.
1184 params.alphaBlend = false;
1185 params.renderPassType = renderPassType;
1186 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1187 VK_ATTACHMENT_LOAD_OP_LOAD,
1188 VK_ATTACHMENT_STORE_OP_STORE,
1189 ATTACHMENT_INIT_PRE,
1192 params.attachments.push_back({ATTACHMENT_USAGE_DEPTH,
1193 VK_ATTACHMENT_LOAD_OP_LOAD,
1194 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1195 ATTACHMENT_INIT_PRE,
1198 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 2u});
1200 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_load_op_load_store_op_none", "", params));
1203 // Preinitialize depth attachment to 0.5. Use a render pass with load and store ops none for the depth, but
1204 // disable depth test which also disables depth writes. The depth attachment should have the original
1205 // preinitialized value after the render pass.
1208 params.alphaBlend = false;
1209 params.renderPassType = renderPassType;
1210 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1211 VK_ATTACHMENT_LOAD_OP_LOAD,
1212 VK_ATTACHMENT_STORE_OP_STORE,
1213 ATTACHMENT_INIT_PRE,
1216 params.attachments.push_back({ATTACHMENT_USAGE_DEPTH,
1217 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1218 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1219 ATTACHMENT_INIT_PRE,
1222 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_WRITE_OFF}}, 1u});
1224 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_load_op_none_store_op_none_write_off", "", params));
1227 // Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25
1228 // using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update
1229 // depth buffer to 1.0. After the renderpass the color buffer should have red inside the render area and depth should have the
1230 // shader updated value of 1.0.
1233 params.alphaBlend = false;
1234 params.renderPassType = renderPassType;
1235 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1236 VK_ATTACHMENT_LOAD_OP_LOAD,
1237 VK_ATTACHMENT_STORE_OP_STORE,
1238 ATTACHMENT_INIT_PRE,
1241 params.attachments.push_back({ATTACHMENT_USAGE_DEPTH,
1242 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1243 VK_ATTACHMENT_STORE_OP_STORE,
1244 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1247 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u});
1249 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_load_op_none_store_op_store", "", params));
1252 // Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25
1253 // using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater' which will pass.
1254 // After the renderpass the color buffer should have red inside the render area. Depth buffer contents inside render
1255 // are is undefined because of store op 'don't care', but the outside should have the original value of 0.5.
1258 params.alphaBlend = false;
1259 params.renderPassType = renderPassType;
1260 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1261 VK_ATTACHMENT_LOAD_OP_LOAD,
1262 VK_ATTACHMENT_STORE_OP_STORE,
1263 ATTACHMENT_INIT_PRE,
1266 params.attachments.push_back({ATTACHMENT_USAGE_DEPTH,
1267 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1268 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1269 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1272 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u});
1274 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "depth_load_op_none_store_op_dontcare", "", params));
1277 // Preinitialize attachment 0 (color) to green and attachment 1 (stencil) to 128.
1278 // Draw a red rectangle using stencil testing with compare op 'greater' and reference of 255. The stencil test
1279 // will pass. This is followed by another draw with a blue rectangle using the same stencil settings. This time
1280 // the stencil test fails and nothing is written.
1281 // After the renderpass the red color should remain inside the render area of the color buffer.
1282 // Store op 'store' for stencil buffer makes the written values undefined, but the pixels outside
1283 // render area should still contain the original value of 128.
1286 params.alphaBlend = false;
1287 params.renderPassType = renderPassType;
1288 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1289 VK_ATTACHMENT_LOAD_OP_LOAD,
1290 VK_ATTACHMENT_STORE_OP_STORE,
1291 ATTACHMENT_INIT_PRE,
1294 params.attachments.push_back({ATTACHMENT_USAGE_STENCIL,
1295 VK_ATTACHMENT_LOAD_OP_LOAD,
1296 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1297 ATTACHMENT_INIT_PRE,
1299 true, stencilInit});
1300 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 2u});
1302 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_load_op_load_store_op_none", "", params));
1305 // Preinitialize stencil attachment to 128. Use a render pass with load and store ops none for the stencil, but
1306 // disable stencil test which also disables stencil writes. The stencil attachment should have the original
1307 // preinitialized value after the render pass.
1310 params.alphaBlend = false;
1311 params.renderPassType = renderPassType;
1312 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1313 VK_ATTACHMENT_LOAD_OP_LOAD,
1314 VK_ATTACHMENT_STORE_OP_STORE,
1315 ATTACHMENT_INIT_PRE,
1318 params.attachments.push_back({ATTACHMENT_USAGE_STENCIL,
1319 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1320 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1321 ATTACHMENT_INIT_PRE,
1323 true, stencilInit});
1324 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL | ATTACHMENT_USAGE_WRITE_OFF}}, 1u});
1326 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_load_op_none_store_op_none_write_off", "", params));
1329 // Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64
1330 // using cmdClearAttachments. Draw a red rectangle using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update
1331 // stencil buffer to 255. After the renderpass the color buffer should have red inside the render area and stencil should have the
1332 // shader updated value of 255.
1335 params.alphaBlend = false;
1336 params.renderPassType = renderPassType;
1337 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1338 VK_ATTACHMENT_LOAD_OP_LOAD,
1339 VK_ATTACHMENT_STORE_OP_STORE,
1340 ATTACHMENT_INIT_PRE,
1343 params.attachments.push_back({ATTACHMENT_USAGE_STENCIL,
1344 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1345 VK_ATTACHMENT_STORE_OP_STORE,
1346 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1348 true, stencilInit});
1349 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u});
1351 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_load_op_none_store_op_store", "", params));
1354 // Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64
1355 // using cmdClearAttachments. Draw a red rectangle using stencil reference 255 and stencil op 'greater' which will pass.
1356 // After the renderpass the color buffer should have red inside the render area. Stencil buffer contents inside render
1357 // are is undefined because of store op 'don't care', but the outside should have the original value of 128.
1360 params.alphaBlend = false;
1361 params.renderPassType = renderPassType;
1362 params.attachments.push_back({ATTACHMENT_USAGE_COLOR,
1363 VK_ATTACHMENT_LOAD_OP_LOAD,
1364 VK_ATTACHMENT_STORE_OP_STORE,
1365 ATTACHMENT_INIT_PRE,
1368 params.attachments.push_back({ATTACHMENT_USAGE_STENCIL,
1369 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1370 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1371 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1373 true, stencilInit});
1374 params.subpasses.push_back({{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u});
1376 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "stencil_load_op_none_store_op_dontcare", "", params));
1379 return opNoneTests.release();