1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2021 The Khronos Group Inc.
6 * Copyright (c) 2021 Google 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 load and store op "none"
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktRenderPassLoadStoreOpNoneTests.hpp"
26 #include "pipeline/vktPipelineImageUtil.hpp"
27 #include "vktRenderPassTestsUtil.hpp"
28 #include "vktTestCase.hpp"
29 #include "vkBarrierUtil.hpp"
30 #include "vkImageUtil.hpp"
31 #include "vkMemUtil.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkQueryUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkRef.hpp"
36 #include "vkRefUtil.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkObjUtil.hpp"
39 #include "tcuImageCompare.hpp"
40 #include "tcuPlatform.hpp"
41 #include "tcuTestLog.hpp"
42 #include "tcuTextureUtil.hpp"
43 #include "deStringUtil.hpp"
44 #include "deUniquePtr.hpp"
45 #include "deRandom.hpp"
46 #include <cstring>
47 #include <cmath>
48 #include <vector>
49
50 namespace vkt
51 {
52 namespace renderpass
53 {
54
55 using namespace vk;
56
57 namespace
58 {
59
60 enum AttachmentInit
61 {
62 ATTACHMENT_INIT_PRE = 1,
63 ATTACHMENT_INIT_CMD_CLEAR = 2
64 };
65
66 enum AttachmentUsage
67 {
68 ATTACHMENT_USAGE_UNDEFINED = 0,
69 ATTACHMENT_USAGE_COLOR = 1,
70 ATTACHMENT_USAGE_DEPTH = 2,
71 ATTACHMENT_USAGE_STENCIL = 4,
72 ATTACHMENT_USAGE_DEPTH_STENCIL = ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_STENCIL,
73 ATTACHMENT_USAGE_INPUT = 8,
74 ATTACHMENT_USAGE_COLOR_WRITE_OFF = 16,
75 ATTACHMENT_USAGE_DEPTH_WRITE_OFF = 32,
76 ATTACHMENT_USAGE_STENCIL_WRITE_OFF = 64,
77 ATTACHMENT_USAGE_DEPTH_TEST_OFF = 128,
78 ATTACHMENT_USAGE_STENCIL_TEST_OFF = 256,
79 ATTACHMENT_USAGE_MULTISAMPLE = 512,
80 ATTACHMENT_USAGE_RESOLVE_TARGET = 1024,
81 ATTACHMENT_USAGE_INTEGER = 2048
82 };
83
84 struct VerifyAspect
85 {
86 VkImageAspectFlagBits aspect;
87 bool verifyInner;
88 tcu::Vec4 innerRef;
89 bool verifyOuter;
90 tcu::Vec4 outerRef;
91 };
92
93 struct AttachmentParams
94 {
95 uint32_t usage;
96 VkAttachmentLoadOp loadOp;
97 VkAttachmentStoreOp storeOp;
98 VkAttachmentLoadOp stencilLoadOp;
99 VkAttachmentStoreOp stencilStoreOp;
100 uint32_t init;
101 std::vector<VerifyAspect> verifyAspects;
102 };
103
104 struct AttachmentRef
105 {
106 uint32_t idx;
107 uint32_t usage;
108 };
109
110 struct SubpassParams
111 {
112 std::vector<AttachmentRef> attachmentRefs;
113 uint32_t numDraws;
114 };
115
116 enum class ExtensionPreference
117 {
118 EXT,
119 KHR,
120 };
121
122 struct TestParams
123 {
124 std::vector<AttachmentParams> attachments;
125 std::vector<SubpassParams> subpasses;
126 const SharedGroupParams groupParams;
127 VkFormat depthStencilFormat;
128 bool alphaBlend;
129
130 // To ensure both VK_EXT_load_store_op_none and VK_KHR_load_store_op_none are tested, use KHR by
131 // default (if available), but have some tests use EXT (if available). Either way, if one
132 // extension is not available, the other is always used.
133 ExtensionPreference extPreference;
134 };
135
136 struct Vertex4RGBA
137 {
138 tcu::Vec4 position;
139 tcu::Vec4 color;
140 };
141
142 template <typename T>
makeSharedPtr(vk::Move<T> move)143 inline de::SharedPtr<vk::Move<T>> makeSharedPtr(vk::Move<T> move)
144 {
145 return de::SharedPtr<vk::Move<T>>(new vk::Move<T>(move));
146 }
147
createQuad(void)148 std::vector<Vertex4RGBA> createQuad(void)
149 {
150 std::vector<Vertex4RGBA> vertices;
151
152 const float size = 1.0f;
153 const tcu::Vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
154 const tcu::Vec4 blue(0.0f, 0.0f, 1.0f, 1.0f);
155 const Vertex4RGBA lowerLeftVertexRed = {tcu::Vec4(-size, -size, 0.0f, 1.0f), red};
156 const Vertex4RGBA lowerRightVertexRed = {tcu::Vec4(size, -size, 0.0f, 1.0f), red};
157 const Vertex4RGBA upperLeftVertexRed = {tcu::Vec4(-size, size, 0.0f, 1.0f), red};
158 const Vertex4RGBA upperRightVertexRed = {tcu::Vec4(size, size, 0.0f, 1.0f), red};
159 const Vertex4RGBA lowerLeftVertexBlue = {tcu::Vec4(-size, -size, 0.0f, 1.0f), blue};
160 const Vertex4RGBA lowerRightVertexBlue = {tcu::Vec4(size, -size, 0.0f, 1.0f), blue};
161 const Vertex4RGBA upperLeftVertexBlue = {tcu::Vec4(-size, size, 0.0f, 1.0f), blue};
162 const Vertex4RGBA upperRightVertexBlue = {tcu::Vec4(size, size, 0.0f, 1.0f), blue};
163
164 vertices.push_back(lowerLeftVertexRed);
165 vertices.push_back(lowerRightVertexRed);
166 vertices.push_back(upperLeftVertexRed);
167 vertices.push_back(upperLeftVertexRed);
168 vertices.push_back(lowerRightVertexRed);
169 vertices.push_back(upperRightVertexRed);
170
171 vertices.push_back(lowerLeftVertexBlue);
172 vertices.push_back(lowerRightVertexBlue);
173 vertices.push_back(upperLeftVertexBlue);
174 vertices.push_back(upperLeftVertexBlue);
175 vertices.push_back(lowerRightVertexBlue);
176 vertices.push_back(upperRightVertexBlue);
177
178 return vertices;
179 }
180
getFirstUsage(uint32_t attachmentIdx,const std::vector<SubpassParams> & subpasses)181 uint32_t getFirstUsage(uint32_t attachmentIdx, const std::vector<SubpassParams> &subpasses)
182 {
183 for (const auto &subpass : subpasses)
184 for (const auto &ref : subpass.attachmentRefs)
185 if (ref.idx == attachmentIdx)
186 return ref.usage;
187
188 return ATTACHMENT_USAGE_UNDEFINED;
189 }
190
getFormatCaseName(VkFormat format)191 std::string getFormatCaseName(VkFormat format)
192 {
193 return de::toLower(de::toString(getFormatStr(format)).substr(10));
194 }
195
196 // Selects an image format based on the usage flags.
getFormat(uint32_t usage,VkFormat depthStencilFormat)197 VkFormat getFormat(uint32_t usage, VkFormat depthStencilFormat)
198 {
199 if (usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
200 {
201 return depthStencilFormat;
202 }
203
204 if (usage & ATTACHMENT_USAGE_INTEGER)
205 {
206 // Color attachment using integer format.
207 return VK_FORMAT_R8G8B8A8_UINT;
208 }
209
210 return VK_FORMAT_R8G8B8A8_UNORM;
211 }
212
213 template <typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep,
214 typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vk,VkDevice vkDevice,const TestParams testParams)215 Move<VkRenderPass> createRenderPass(const DeviceInterface &vk, VkDevice vkDevice, const TestParams testParams)
216 {
217 const VkImageAspectFlags aspectMask =
218 testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY ? 0 : VK_IMAGE_ASPECT_COLOR_BIT;
219 std::vector<AttachmentDesc> attachmentDescriptions;
220 std::vector<SubpassDesc> subpassDescriptions;
221
222 struct Refs
223 {
224 std::vector<AttachmentRef> colorAttachmentRefs;
225 std::vector<AttachmentRef> resolveAttachmentRefs;
226 std::vector<AttachmentRef> depthStencilAttachmentRefs;
227 std::vector<AttachmentRef> inputAttachmentRefs;
228 };
229
230 std::vector<Refs> subpassRefs;
231 bool hasInputAttachment = false;
232
233 for (size_t i = 0; i < testParams.attachments.size(); i++)
234 {
235 VkImageLayout initialLayout;
236 VkImageLayout finalLayout;
237 VkFormat format = getFormat(testParams.attachments[i].usage, testParams.depthStencilFormat);
238
239 // Search for the first reference to determine the initial layout.
240 uint32_t firstUsage = getFirstUsage((uint32_t)i, testParams.subpasses);
241
242 // No subpasses using this attachment. Use the usage flags of the attachment.
243 if (firstUsage == ATTACHMENT_USAGE_UNDEFINED)
244 firstUsage = testParams.attachments[i].usage;
245
246 if (firstUsage & ATTACHMENT_USAGE_COLOR)
247 initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
248 else if (firstUsage & ATTACHMENT_USAGE_DEPTH_STENCIL)
249 initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
250 else
251 {
252 DE_ASSERT(firstUsage & ATTACHMENT_USAGE_INPUT);
253 initialLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
254 }
255
256 // Set final layout to transfer src if it's being verified. Otherwise
257 // just use the initial layout as it's known to be supported by
258 // the usage flags.
259 if (!testParams.attachments[i].verifyAspects.empty())
260 finalLayout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
261 else
262 finalLayout = initialLayout;
263
264 const VkSampleCountFlagBits sampleCount = testParams.attachments[i].usage & ATTACHMENT_USAGE_MULTISAMPLE ?
265 VK_SAMPLE_COUNT_4_BIT :
266 VK_SAMPLE_COUNT_1_BIT;
267
268 const AttachmentDesc attachmentDesc = {
269 nullptr, // const void* pNext
270 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags
271 format, // VkFormat format
272 sampleCount, // VkSampleCountFlagBits samples
273 testParams.attachments[i].loadOp, // VkAttachmentLoadOp loadOp
274 testParams.attachments[i].storeOp, // VkAttachmentStoreOp storeOp
275 testParams.attachments[i].stencilLoadOp, // VkAttachmentLoadOp stencilLoadOp
276 testParams.attachments[i].stencilStoreOp, // VkAttachmentStoreOp stencilStoreOp
277 initialLayout, // VkImageLayout initialLayout
278 finalLayout // VkImageLayout finalLayout
279 };
280
281 attachmentDescriptions.push_back(attachmentDesc);
282 }
283
284 for (const auto &subpass : testParams.subpasses)
285 {
286 subpassRefs.push_back({});
287 auto &refs = subpassRefs.back();
288
289 for (const auto &ref : subpass.attachmentRefs)
290 {
291 VkImageLayout layout;
292
293 if (ref.usage & ATTACHMENT_USAGE_RESOLVE_TARGET)
294 {
295 layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
296 refs.resolveAttachmentRefs.push_back({nullptr, ref.idx, layout, aspectMask});
297 }
298 else if (ref.usage & ATTACHMENT_USAGE_COLOR)
299 {
300 layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
301 refs.colorAttachmentRefs.push_back({nullptr, ref.idx, layout, aspectMask});
302 }
303 else if (ref.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
304 {
305 layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
306 const auto depthStencilAspectMask =
307 testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY ?
308 0 :
309 getImageAspectFlags(mapVkFormat(testParams.depthStencilFormat));
310 refs.depthStencilAttachmentRefs.push_back({nullptr, ref.idx, layout, depthStencilAspectMask});
311 }
312 else
313 {
314 DE_ASSERT(ref.usage & ATTACHMENT_USAGE_INPUT);
315 layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
316 refs.inputAttachmentRefs.push_back({nullptr, ref.idx, layout, aspectMask});
317 hasInputAttachment = true;
318 }
319 }
320
321 const SubpassDesc subpassDescription = {
322 nullptr,
323 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags
324 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint
325 0u, // uint32_t viewMask
326 (uint32_t)refs.inputAttachmentRefs.size(), // uint32_t inputAttachmentCount
327 refs.inputAttachmentRefs.empty() ?
328 nullptr :
329 refs.inputAttachmentRefs.data(), // const VkAttachmentReference* pInputAttachments
330 (uint32_t)refs.colorAttachmentRefs.size(), // uint32_t colorAttachmentCount
331 refs.colorAttachmentRefs.empty() ?
332 nullptr :
333 refs.colorAttachmentRefs.data(), // const VkAttachmentReference* pColorAttachments
334 refs.resolveAttachmentRefs.empty() ?
335 nullptr :
336 refs.resolveAttachmentRefs.data(), // const VkAttachmentReference* pResolveAttachments
337 refs.depthStencilAttachmentRefs.empty() ?
338 nullptr :
339 refs.depthStencilAttachmentRefs.data(), // const VkAttachmentReference* pDepthStencilAttachment
340 0u, // uint32_t preserveAttachmentCount
341 nullptr // const uint32_t* pPreserveAttachments
342 };
343
344 subpassDescriptions.push_back(subpassDescription);
345 }
346
347 // Dependency of color attachment of subpass 0 to input attachment of subpass 1.
348 // Determined later if it's being used.
349 const SubpassDep subpassDependency = {
350 nullptr, // const void* pNext
351 0u, // uint32_t srcSubpass
352 1u, // uint32_t dstSubpass
353 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags srcStageMask
354 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags dstStageMask
355 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags srcAccessMask
356 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT, // VkAccessFlags dstAccessMask
357 VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags
358 0u // int32_t viewOffset
359 };
360
361 const RenderPassCreateInfo renderPassInfo = {
362 nullptr, // const void* pNext
363 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags
364 (uint32_t)attachmentDescriptions.size(), // uint32_t attachmentCount
365 attachmentDescriptions.data(), // const VkAttachmentDescription* pAttachments
366 (uint32_t)subpassDescriptions.size(), // uint32_t subpassCount
367 subpassDescriptions.data(), // const VkSubpassDescription* pSubpasses
368 hasInputAttachment ? 1u : 0u, // uint32_t dependencyCount
369 hasInputAttachment ? &subpassDependency : nullptr, // const VkSubpassDependency* pDependencies
370 0u, // uint32_t correlatedViewMaskCount
371 nullptr // const uint32_t* pCorrelatedViewMasks
372 };
373
374 return renderPassInfo.createRenderPass(vk, vkDevice);
375 }
376
377 class LoadStoreOpNoneTest : public vkt::TestCase
378 {
379 public:
380 LoadStoreOpNoneTest(tcu::TestContext &testContext, const std::string &name, const TestParams &testParams);
381 virtual ~LoadStoreOpNoneTest(void) = default;
382 virtual void initPrograms(SourceCollections &sourceCollections) const;
383 virtual void checkSupport(Context &context) const;
384 virtual TestInstance *createInstance(Context &context) const;
385
386 private:
387 const TestParams m_testParams;
388 };
389
390 class LoadStoreOpNoneTestInstance : public vkt::TestInstance
391 {
392 public:
393 LoadStoreOpNoneTestInstance(Context &context, const TestParams &testParams);
394 virtual ~LoadStoreOpNoneTestInstance(void) = default;
395 virtual tcu::TestStatus iterate(void);
396
397 template <typename RenderpassSubpass>
398 void createCommandBuffer(const DeviceInterface &vk, VkDevice vkDevice,
399 std::vector<Move<VkDescriptorSet>> &descriptorSets,
400 std::vector<PipelineLayoutWrapper> &pipelineLayouts,
401 std::vector<GraphicsPipelineWrapper> &pipelines);
402 void createCommandBuffer(const DeviceInterface &vk, VkDevice vkDevice, std::vector<Move<VkImageView>> &imageViews,
403 std::vector<Move<VkDescriptorSet>> &descriptorSets,
404 std::vector<PipelineLayoutWrapper> &pipelineLayouts,
405 std::vector<GraphicsPipelineWrapper> &pipelines);
406 void drawCommands(VkCommandBuffer cmdBuffer, std::vector<Move<VkDescriptorSet>> &descriptorSets,
407 std::vector<PipelineLayoutWrapper> &pipelineLayouts,
408 std::vector<GraphicsPipelineWrapper> &pipelines) const;
409
410 private:
411 TestParams m_testParams;
412
413 const tcu::UVec2 m_imageSize;
414 const tcu::UVec2 m_renderSize;
415
416 Move<VkDescriptorPool> m_descriptorPool;
417 Move<VkRenderPass> m_renderPass;
418 Move<VkFramebuffer> m_framebuffer;
419
420 Move<VkBuffer> m_vertexBuffer;
421 std::vector<Vertex4RGBA> m_vertices;
422 de::MovePtr<Allocation> m_vertexBufferAlloc;
423
424 Move<VkCommandPool> m_cmdPool;
425 Move<VkCommandBuffer> m_cmdBuffer;
426 Move<VkCommandBuffer> m_secCmdBuffer;
427 };
428
LoadStoreOpNoneTest(tcu::TestContext & testContext,const std::string & name,const TestParams & testParams)429 LoadStoreOpNoneTest::LoadStoreOpNoneTest(tcu::TestContext &testContext, const std::string &name,
430 const TestParams &testParams)
431 : vkt::TestCase(testContext, name)
432 , m_testParams(testParams)
433 {
434 }
435
createInstance(Context & context) const436 TestInstance *LoadStoreOpNoneTest::createInstance(Context &context) const
437 {
438 return new LoadStoreOpNoneTestInstance(context, m_testParams);
439 }
440
checkSupport(Context & ctx) const441 void LoadStoreOpNoneTest::checkSupport(Context &ctx) const
442 {
443 const auto &vki = ctx.getInstanceInterface();
444 const auto physDev = ctx.getPhysicalDevice();
445
446 checkPipelineConstructionRequirements(vki, physDev, m_testParams.groupParams->pipelineConstructionType);
447
448 // Check for renderpass2 extension if used.
449 if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
450 ctx.requireDeviceFunctionality("VK_KHR_create_renderpass2");
451
452 // Check for dynamic_rendering extension if used
453 if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
454 {
455 ctx.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
456 if (m_testParams.subpasses.size() > 1)
457 ctx.requireDeviceFunctionality("VK_KHR_dynamic_rendering_local_read");
458 }
459
460 const bool supportsExt = ctx.isDeviceFunctionalitySupported("VK_EXT_load_store_op_none");
461 const bool supportsKHR = ctx.isDeviceFunctionalitySupported("VK_KHR_load_store_op_none");
462 // Prefer VK_EXT_load_store_op_none if supported, and either explicitly preferred or KHR is not
463 // supported. Otherwise require VK_KHR_load_store_op_none. The tests are skipped if neither
464 // extension is supported.
465 if (supportsExt && (m_testParams.extPreference == ExtensionPreference::EXT || !supportsKHR))
466 ctx.requireDeviceFunctionality("VK_EXT_load_store_op_none");
467 else
468 ctx.requireDeviceFunctionality("VK_KHR_load_store_op_none");
469
470 // Check depth/stencil format support.
471 for (const auto &att : m_testParams.attachments)
472 {
473 if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
474 {
475 const VkFormat format = getFormat(att.usage, m_testParams.depthStencilFormat);
476 VkImageUsageFlags usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
477 const auto aspectFlags = getImageAspectFlags(mapVkFormat(format));
478
479 if (att.usage & ATTACHMENT_USAGE_DEPTH)
480 DE_ASSERT((aspectFlags & VK_IMAGE_ASPECT_DEPTH_BIT) != 0u);
481
482 if (att.usage & ATTACHMENT_USAGE_STENCIL)
483 DE_ASSERT((aspectFlags & VK_IMAGE_ASPECT_STENCIL_BIT) != 0u);
484
485 DE_UNREF(aspectFlags); // For release builds.
486
487 if (!att.verifyAspects.empty())
488 usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
489
490 if (att.init & ATTACHMENT_INIT_PRE)
491 usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
492
493 const auto imgType = VK_IMAGE_TYPE_2D;
494 const auto tiling = VK_IMAGE_TILING_OPTIMAL;
495 VkImageFormatProperties properties;
496 const auto result =
497 vki.getPhysicalDeviceImageFormatProperties(physDev, format, imgType, tiling, usage, 0u, &properties);
498
499 if (result != VK_SUCCESS)
500 TCU_THROW(NotSupportedError, "Depth-stencil format not supported");
501 }
502 }
503 }
504
initPrograms(SourceCollections & sourceCollections) const505 void LoadStoreOpNoneTest::initPrograms(SourceCollections &sourceCollections) const
506 {
507 std::ostringstream fragmentSource;
508
509 sourceCollections.glslSources.add("color_vert")
510 << glu::VertexSource("#version 450\n"
511 "layout(location = 0) in highp vec4 position;\n"
512 "layout(location = 1) in highp vec4 color;\n"
513 "layout(location = 0) out highp vec4 vtxColor;\n"
514 "void main (void)\n"
515 "{\n"
516 " gl_Position = position;\n"
517 " vtxColor = color;\n"
518 "}\n");
519
520 sourceCollections.glslSources.add("color_frag")
521 << glu::FragmentSource("#version 450\n"
522 "layout(location = 0) in highp vec4 vtxColor;\n"
523 "layout(location = 0) out highp vec4 fragColor;\n"
524 "void main (void)\n"
525 "{\n"
526 " fragColor = vtxColor;\n"
527 " gl_FragDepth = 1.0;\n"
528 "}\n");
529
530 sourceCollections.glslSources.add("color_frag_uint")
531 << glu::FragmentSource("#version 450\n"
532 "layout(location = 0) in highp vec4 vtxColor;\n"
533 "layout(location = 0) out highp uvec4 fragColor;\n"
534 "void main (void)\n"
535 "{\n"
536 " fragColor = uvec4(vtxColor * vec4(255));\n"
537 " gl_FragDepth = 1.0;\n"
538 "}\n");
539
540 sourceCollections.glslSources.add("color_frag_blend")
541 << glu::FragmentSource("#version 450\n"
542 "layout(location = 0) in highp vec4 vtxColor;\n"
543 "layout(location = 0) out highp vec4 fragColor;\n"
544 "void main (void)\n"
545 "{\n"
546 " fragColor = vec4(vtxColor.rgb, 0.5);\n"
547 " gl_FragDepth = 1.0;\n"
548 "}\n");
549
550 sourceCollections.glslSources.add("color_frag_input") << glu::FragmentSource(
551 "#version 450\n"
552 "layout(location = 0) in highp vec4 vtxColor;\n"
553 "layout(location = 0) out highp vec4 fragColor;\n"
554 "layout(input_attachment_index = 0, set = 0, binding = 0) uniform subpassInput inputColor;\n"
555 "void main (void)\n"
556 "{\n"
557 " fragColor = subpassLoad(inputColor) + vtxColor;\n"
558 " gl_FragDepth = 1.0;\n"
559 "}\n");
560 }
561
LoadStoreOpNoneTestInstance(Context & context,const TestParams & testParams)562 LoadStoreOpNoneTestInstance::LoadStoreOpNoneTestInstance(Context &context, const TestParams &testParams)
563 : vkt::TestInstance(context)
564 , m_testParams(testParams)
565 , m_imageSize(32u, 32u)
566 , m_renderSize(27u, 19u)
567 , m_vertices(createQuad())
568 {
569 }
570
571 template <typename RenderpassSubpass>
createCommandBuffer(const DeviceInterface & vk,VkDevice vkDevice,std::vector<Move<VkDescriptorSet>> & descriptorSets,std::vector<PipelineLayoutWrapper> & pipelineLayouts,std::vector<GraphicsPipelineWrapper> & pipelines)572 void LoadStoreOpNoneTestInstance::createCommandBuffer(const DeviceInterface &vk, VkDevice vkDevice,
573 std::vector<Move<VkDescriptorSet>> &descriptorSets,
574 std::vector<PipelineLayoutWrapper> &pipelineLayouts,
575 std::vector<GraphicsPipelineWrapper> &pipelines)
576 {
577 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(nullptr, VK_SUBPASS_CONTENTS_INLINE);
578 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(nullptr);
579
580 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
581
582 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
583 const VkRenderPassBeginInfo renderPassBeginInfo{
584 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType
585 nullptr, // const void* pNext
586 *m_renderPass, // VkRenderPass renderPass
587 *m_framebuffer, // VkFramebuffer framebuffer
588 makeRect2D(m_renderSize), // VkRect2D renderArea
589 0u, // uint32_t clearValueCount
590 nullptr // const VkClearValue* pClearValues
591 };
592 RenderpassSubpass::cmdBeginRenderPass(vk, *m_cmdBuffer, &renderPassBeginInfo, &subpassBeginInfo);
593
594 drawCommands(*m_cmdBuffer, descriptorSets, pipelineLayouts, pipelines);
595
596 RenderpassSubpass::cmdEndRenderPass(vk, *m_cmdBuffer, &subpassEndInfo);
597 endCommandBuffer(vk, *m_cmdBuffer);
598 }
599
createCommandBuffer(const DeviceInterface & vk,VkDevice vkDevice,std::vector<Move<VkImageView>> & imageViews,std::vector<Move<VkDescriptorSet>> & descriptorSets,std::vector<PipelineLayoutWrapper> & pipelineLayouts,std::vector<GraphicsPipelineWrapper> & pipelines)600 void LoadStoreOpNoneTestInstance::createCommandBuffer(const DeviceInterface &vk, VkDevice vkDevice,
601 std::vector<Move<VkImageView>> &imageViews,
602 std::vector<Move<VkDescriptorSet>> &descriptorSets,
603 std::vector<PipelineLayoutWrapper> &pipelineLayouts,
604 std::vector<GraphicsPipelineWrapper> &pipelines)
605 {
606 std::vector<VkRenderingAttachmentInfo> colorAttachments;
607
608 VkRenderingAttachmentInfo depthAttachment{
609 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType sType;
610 nullptr, // const void* pNext;
611 VK_NULL_HANDLE, // VkImageView imageView;
612 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
613 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
614 VK_NULL_HANDLE, // VkImageView resolveImageView;
615 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
616 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
617 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
618 makeClearValueDepthStencil(0.0f, 0u) // VkClearValue clearValue;
619 };
620
621 VkRenderingAttachmentInfo stencilAttachment{
622 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType sType;
623 nullptr, // const void* pNext;
624 VK_NULL_HANDLE, // VkImageView imageView;
625 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
626 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
627 VK_NULL_HANDLE, // VkImageView resolveImageView;
628 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
629 VK_ATTACHMENT_LOAD_OP_LOAD, // VkAttachmentLoadOp loadOp;
630 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
631 makeClearValueDepthStencil(0.0f, 0u) // VkClearValue clearValue;
632 };
633
634 bool useDepth = false;
635 bool useStencil = false;
636
637 VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT;
638 std::vector<VkFormat> colorAttachmentFormats;
639
640 for (size_t i = 0; i < imageViews.size(); i++)
641 {
642 if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_MULTISAMPLE)
643 {
644 DE_ASSERT(m_testParams.attachments[i + 1].usage & ATTACHMENT_USAGE_RESOLVE_TARGET);
645 const auto resolveMode =
646 ((m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INTEGER) ? VK_RESOLVE_MODE_SAMPLE_ZERO_BIT :
647 VK_RESOLVE_MODE_AVERAGE_BIT);
648 colorAttachments.push_back({
649 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType sType;
650 nullptr, // const void* pNext;
651 *imageViews[i], // VkImageView imageView;
652 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
653 resolveMode, // VkResolveModeFlagBits resolveMode;
654 *imageViews[i + 1], // VkImageView resolveImageView;
655 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout resolveImageLayout;
656 m_testParams.attachments[i].loadOp, // VkAttachmentLoadOp loadOp;
657 m_testParams.attachments[i].storeOp, // VkAttachmentStoreOp storeOp;
658 makeClearValueColor(tcu::Vec4(0.0f)) // VkClearValue clearValue;
659 });
660 colorAttachmentFormats.push_back(
661 getFormat(m_testParams.attachments[i].usage, m_testParams.depthStencilFormat));
662 sampleCount = VK_SAMPLE_COUNT_4_BIT;
663 i += 1;
664 }
665 else if (m_testParams.attachments[i].usage & (ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT))
666 {
667 VkImageLayout imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
668 if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INPUT)
669 imageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
670
671 colorAttachments.push_back({
672 VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, // VkStructureType sType;
673 nullptr, // const void* pNext;
674 *imageViews[i], // VkImageView imageView;
675 imageLayout, // VkImageLayout imageLayout;
676 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
677 VK_NULL_HANDLE, // VkImageView resolveImageView;
678 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout;
679 m_testParams.attachments[i].loadOp, // VkAttachmentLoadOp loadOp;
680 m_testParams.attachments[i].storeOp, // VkAttachmentStoreOp storeOp;
681 makeClearValueColor(tcu::Vec4(0.0f)) // VkClearValue clearValue;
682 });
683 colorAttachmentFormats.push_back(
684 getFormat(m_testParams.attachments[i].usage, m_testParams.depthStencilFormat));
685 }
686 else
687 {
688 uint32_t usage = m_testParams.attachments[i].usage;
689 useDepth = usage & ATTACHMENT_USAGE_DEPTH;
690 useStencil = usage & ATTACHMENT_USAGE_STENCIL;
691
692 depthAttachment.imageView = *imageViews[i];
693 depthAttachment.loadOp = m_testParams.attachments[i].loadOp;
694 depthAttachment.storeOp = m_testParams.attachments[i].storeOp;
695 stencilAttachment.imageView = *imageViews[i];
696 stencilAttachment.loadOp = m_testParams.attachments[i].stencilLoadOp;
697 stencilAttachment.storeOp = m_testParams.attachments[i].stencilStoreOp;
698 }
699 }
700
701 VkCommandBufferInheritanceRenderingInfo inheritanceRenderingInfo{
702 VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO, // VkStructureType sType;
703 nullptr, // const void* pNext;
704 0u, // VkRenderingFlagsKHR flags;
705 0u, // uint32_t viewMask;
706 static_cast<uint32_t>(colorAttachmentFormats.size()), // uint32_t colorAttachmentCount;
707 colorAttachmentFormats.data(), // const VkFormat* pColorAttachmentFormats;
708 useDepth ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED, // VkFormat depthAttachmentFormat;
709 useStencil ? m_testParams.depthStencilFormat : VK_FORMAT_UNDEFINED, // VkFormat stencilAttachmentFormat;
710 sampleCount // VkSampleCountFlagBits rasterizationSamples;
711 };
712
713 const VkCommandBufferInheritanceInfo bufferInheritanceInfo = initVulkanStructure(&inheritanceRenderingInfo);
714 VkCommandBufferBeginInfo commandBufBeginParams{
715 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
716 nullptr, // const void* pNext;
717 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
718 &bufferInheritanceInfo};
719
720 VkRenderingInfo renderingInfo{
721 VK_STRUCTURE_TYPE_RENDERING_INFO,
722 nullptr,
723 0u, // VkRenderingFlagsKHR flags;
724 makeRect2D(m_renderSize), // VkRect2D renderArea;
725 1u, // uint32_t layerCount;
726 0u, // uint32_t viewMask;
727 (uint32_t)colorAttachments.size(), // uint32_t colorAttachmentCount;
728 de::dataOrNull(colorAttachments), // const VkRenderingAttachmentInfoKHR* pColorAttachments;
729 useDepth ? &depthAttachment : nullptr, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
730 useStencil ? &stencilAttachment : nullptr // const VkRenderingAttachmentInfoKHR* pStencilAttachment;
731 };
732
733 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
734
735 if (m_testParams.groupParams->useSecondaryCmdBuffer)
736 {
737 m_secCmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_SECONDARY);
738
739 // record secondary command buffer
740 if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
741 {
742 inheritanceRenderingInfo.flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT;
743 vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams);
744 vk.cmdBeginRendering(*m_secCmdBuffer, &renderingInfo);
745 }
746 else
747 {
748 commandBufBeginParams.flags |= VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT;
749 vk.beginCommandBuffer(*m_secCmdBuffer, &commandBufBeginParams);
750 }
751
752 drawCommands(*m_secCmdBuffer, descriptorSets, pipelineLayouts, pipelines);
753
754 if (m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
755 vk.cmdEndRendering(*m_secCmdBuffer);
756 endCommandBuffer(vk, *m_secCmdBuffer);
757
758 // record primary command buffer
759 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
760 if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
761 {
762 renderingInfo.flags = vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
763 vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
764 }
765 vk.cmdExecuteCommands(*m_cmdBuffer, 1u, &*m_secCmdBuffer);
766 if (!m_testParams.groupParams->secondaryCmdBufferCompletelyContainsDynamicRenderpass)
767 vk.cmdEndRendering(*m_cmdBuffer);
768 endCommandBuffer(vk, *m_cmdBuffer);
769 }
770 else
771 {
772 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
773 vk.cmdBeginRendering(*m_cmdBuffer, &renderingInfo);
774
775 drawCommands(*m_cmdBuffer, descriptorSets, pipelineLayouts, pipelines);
776
777 vk.cmdEndRendering(*m_cmdBuffer);
778 endCommandBuffer(vk, *m_cmdBuffer);
779 }
780 }
781
drawCommands(VkCommandBuffer cmdBuffer,std::vector<Move<VkDescriptorSet>> & descriptorSets,std::vector<PipelineLayoutWrapper> & pipelineLayouts,std::vector<GraphicsPipelineWrapper> & pipelines) const782 void LoadStoreOpNoneTestInstance::drawCommands(VkCommandBuffer cmdBuffer,
783 std::vector<Move<VkDescriptorSet>> &descriptorSets,
784 std::vector<PipelineLayoutWrapper> &pipelineLayouts,
785 std::vector<GraphicsPipelineWrapper> &pipelines) const
786 {
787 const DeviceInterface &vk = m_context.getDeviceInterface();
788 const VkClearRect rect = {makeRect2D(m_renderSize), 0u, 1u};
789 const VkDeviceSize vertexBufferOffset = 0;
790
791 // Add clear commands for selected attachments
792 std::vector<VkClearAttachment> clearAttachments;
793 uint32_t colorAttIdx = 0u;
794 for (const auto &att : m_testParams.attachments)
795 {
796 if (att.init & ATTACHMENT_INIT_CMD_CLEAR)
797 {
798 if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
799 {
800 VkImageAspectFlags aspectMask = 0;
801 if (att.usage & ATTACHMENT_USAGE_DEPTH)
802 aspectMask |= VK_IMAGE_ASPECT_DEPTH_BIT;
803 if (att.usage & ATTACHMENT_USAGE_STENCIL)
804 aspectMask |= VK_IMAGE_ASPECT_STENCIL_BIT;
805 clearAttachments.push_back({aspectMask, 0u, makeClearValueDepthStencil(0.25, 64)});
806 }
807 else
808 {
809 clearAttachments.push_back(
810 {VK_IMAGE_ASPECT_COLOR_BIT, colorAttIdx++, makeClearValueColorF32(0.0f, 0.0f, 0.5f, 1.0f)});
811 }
812 }
813 }
814 if (!clearAttachments.empty())
815 vk.cmdClearAttachments(cmdBuffer, (uint32_t)clearAttachments.size(), clearAttachments.data(), 1u, &rect);
816
817 vk.cmdBindVertexBuffers(cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
818
819 uint32_t descriptorSetIdx = 0u;
820 uint32_t vertexOffset = 0u;
821 for (size_t i = 0; i < m_testParams.subpasses.size(); i++)
822 {
823 if (i != 0)
824 {
825 if (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
826 {
827 // if more subpasses are ever needed code should be adjusted
828 DE_ASSERT(m_testParams.subpasses.size() < 3);
829
830 // barier before next subpass
831 VkMemoryBarrier memoryBarrier =
832 makeMemoryBarrier(VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, VK_ACCESS_INPUT_ATTACHMENT_READ_BIT);
833 vk.cmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
834 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, VK_DEPENDENCY_BY_REGION_BIT, 1u,
835 &memoryBarrier, 0u, nullptr, 0u, nullptr);
836
837 VkRenderingAttachmentLocationInfoKHR renderingAttachmentLocationInfo = initVulkanStructure();
838 VkRenderingInputAttachmentIndexInfoKHR renderingInputAttachmentIndexInfo = initVulkanStructure();
839 std::vector<uint32_t> colorAttachmentLocations(m_testParams.attachments.size(), VK_ATTACHMENT_UNUSED);
840 std::vector<uint32_t> colorAttachmentInputs(m_testParams.attachments.size(), VK_ATTACHMENT_UNUSED);
841 const auto &subpass = m_testParams.subpasses[1];
842 uint32_t locationIndex = 0u;
843 uint32_t inputIndex = 0u;
844
845 // remap color attachment locations and input attachment indices
846 for (uint32_t attIdx = 0; attIdx < (uint32_t)subpass.attachmentRefs.size(); ++attIdx)
847 {
848 if (subpass.attachmentRefs[attIdx].usage == ATTACHMENT_USAGE_COLOR)
849 colorAttachmentLocations[attIdx] = locationIndex++;
850 else if (subpass.attachmentRefs[attIdx].usage == ATTACHMENT_USAGE_INPUT)
851 colorAttachmentInputs[attIdx] = inputIndex++;
852 }
853
854 renderingAttachmentLocationInfo.colorAttachmentCount = (uint32_t)colorAttachmentLocations.size();
855 renderingAttachmentLocationInfo.pColorAttachmentLocations = colorAttachmentLocations.data();
856 renderingInputAttachmentIndexInfo.colorAttachmentCount = (uint32_t)colorAttachmentInputs.size();
857 renderingInputAttachmentIndexInfo.pColorAttachmentInputIndices = colorAttachmentInputs.data();
858
859 vk.cmdSetRenderingAttachmentLocations(cmdBuffer, &renderingAttachmentLocationInfo);
860 vk.cmdSetRenderingInputAttachmentIndices(cmdBuffer, &renderingInputAttachmentIndexInfo);
861 }
862 else
863 vk.cmdNextSubpass(cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
864 }
865
866 vk.cmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines[i].getPipeline());
867
868 bool hasInput = false;
869 for (const auto &ref : m_testParams.subpasses[i].attachmentRefs)
870 if (ref.usage & ATTACHMENT_USAGE_INPUT)
871 hasInput = true;
872
873 if (hasInput)
874 vk.cmdBindDescriptorSets(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *pipelineLayouts[i], 0, 1,
875 &descriptorSets[descriptorSetIdx++].get(), 0, nullptr);
876
877 for (uint32_t d = 0; d < m_testParams.subpasses[i].numDraws; d++)
878 {
879 vk.cmdDraw(cmdBuffer, 6u, 1, vertexOffset, 0);
880 vertexOffset += 6u;
881 }
882 }
883 }
884
iterate(void)885 tcu::TestStatus LoadStoreOpNoneTestInstance::iterate(void)
886 {
887 const DeviceInterface &vk = m_context.getDeviceInterface();
888 const VkDevice vkDevice = m_context.getDevice();
889 const VkQueue queue = m_context.getUniversalQueue();
890 const uint32_t queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
891 SimpleAllocator memAlloc(
892 vk, vkDevice,
893 getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
894 const VkComponentMapping componentMappingRGBA = {VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G,
895 VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A};
896 const bool isDynamicRendering = (m_testParams.groupParams->renderingType == RENDERING_TYPE_DYNAMIC_RENDERING);
897 bool depthIsUndefined = false;
898 bool stencilIsUndefined = false;
899
900 std::vector<Move<VkImage>> attachmentImages;
901 std::vector<de::MovePtr<Allocation>> attachmentImageAllocs;
902 std::vector<Move<VkImageView>> imageViews;
903 std::vector<GraphicsPipelineWrapper> pipelines;
904
905 for (const auto &att : m_testParams.attachments)
906 {
907 VkFormat format = getFormat(att.usage, m_testParams.depthStencilFormat);
908 VkImageUsageFlags usage = 0;
909 VkImageAspectFlags aspectFlags;
910
911 if (!att.verifyAspects.empty())
912 usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
913 if (att.init & ATTACHMENT_INIT_PRE)
914 usage |= VK_IMAGE_USAGE_TRANSFER_DST_BIT;
915
916 if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
917 {
918 aspectFlags = getImageAspectFlags(mapVkFormat(format));
919 usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
920
921 // If depth or stencil load op is NONE, "the previous contents of the image will be undefined inside the render pass. No
922 // access type is used as the image is not accessed."
923 if (att.loadOp == VK_ATTACHMENT_LOAD_OP_NONE_EXT)
924 depthIsUndefined = true;
925
926 if (att.stencilLoadOp == VK_ATTACHMENT_LOAD_OP_NONE_EXT)
927 stencilIsUndefined = true;
928 }
929 else
930 {
931 // Color and input attachments.
932 aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
933
934 if (att.usage & ATTACHMENT_USAGE_COLOR)
935 usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
936 if (att.usage & ATTACHMENT_USAGE_INPUT)
937 usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
938 }
939
940 const VkSampleCountFlagBits sampleCount =
941 att.usage & ATTACHMENT_USAGE_MULTISAMPLE ? VK_SAMPLE_COUNT_4_BIT : VK_SAMPLE_COUNT_1_BIT;
942
943 const VkImageCreateInfo imageParams = {
944 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType
945 nullptr, // const void* pNext
946 0u, // VkImageCreateFlags flags
947 VK_IMAGE_TYPE_2D, // VkImageType imageType
948 format, // VkFormat format
949 {m_imageSize.x(), m_imageSize.y(), 1u}, // VkExtent3D extent
950 1u, // uint32_t mipLevels
951 1u, // uint32_t arrayLayers
952 sampleCount, // VkSampleCountFlagBits samples
953 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
954 usage, // VkImageUsageFlags usage
955 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
956 1u, // uint32_t queueFamilyIndexCount
957 &queueFamilyIndex, // const uint32_t* pQueueFamilyIndices
958 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout
959 };
960
961 attachmentImages.push_back(createImage(vk, vkDevice, &imageParams));
962
963 // Allocate and bind image memory.
964 attachmentImageAllocs.push_back(memAlloc.allocate(
965 getImageMemoryRequirements(vk, vkDevice, *attachmentImages.back()), MemoryRequirement::Any));
966 VK_CHECK(vk.bindImageMemory(vkDevice, *attachmentImages.back(), attachmentImageAllocs.back()->getMemory(),
967 attachmentImageAllocs.back()->getOffset()));
968
969 // Create image view.
970 const VkImageViewCreateInfo imageViewParams = {
971 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType
972 nullptr, // const void* pNext
973 0u, // VkImageViewCreateFlags flags
974 *attachmentImages.back(), // VkImage image
975 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType
976 format, // VkFormat format
977 componentMappingRGBA, // VkChannelMapping channels
978 {aspectFlags, 0u, 1u, 0u, 1u} // VkImageSubresourceRange subresourceRange
979 };
980
981 imageViews.push_back(createImageView(vk, vkDevice, &imageViewParams));
982
983 if (att.init & ATTACHMENT_INIT_PRE)
984 {
985 // Preinitialize image
986 uint32_t attachmentIdx = (uint32_t)attachmentImages.size() - 1;
987 uint32_t firstUsage = getFirstUsage(attachmentIdx, m_testParams.subpasses);
988 if (firstUsage == ATTACHMENT_USAGE_UNDEFINED)
989 firstUsage = att.usage;
990
991 if (firstUsage & ATTACHMENT_USAGE_DEPTH_STENCIL)
992 {
993 const auto dstAccess =
994 (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT);
995 const auto dstStage =
996 (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
997
998 clearDepthStencilImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), format, 0.5f,
999 128u, VK_IMAGE_LAYOUT_UNDEFINED,
1000 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, dstAccess, dstStage);
1001 }
1002 else
1003 {
1004 const auto dstAccess = (VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
1005 VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT);
1006 const auto dstStage =
1007 (VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT);
1008 const auto clearColor =
1009 ((att.usage & ATTACHMENT_USAGE_INTEGER) ? makeClearValueColorU32(0u, 255u, 0u, 255u).color :
1010 makeClearValueColorF32(0.0f, 1.0f, 0.0f, 1.0f).color);
1011 auto layout = ((firstUsage & ATTACHMENT_USAGE_COLOR) ? VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL :
1012 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1013
1014 if (isDynamicRendering && (m_testParams.attachments[attachmentIdx].usage & ATTACHMENT_USAGE_INPUT))
1015 layout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
1016
1017 clearColorImage(vk, vkDevice, queue, queueFamilyIndex, *attachmentImages.back(), clearColor,
1018 VK_IMAGE_LAYOUT_UNDEFINED, layout, dstAccess, dstStage);
1019 }
1020 }
1021 }
1022
1023 if (!isDynamicRendering)
1024 {
1025 // Create render pass.
1026 if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
1027 m_renderPass = createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1,
1028 SubpassDependency1, RenderPassCreateInfo1>(vk, vkDevice, m_testParams);
1029 else
1030 m_renderPass = createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2,
1031 SubpassDependency2, RenderPassCreateInfo2>(vk, vkDevice, m_testParams);
1032
1033 std::vector<VkImageView> views;
1034 for (const auto &view : imageViews)
1035 views.push_back(*view);
1036
1037 // Create framebuffer.
1038 const VkFramebufferCreateInfo framebufferParams = {
1039 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType
1040 nullptr, // const void* pNext
1041 0u, // VkFramebufferCreateFlags flags
1042 *m_renderPass, // VkRenderPass renderPass
1043 (uint32_t)views.size(), // uint32_t attachmentCount
1044 views.data(), // const VkImageView* pAttachments
1045 (uint32_t)m_imageSize.x(), // uint32_t width
1046 (uint32_t)m_imageSize.y(), // uint32_t height
1047 1u // uint32_t layers
1048 };
1049
1050 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1051 }
1052
1053 // Create shader modules
1054 ShaderWrapper vertexShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_vert"), 0);
1055 ShaderWrapper fragmentShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("color_frag"), 0);
1056 ShaderWrapper fragmentShaderModuleUint(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_uint"), 0);
1057 ShaderWrapper fragmentShaderModuleBlend(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_blend"), 0);
1058 ShaderWrapper fragmentShaderModuleInput(vk, vkDevice, m_context.getBinaryCollection().get("color_frag_input"), 0);
1059
1060 // Create descriptor pool. Prepare for using one input attachment at most.
1061 {
1062 const VkDescriptorPoolSize descriptorPoolSize = {
1063 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType type
1064 1u // uint32_t descriptorCount
1065 };
1066
1067 const VkDescriptorPoolCreateInfo descriptorPoolCreateInfo = {
1068 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType
1069 nullptr, // const void* pNext
1070 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags
1071 1u, // uint32_t maxSets
1072 1u, // uint32_t poolSizeCount
1073 &descriptorPoolSize // const VkDescriptorPoolSize* pPoolSizes
1074 };
1075
1076 m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolCreateInfo);
1077 }
1078
1079 const auto subpassCount = (uint32_t)m_testParams.subpasses.size();
1080 std::vector<Move<VkDescriptorSetLayout>> descriptorSetLayouts;
1081 std::vector<Move<VkDescriptorSet>> descriptorSets;
1082 std::vector<PipelineLayoutWrapper> pipelineLayouts(subpassCount);
1083
1084 for (uint32_t subpassIdx = 0; subpassIdx < subpassCount; ++subpassIdx)
1085 {
1086 const auto &subpass = m_testParams.subpasses[subpassIdx];
1087 uint32_t numInputAttachments = 0u;
1088 bool noColorWrite = false;
1089 bool depthTest = false;
1090 bool stencilTest = false;
1091 bool depthWrite = true;
1092 bool stencilWrite = true;
1093 bool multisample = false;
1094 bool uintColorBuffer = false;
1095 VkCompareOp depthCompareOp = VK_COMPARE_OP_GREATER;
1096 VkCompareOp stencilCompareOp = VK_COMPARE_OP_GREATER;
1097
1098 // Create pipeline layout.
1099 {
1100 std::vector<VkDescriptorSetLayoutBinding> layoutBindings;
1101
1102 for (const auto ref : subpass.attachmentRefs)
1103 {
1104 if (ref.usage & ATTACHMENT_USAGE_INPUT)
1105 {
1106 const VkDescriptorSetLayoutBinding layoutBinding = {
1107 0u, // uint32_t binding
1108 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType
1109 1u, // uint32_t descriptorCount
1110 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlags stageFlags
1111 nullptr // const VkSampler* pImmutableSamplers
1112 };
1113
1114 layoutBindings.push_back(layoutBinding);
1115 numInputAttachments++;
1116 }
1117 if (ref.usage & ATTACHMENT_USAGE_COLOR)
1118 {
1119 if (ref.usage & ATTACHMENT_USAGE_COLOR_WRITE_OFF)
1120 noColorWrite = true;
1121 }
1122 if (ref.usage & ATTACHMENT_USAGE_DEPTH)
1123 {
1124 if (!(ref.usage & ATTACHMENT_USAGE_DEPTH_TEST_OFF))
1125 depthTest = true;
1126 if (ref.usage & ATTACHMENT_USAGE_DEPTH_WRITE_OFF)
1127 depthWrite = false;
1128
1129 // Enabling depth testing with undefined depth buffer contents. Let's make sure
1130 // all samples pass the depth test.
1131 if (depthIsUndefined && depthTest)
1132 depthCompareOp = VK_COMPARE_OP_ALWAYS;
1133 }
1134 if (ref.usage & ATTACHMENT_USAGE_STENCIL)
1135 {
1136 if (!(ref.usage & ATTACHMENT_USAGE_STENCIL_TEST_OFF))
1137 stencilTest = true;
1138 if (ref.usage & ATTACHMENT_USAGE_STENCIL_WRITE_OFF)
1139 stencilWrite = false;
1140
1141 if (stencilIsUndefined && stencilTest)
1142 stencilCompareOp = VK_COMPARE_OP_ALWAYS;
1143 }
1144 if (ref.usage & ATTACHMENT_USAGE_MULTISAMPLE)
1145 {
1146 multisample = true;
1147 }
1148 if (ref.usage & ATTACHMENT_USAGE_INTEGER)
1149 {
1150 uintColorBuffer = true;
1151 }
1152 }
1153
1154 const VkDescriptorSetLayoutCreateInfo descriptorSetLayoutParams = {
1155 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType
1156 nullptr, // const void* pNext
1157 0u, // VkDescriptorSetLayoutCreateFlags flags
1158 (uint32_t)layoutBindings.size(), // uint32_t bindingCount
1159 layoutBindings.empty() ? nullptr :
1160 layoutBindings.data() // const VkDescriptorSetLayoutBinding* pBindings
1161 };
1162 descriptorSetLayouts.push_back(createDescriptorSetLayout(vk, vkDevice, &descriptorSetLayoutParams));
1163 pipelineLayouts[subpassIdx] = PipelineLayoutWrapper(m_testParams.groupParams->pipelineConstructionType, vk,
1164 vkDevice, *descriptorSetLayouts.back());
1165 }
1166
1167 // Update descriptor set if needed.
1168 if (numInputAttachments > 0u)
1169 {
1170 VkImageLayout inputImageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
1171 if (isDynamicRendering)
1172 inputImageLayout = VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR;
1173
1174 // Assuming there's only one input attachment at most.
1175 DE_ASSERT(numInputAttachments == 1u);
1176
1177 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo = {
1178 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType
1179 nullptr, // const void* pNext
1180 *m_descriptorPool, // VkDescriptorPool descriptorPool
1181 1u, // uint32_t descriptorSetCount
1182 &descriptorSetLayouts.back().get(), // const VkDescriptorSetLayout* pSetLayouts
1183 };
1184
1185 descriptorSets.push_back(allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo));
1186
1187 for (size_t i = 0; i < imageViews.size(); i++)
1188 {
1189 if (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INPUT)
1190 {
1191 const VkDescriptorImageInfo inputImageInfo{
1192 VK_NULL_HANDLE, // VkSampler sampler
1193 *imageViews[i], // VkImageView imageView
1194 inputImageLayout // VkImageLayout imageLayout
1195 };
1196
1197 const VkWriteDescriptorSet descriptorWrite = {
1198 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType
1199 nullptr, // const void* pNext
1200 *descriptorSets.back(), // VkDescriptorSet dstSet
1201 0u, // uint32_t dstBinding
1202 0u, // uint32_t dstArrayElement
1203 1u, // uint32_t descriptorCount
1204 VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, // VkDescriptorType descriptorType
1205 &inputImageInfo, // const VkDescriptorImageInfo* pImageInfo
1206 nullptr, // const VkDescriptorBufferInfo* pBufferInfo
1207 nullptr // const VkBufferView* pTexelBufferView
1208 };
1209 vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, nullptr);
1210 }
1211 }
1212 }
1213
1214 // Create pipeline.
1215 {
1216 const VkVertexInputBindingDescription vertexInputBindingDescription = {
1217 0u, // uint32_t binding
1218 (uint32_t)sizeof(Vertex4RGBA), // uint32_t strideInBytes
1219 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate
1220 };
1221
1222 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] = {
1223 {
1224 0u, // uint32_t location
1225 0u, // uint32_t binding
1226 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
1227 0u // uint32_t offset
1228 },
1229 {
1230 1u, // uint32_t location
1231 0u, // uint32_t binding
1232 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format
1233 (uint32_t)(sizeof(float) * 4), // uint32_t offset
1234 }};
1235
1236 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams = {
1237 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType
1238 nullptr, // const void* pNext
1239 0u, // VkPipelineVertexInputStateCreateFlags flags
1240 1u, // uint32_t vertexBindingDescriptionCount
1241 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions
1242 2u, // uint32_t vertexAttributeDescriptionCount
1243 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions
1244 };
1245
1246 const VkColorComponentFlags writeMask =
1247 noColorWrite ? 0 :
1248 VK_COLOR_COMPONENT_R_BIT // VkColorComponentFlags colorWriteMask
1249 | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
1250
1251 VkPipelineRenderingCreateInfoKHR renderingCreateInfo = initVulkanStructure();
1252
1253 std::vector<VkFormat> colorVector;
1254 for (const auto &att : m_testParams.attachments)
1255 {
1256 VkFormat format = getFormat(att.usage, m_testParams.depthStencilFormat);
1257
1258 if (att.usage & ATTACHMENT_USAGE_DEPTH_STENCIL)
1259 {
1260 const auto tcuFormat = mapVkFormat(format);
1261 const auto hasDepth = tcu::hasDepthComponent(tcuFormat.order);
1262 const auto hasStencil = tcu::hasStencilComponent(tcuFormat.order);
1263 const auto useDepth = att.usage & ATTACHMENT_USAGE_DEPTH;
1264 const auto useStencil = att.usage & ATTACHMENT_USAGE_STENCIL;
1265 renderingCreateInfo.depthAttachmentFormat = (hasDepth && useDepth ? format : VK_FORMAT_UNDEFINED);
1266 renderingCreateInfo.stencilAttachmentFormat =
1267 (hasStencil && useStencil ? format : VK_FORMAT_UNDEFINED);
1268 }
1269 else if (!(att.usage & ATTACHMENT_USAGE_RESOLVE_TARGET))
1270 {
1271 colorVector.push_back(format);
1272 }
1273 }
1274
1275 uint32_t attachmentCount =
1276 (*m_renderPass == VK_NULL_HANDLE) ? static_cast<uint32_t>(colorVector.size()) : 1u;
1277 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentState(
1278 attachmentCount,
1279 {
1280 false, // VkBool32 blendEnable
1281 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor
1282 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor
1283 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
1284 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor
1285 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor
1286 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
1287 writeMask // VkColorComponentFlags colorWriteMask
1288 });
1289
1290 if (m_testParams.alphaBlend)
1291 {
1292 uint32_t attachmentIndex = (*m_renderPass == VK_NULL_HANDLE) ? (uint32_t)pipelines.size() : 0u;
1293 colorBlendAttachmentState[attachmentIndex].blendEnable = true;
1294 }
1295
1296 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams{
1297 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
1298 nullptr, // const void* pNext
1299 0u, // VkPipelineColorBlendStateCreateFlags flags
1300 VK_FALSE, // VkBool32 logicOpEnable
1301 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp
1302 attachmentCount, // uint32_t attachmentCount
1303 colorBlendAttachmentState.data(), // const VkPipelineColorBlendAttachmentState* pAttachments
1304 {0.0f, 0.0f, 0.0f, 0.0f} // float blendConstants[4]
1305 };
1306
1307 const VkStencilOpState stencilOpState = {
1308 VK_STENCIL_OP_KEEP, // VkStencilOp failOp
1309 stencilWrite ? VK_STENCIL_OP_REPLACE : VK_STENCIL_OP_KEEP, // VkStencilOp passOp
1310 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp
1311 stencilCompareOp, // VkCompareOp compareOp
1312 0xff, // uint32_t compareMask
1313 0xff, // uint32_t writeMask
1314 0xff // uint32_t reference
1315 };
1316
1317 const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = {
1318 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
1319 nullptr, // const void* pNext
1320 0u, // VkPipelineDepthStencilStateCreateFlags flags
1321 depthTest, // VkBool32 depthTestEnable
1322 depthWrite ? VK_TRUE : VK_FALSE, // VkBool32 depthWriteEnable
1323 depthCompareOp, // VkCompareOp depthCompareOp
1324 VK_FALSE, // VkBool32 depthBoundsTestEnable
1325 stencilTest, // VkBool32 stencilTestEnable
1326 stencilOpState, // VkStencilOpState front
1327 stencilOpState, // VkStencilOpState back
1328 0.0f, // float minDepthBounds
1329 1.0f, // float maxDepthBounds
1330 };
1331
1332 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = {
1333 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
1334 nullptr, // const void* pNext
1335 0u, // VkPipelineMultisampleStateCreateFlags flags
1336 multisample ? VK_SAMPLE_COUNT_4_BIT :
1337 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples
1338 VK_FALSE, // VkBool32 sampleShadingEnable
1339 1.0f, // float minSampleShading
1340 nullptr, // const VkSampleMask* pSampleMask
1341 VK_FALSE, // VkBool32 alphaToCoverageEnable
1342 VK_FALSE // VkBool32 alphaToOneEnable
1343 };
1344
1345 const std::vector<VkViewport> viewports(1, makeViewport(m_imageSize));
1346 const std::vector<VkRect2D> scissors(1, makeRect2D(m_renderSize));
1347 ShaderWrapper *fragShader = &fragmentShaderModule;
1348
1349 if (numInputAttachments > 0u)
1350 fragShader = &fragmentShaderModuleInput;
1351 else if (uintColorBuffer)
1352 fragShader = &fragmentShaderModuleUint;
1353 else if (m_testParams.alphaBlend)
1354 fragShader = &fragmentShaderModuleBlend;
1355
1356 VkRenderingAttachmentLocationInfoKHR renderingAttachmentLocationInfo = initVulkanStructure();
1357 VkRenderingInputAttachmentIndexInfoKHR renderingInputAttachmentIndexInfo = initVulkanStructure();
1358 PipelineRenderingCreateInfoWrapper renderingCreateInfoWrapper;
1359 RenderingAttachmentLocationInfoWrapper renderingAttachmentLocationInfoWrapper;
1360 RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfoWrapper;
1361 std::vector<uint32_t> colorAttachmentLocations(colorVector.size(), VK_ATTACHMENT_UNUSED);
1362 std::vector<uint32_t> colorAttachmentInputs(colorVector.size(), VK_ATTACHMENT_UNUSED);
1363
1364 if (isDynamicRendering)
1365 {
1366 renderingCreateInfo.colorAttachmentCount = static_cast<uint32_t>(colorVector.size());
1367 renderingCreateInfo.pColorAttachmentFormats = colorVector.data();
1368 renderingCreateInfoWrapper.ptr = &renderingCreateInfo;
1369
1370 if (numInputAttachments > 0u)
1371 {
1372 uint32_t locationIndex = 0u;
1373 uint32_t inputIndex = 0u;
1374 for (uint32_t i = 0; i < (uint32_t)subpass.attachmentRefs.size(); ++i)
1375 {
1376 if (subpass.attachmentRefs[i].usage == ATTACHMENT_USAGE_COLOR)
1377 colorAttachmentLocations[i] = locationIndex++;
1378 else if (subpass.attachmentRefs[i].usage == ATTACHMENT_USAGE_INPUT)
1379 colorAttachmentInputs[i] = inputIndex++;
1380 }
1381
1382 renderingAttachmentLocationInfo.colorAttachmentCount = renderingCreateInfo.colorAttachmentCount;
1383 renderingAttachmentLocationInfo.pColorAttachmentLocations = colorAttachmentLocations.data();
1384 renderingAttachmentLocationInfoWrapper.ptr = &renderingAttachmentLocationInfo;
1385 renderingInputAttachmentIndexInfo.colorAttachmentCount = renderingCreateInfo.colorAttachmentCount;
1386 renderingInputAttachmentIndexInfo.pColorAttachmentInputIndices = colorAttachmentInputs.data();
1387 renderingInputAttachmentIndexInfoWrapper.ptr = &renderingInputAttachmentIndexInfo;
1388 }
1389 }
1390
1391 const auto &pipelineLayout = pipelineLayouts[subpassIdx];
1392 pipelines.emplace_back(m_context.getInstanceInterface(), vk, m_context.getPhysicalDevice(), vkDevice,
1393 m_context.getDeviceExtensions(), m_testParams.groupParams->pipelineConstructionType);
1394 pipelines.back()
1395 .setDefaultRasterizationState()
1396 .setupVertexInputState(&vertexInputStateParams)
1397 .setupPreRasterizationShaderState(viewports, scissors, pipelineLayout, *m_renderPass, subpassIdx,
1398 vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(),
1399 ShaderWrapper(), nullptr, nullptr, renderingCreateInfoWrapper)
1400 .setupFragmentShaderState(pipelineLayout, *m_renderPass, subpassIdx, *fragShader,
1401 &depthStencilStateParams, &multisampleStateParams, 0, VK_NULL_HANDLE, {},
1402 renderingInputAttachmentIndexInfoWrapper)
1403 .setupFragmentOutputState(*m_renderPass, subpassIdx, &colorBlendStateParams, &multisampleStateParams,
1404 VK_NULL_HANDLE, {}, renderingAttachmentLocationInfoWrapper)
1405 .setMonolithicPipelineLayout(pipelineLayout)
1406 .buildPipeline();
1407 }
1408 }
1409
1410 // Create vertex buffer.
1411 {
1412 const VkBufferCreateInfo vertexBufferParams = {
1413 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
1414 nullptr, // const void* pNext
1415 0u, // VkBufferCreateFlags flags
1416 (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()), // VkDeviceSize size
1417 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage
1418 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1419 1u, // uint32_t queueFamilyIndexCount
1420 &queueFamilyIndex // const uint32_t* pQueueFamilyIndices
1421 };
1422
1423 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
1424 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer),
1425 MemoryRequirement::HostVisible);
1426
1427 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(),
1428 m_vertexBufferAlloc->getOffset()));
1429
1430 // Upload vertex data.
1431 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
1432 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
1433 }
1434
1435 // Create command pool.
1436 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1437
1438 // Create command buffer.
1439 if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
1440 createCommandBuffer<RenderpassSubpass1>(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines);
1441 else if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
1442 createCommandBuffer<RenderpassSubpass2>(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines);
1443 else
1444 createCommandBuffer(vk, vkDevice, imageViews, descriptorSets, pipelineLayouts, pipelines);
1445
1446 // Submit commands.
1447 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1448
1449 bool pass = true;
1450
1451 // Verify selected attachments.
1452 for (size_t i = 0; i < m_testParams.attachments.size(); i++)
1453 {
1454 bool transitioned = false;
1455 for (const auto &verify : m_testParams.attachments[i].verifyAspects)
1456 {
1457 de::MovePtr<tcu::TextureLevel> textureLevelResult;
1458
1459 SimpleAllocator allocator(
1460 vk, vkDevice,
1461 getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1462 VkFormat format = getFormat(m_testParams.attachments[i].usage, m_testParams.depthStencilFormat);
1463
1464 if (verify.aspect == VK_IMAGE_ASPECT_DEPTH_BIT)
1465 {
1466 VkImageLayout layout = (isDynamicRendering && !transitioned) ?
1467 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
1468 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1469 textureLevelResult = pipeline::readDepthAttachment(
1470 vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i],
1471 m_testParams.depthStencilFormat, m_imageSize, layout);
1472 transitioned = true;
1473 }
1474 else if (verify.aspect == VK_IMAGE_ASPECT_STENCIL_BIT)
1475 {
1476 VkImageLayout layout = (isDynamicRendering && !transitioned) ?
1477 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
1478 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1479 textureLevelResult = pipeline::readStencilAttachment(
1480 vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i],
1481 m_testParams.depthStencilFormat, m_imageSize, layout);
1482 transitioned = true;
1483 }
1484 else
1485 {
1486 DE_ASSERT(verify.aspect == VK_IMAGE_ASPECT_COLOR_BIT);
1487 VkImageLayout layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1488 if (isDynamicRendering && !transitioned)
1489 layout = (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INPUT) ?
1490 VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR :
1491 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1492 textureLevelResult = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator,
1493 *attachmentImages[i], format, m_imageSize, layout);
1494 transitioned = true;
1495 }
1496
1497 const tcu::ConstPixelBufferAccess &access = textureLevelResult->getAccess();
1498
1499 // Log attachment contents
1500 m_context.getTestContext().getLog()
1501 << tcu::TestLog::ImageSet("Attachment " + de::toString(i), "")
1502 << tcu::TestLog::Image("Attachment " + de::toString(i), "", access) << tcu::TestLog::EndImageSet;
1503
1504 for (int y = 0; y < access.getHeight(); y++)
1505 for (int x = 0; x < access.getWidth(); x++)
1506 {
1507 const bool inner = x < (int)m_renderSize.x() && y < (int)m_renderSize.y();
1508
1509 if (inner && !verify.verifyInner)
1510 continue;
1511 if (!inner && !verify.verifyOuter)
1512 continue;
1513
1514 const tcu::Vec4 ref = inner ? verify.innerRef : verify.outerRef;
1515 const tcu::Vec4 p = access.getPixel(x, y);
1516
1517 for (int c = 0; c < 4; c++)
1518 if (fabs(p[c] - ref[c]) > 0.01f)
1519 pass = false;
1520 }
1521 }
1522 }
1523
1524 if (pass)
1525 return tcu::TestStatus::pass("Pass");
1526 else
1527 return tcu::TestStatus::fail("Fail");
1528 }
1529
1530 } // namespace
1531
createRenderPassLoadStoreOpNoneTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)1532 tcu::TestCaseGroup *createRenderPassLoadStoreOpNoneTests(tcu::TestContext &testCtx, const SharedGroupParams groupParams)
1533 {
1534 de::MovePtr<tcu::TestCaseGroup> opNoneTests(new tcu::TestCaseGroup(testCtx, "load_store_op_none"));
1535
1536 const tcu::Vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
1537 const tcu::Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
1538 const tcu::Vec4 magenta(1.0f, 0.0f, 1.0f, 1.0f);
1539 const tcu::Vec4 darkBlue(0.0f, 0.0f, 0.5f, 1.0f);
1540 const tcu::Vec4 blend(0.5f, 0.0f, 0.25f, 0.5f);
1541 const tcu::Vec4 depthInit(0.5f, 0.0f, 0.0f, 1.0f);
1542 const tcu::Vec4 depthFull(1.0f, 0.0f, 0.0f, 1.0f);
1543 const tcu::Vec4 stencilInit(128.0f, 0.0f, 0.0f, 1.0f);
1544 const tcu::Vec4 stencilFull(255.0f, 0.0f, 0.0f, 1.0f);
1545 const tcu::Vec4 redUint(255.0f, 0.0f, 0.0f, 255.0f);
1546 const tcu::Vec4 greenUint(0.0f, 255.0f, 0.0f, 255.0f);
1547
1548 // Preinitialize attachments 0 and 1 to green.
1549 // Subpass 0: draw a red rectangle inside attachment 0.
1550 // Subpass 1: use the attachment 0 as input and add blue channel to it resulting in magenta. Write the results to
1551 // attachment 1.
1552 // After the render pass attachment 0 has undefined values inside the render area because of the shader writes with
1553 // store op 'none', but outside should still have the preinitialized value of green. Attachment 1 should have the
1554 // preinitialized green outside the render area and magenta inside.
1555 if (!groupParams->useSecondaryCmdBuffer)
1556 {
1557 TestParams params{
1558 {// std::vector<AttachmentParams> attachments;
1559 {ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT,
1560 VK_ATTACHMENT_LOAD_OP_LOAD,
1561 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1562 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1563 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1564 ATTACHMENT_INIT_PRE,
1565 {{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}}},
1566 {ATTACHMENT_USAGE_COLOR,
1567 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1568 VK_ATTACHMENT_STORE_OP_STORE,
1569 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1570 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1571 ATTACHMENT_INIT_PRE,
1572 {{VK_IMAGE_ASPECT_COLOR_BIT, true, magenta, true, green}}}},
1573 {// std::vector<SubpassParams> subpasses;
1574 {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u},
1575 {{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u}},
1576 groupParams, // const SharedGroupParams groupParams;
1577 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1578 false, // bool alphaBlend;
1579 ExtensionPreference::KHR,
1580 };
1581
1582 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_load_store_op_none", params));
1583 }
1584
1585 // Preinitialize color attachment to green. Use a render pass with load and store ops none, but
1586 // disable color writes using an empty color mask. The color attachment image should have the original
1587 // preinitialized value after the render pass.
1588 if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1589 {
1590 TestParams params{
1591 {// std::vector<AttachmentParams> attachments;
1592 {ATTACHMENT_USAGE_COLOR,
1593 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1594 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1595 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1596 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1597 ATTACHMENT_INIT_PRE,
1598 {{VK_IMAGE_ASPECT_COLOR_BIT, true, green, true, green}}}},
1599 {// std::vector<SubpassParams> subpasses;
1600 {{{0u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_COLOR_WRITE_OFF}}, 1u}},
1601 groupParams, // const SharedGroupParams groupParams;
1602 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1603 false, // bool alphaBlend;
1604 ExtensionPreference::EXT,
1605 };
1606
1607 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none_write_off", params));
1608 }
1609
1610 // Preinitialize color attachment to green. Use a render pass with load and store ops none, and
1611 // write a rectangle to the color buffer. The render area is undefined, but the outside area should
1612 // still have the preinitialized color.
1613 if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1614 {
1615 TestParams params{
1616 {// std::vector<AttachmentParams> attachments;
1617 {ATTACHMENT_USAGE_COLOR,
1618 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1619 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1620 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1621 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1622 ATTACHMENT_INIT_PRE,
1623 {{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}}}},
1624 {// std::vector<SubpassParams> subpasses;
1625 {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}},
1626 groupParams, // const SharedGroupParams groupParams;
1627 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1628 false, // bool alphaBlend;
1629 ExtensionPreference::KHR,
1630 };
1631
1632 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none", params));
1633 }
1634
1635 // Preinitialize color attachment to green. Use a subpass with no draw calls but instead
1636 // do an attachment clear command using dark blue color. Using load op none preserves the preinitialized
1637 // data and store op store causes the cleared blue render area to be present after the render pass.
1638 if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1639 {
1640 TestParams params{
1641 {// std::vector<AttachmentParams> attachments;
1642 {ATTACHMENT_USAGE_COLOR,
1643 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1644 VK_ATTACHMENT_STORE_OP_STORE,
1645 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1646 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1647 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1648 {{VK_IMAGE_ASPECT_COLOR_BIT, true, darkBlue, true, green}}}},
1649 {// std::vector<SubpassParams> subpasses;
1650 {{{0u, ATTACHMENT_USAGE_COLOR}}, 0u}},
1651 groupParams, // const SharedGroupParams groupParams;
1652 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1653 false, // bool alphaBlend;
1654 ExtensionPreference::EXT,
1655 };
1656
1657 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store", params));
1658 }
1659
1660 // Preinitialize color attachment to green. Use a subpass with a dark blue attachment clear followed
1661 // by an alpha blender draw. Load op none preserves the preinitialized data and store op store
1662 // keeps the blended color inside the render area after the render pass.
1663 if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1664 {
1665 TestParams params{
1666 {// std::vector<AttachmentParams> attachments;
1667 {ATTACHMENT_USAGE_COLOR,
1668 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1669 VK_ATTACHMENT_STORE_OP_STORE,
1670 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1671 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1672 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1673 {{VK_IMAGE_ASPECT_COLOR_BIT, true, blend, true, green}}}},
1674 {// std::vector<SubpassParams> subpasses;
1675 {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}},
1676 groupParams, // const SharedGroupParams groupParams;
1677 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1678 true, // bool alphaBlend;
1679 ExtensionPreference::KHR,
1680 };
1681
1682 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store_alphablend", params));
1683 }
1684
1685 // Preinitialize attachments 0 and 1 to green. Attachment 0 contents inside render area is undefined because load op 'none'.
1686 // Subpass 0: draw a red rectangle inside attachment 0 overwriting all undefined values.
1687 // Subpass 1: use the attachment 0 as input and add blue to it resulting in magenta. Write the results to attachment 1.
1688 // After the render pass attachment 0 contents inside the render area are undefined because of store op 'don't care',
1689 // but the outside area should still have the preinitialized content.
1690 // Attachment 1 should have the preinitialized green outside render area and magenta inside.
1691 if (!groupParams->useSecondaryCmdBuffer)
1692 {
1693 TestParams params{
1694 {// std::vector<AttachmentParams> attachments;
1695 {ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT,
1696 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1697 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1698 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1699 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1700 ATTACHMENT_INIT_PRE,
1701 {{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}}},
1702 {ATTACHMENT_USAGE_COLOR,
1703 VK_ATTACHMENT_LOAD_OP_LOAD,
1704 VK_ATTACHMENT_STORE_OP_STORE,
1705 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1706 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1707 ATTACHMENT_INIT_PRE,
1708 {{VK_IMAGE_ASPECT_COLOR_BIT, true, magenta, true, green}}}},
1709 {// std::vector<SubpassParams> subpasses;
1710 {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u},
1711 {{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u}},
1712 groupParams, // const SharedGroupParams groupParams;
1713 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1714 false, // bool alphaBlend;
1715 ExtensionPreference::EXT,
1716 };
1717
1718 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_dontcare", params));
1719 }
1720
1721 // Preinitialize color attachment to green. Use a render pass with load and store ops none for a multisample color
1722 // target. Write a red rectangle and check it ends up in the resolved buffer even though the multisample attachment
1723 // doesn't store the results.
1724 if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1725 {
1726 TestParams params{
1727 {// std::vector<AttachmentParams> attachments;
1728 {ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_MULTISAMPLE | ATTACHMENT_USAGE_INTEGER,
1729 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1730 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1731 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1732 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1733 ATTACHMENT_INIT_PRE,
1734 {}},
1735 {ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_RESOLVE_TARGET | ATTACHMENT_USAGE_INTEGER,
1736 VK_ATTACHMENT_LOAD_OP_LOAD,
1737 VK_ATTACHMENT_STORE_OP_STORE,
1738 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1739 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1740 ATTACHMENT_INIT_PRE,
1741 {{VK_IMAGE_ASPECT_COLOR_BIT, true, redUint, true, greenUint}}}},
1742 {// std::vector<SubpassParams> subpasses;
1743 {{{0u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_MULTISAMPLE | ATTACHMENT_USAGE_INTEGER},
1744 {1u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_RESOLVE_TARGET}},
1745 1u}},
1746 groupParams, // const SharedGroupParams groupParams;
1747 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1748 false, // bool alphaBlend;
1749 ExtensionPreference::KHR,
1750 };
1751
1752 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none_resolve", params));
1753 }
1754
1755 if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1756 {
1757 std::vector<VkFormat> formats = {VK_FORMAT_D16_UNORM, VK_FORMAT_D32_SFLOAT,
1758 VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT,
1759 VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_S8_UINT};
1760
1761 for (uint32_t f = 0; f < formats.size(); ++f)
1762 {
1763 const auto tcuFormat = mapVkFormat(formats[f]);
1764 const bool hasDepth = tcu::hasDepthComponent(tcuFormat.order);
1765 const bool hasStencil = tcu::hasStencilComponent(tcuFormat.order);
1766 const std::string formatName = getFormatCaseName(formats[f]);
1767
1768 // Preinitialize attachment 0 (color) to green and attachment 1 (depth) to 0.5.
1769 // Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update
1770 // depth buffer to 1.0.
1771 // This is followed by another draw with a blue rectangle using the same depth of 1.0. This time
1772 // the depth test fails and nothing is written.
1773 // After the renderpass the red color should remain inside the render area of the color buffer.
1774 // Store op 'none' for depth buffer makes the written values undefined, but the pixels outside
1775 // render area should still contain the original value of 0.5.
1776 if (hasDepth)
1777 {
1778 TestParams params{
1779 {// std::vector<AttachmentParams> attachments;
1780 {ATTACHMENT_USAGE_COLOR,
1781 VK_ATTACHMENT_LOAD_OP_LOAD,
1782 VK_ATTACHMENT_STORE_OP_STORE,
1783 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1784 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1785 ATTACHMENT_INIT_PRE,
1786 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1787 {ATTACHMENT_USAGE_DEPTH,
1788 VK_ATTACHMENT_LOAD_OP_LOAD,
1789 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1790 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1791 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1792 ATTACHMENT_INIT_PRE,
1793 {{VK_IMAGE_ASPECT_DEPTH_BIT, false, depthInit, true, depthInit}}}},
1794 {// std::vector<SubpassParams> subpasses;
1795 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 2u}},
1796 groupParams, // const SharedGroupParams groupParams;
1797 formats[f], // VkFormat depthStencilFormat;
1798 false, // bool alphaBlend;
1799 f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
1800 };
1801
1802 opNoneTests->addChild(
1803 new LoadStoreOpNoneTest(testCtx, "depth_" + formatName + "_load_op_load_store_op_none", params));
1804 }
1805
1806 // Preinitialize depth attachment to 0.5. Use a render pass with load and store ops none for the depth, but
1807 // disable depth test which also disables depth writes. The depth attachment should have the original
1808 // preinitialized value after the render pass.
1809 if (hasDepth)
1810 {
1811 TestParams params{
1812 {// std::vector<AttachmentParams> attachments;
1813 {ATTACHMENT_USAGE_COLOR,
1814 VK_ATTACHMENT_LOAD_OP_LOAD,
1815 VK_ATTACHMENT_STORE_OP_STORE,
1816 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1817 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1818 ATTACHMENT_INIT_PRE,
1819 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1820 {ATTACHMENT_USAGE_DEPTH,
1821 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1822 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1823 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1824 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1825 ATTACHMENT_INIT_PRE,
1826 {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit}}}},
1827 {// std::vector<SubpassParams> subpasses;
1828 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_DEPTH_TEST_OFF}},
1829 1u}},
1830 groupParams, // const SharedGroupParams groupParams;
1831 formats[f], // VkFormat depthStencilFormat;
1832 false, // bool alphaBlend;
1833 f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
1834 };
1835
1836 opNoneTests->addChild(new LoadStoreOpNoneTest(
1837 testCtx, "depth_" + formatName + "_load_op_none_store_op_none_write_off", params));
1838 }
1839
1840 // Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25
1841 // using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update
1842 // depth buffer to 1.0. After the renderpass the color buffer should have red inside the render area and depth should have the
1843 // shader updated value of 1.0.
1844 if (hasDepth)
1845 {
1846 TestParams params{
1847 {// std::vector<AttachmentParams> attachments;
1848 {ATTACHMENT_USAGE_COLOR,
1849 VK_ATTACHMENT_LOAD_OP_LOAD,
1850 VK_ATTACHMENT_STORE_OP_STORE,
1851 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1852 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1853 ATTACHMENT_INIT_PRE,
1854 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1855 {ATTACHMENT_USAGE_DEPTH,
1856 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1857 VK_ATTACHMENT_STORE_OP_STORE,
1858 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1859 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1860 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1861 {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit}}}},
1862 {// std::vector<SubpassParams> subpasses;
1863 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u}},
1864 groupParams, // const SharedGroupParams groupParams;
1865 formats[f], // VkFormat depthStencilFormat;
1866 false, // bool alphaBlend;
1867 f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
1868 };
1869
1870 opNoneTests->addChild(
1871 new LoadStoreOpNoneTest(testCtx, "depth_" + formatName + "_load_op_none_store_op_store", params));
1872 }
1873
1874 // Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25
1875 // using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater' which will pass.
1876 // After the renderpass the color buffer should have red inside the render area. Depth buffer contents inside render
1877 // area is undefined because of store op 'don't care', but the outside should have the original value of 0.5.
1878 if (hasDepth)
1879 {
1880 TestParams params{
1881 {// std::vector<AttachmentParams> attachments;
1882 {ATTACHMENT_USAGE_COLOR,
1883 VK_ATTACHMENT_LOAD_OP_LOAD,
1884 VK_ATTACHMENT_STORE_OP_STORE,
1885 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1886 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1887 ATTACHMENT_INIT_PRE,
1888 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1889 {ATTACHMENT_USAGE_DEPTH,
1890 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1891 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1892 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1893 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1894 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1895 {{VK_IMAGE_ASPECT_DEPTH_BIT, false, depthFull, true, depthInit}}}},
1896 {// std::vector<SubpassParams> subpasses;
1897 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u}},
1898 groupParams, // const SharedGroupParams groupParams;
1899 formats[f], // VkFormat depthStencilFormat;
1900 false, // bool alphaBlend;
1901 f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
1902 };
1903
1904 opNoneTests->addChild(new LoadStoreOpNoneTest(
1905 testCtx, "depth_" + formatName + "_load_op_none_store_op_dontcare", params));
1906 }
1907
1908 // Preinitialize attachment 0 (color) to green and attachment 1 (stencil) to 128.
1909 // Draw a red rectangle using stencil testing with compare op 'greater' and reference of 255. The stencil test
1910 // will pass. This is followed by another draw with a blue rectangle using the same stencil settings. This time
1911 // the stencil test fails and nothing is written.
1912 // After the renderpass the red color should remain inside the render area of the color buffer.
1913 // Store op 'none' for stencil buffer makes the written values undefined, but the pixels outside
1914 // render area should still contain the original value of 128.
1915 if (hasStencil)
1916 {
1917 TestParams params{
1918 {// std::vector<AttachmentParams> attachments;
1919 {ATTACHMENT_USAGE_COLOR,
1920 VK_ATTACHMENT_LOAD_OP_LOAD,
1921 VK_ATTACHMENT_STORE_OP_STORE,
1922 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1923 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1924 ATTACHMENT_INIT_PRE,
1925 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1926 {ATTACHMENT_USAGE_STENCIL,
1927 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1928 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1929 VK_ATTACHMENT_LOAD_OP_LOAD,
1930 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1931 ATTACHMENT_INIT_PRE,
1932 {{VK_IMAGE_ASPECT_STENCIL_BIT, false, stencilInit, true, stencilInit}}}},
1933 {// std::vector<SubpassParams> subpasses;
1934 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 2u}},
1935 groupParams, // const SharedGroupParams groupParams;
1936 formats[f], // VkFormat depthStencilFormat;
1937 false, // bool alphaBlend;
1938 f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
1939 };
1940
1941 opNoneTests->addChild(
1942 new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_load_store_op_none", params));
1943 }
1944
1945 // Preinitialize stencil attachment to 128. Use a render pass with load and store ops none for the stencil, but
1946 // disable stencil test which also disables stencil writes. The stencil attachment should have the original
1947 // preinitialized value after the render pass.
1948 if (hasStencil)
1949 {
1950 TestParams params{
1951 {// std::vector<AttachmentParams> attachments;
1952 {ATTACHMENT_USAGE_COLOR,
1953 VK_ATTACHMENT_LOAD_OP_LOAD,
1954 VK_ATTACHMENT_STORE_OP_STORE,
1955 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1956 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1957 ATTACHMENT_INIT_PRE,
1958 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1959 {ATTACHMENT_USAGE_STENCIL,
1960 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1961 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1962 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1963 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1964 ATTACHMENT_INIT_PRE,
1965 {{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit}}}},
1966 {// std::vector<SubpassParams> subpasses;
1967 {{{0u, ATTACHMENT_USAGE_COLOR},
1968 {1u, ATTACHMENT_USAGE_STENCIL | ATTACHMENT_USAGE_STENCIL_TEST_OFF |
1969 ATTACHMENT_USAGE_DEPTH_TEST_OFF}},
1970 1u}},
1971 groupParams, // const SharedGroupParams groupParams;
1972 formats[f], // VkFormat depthStencilFormat;
1973 false, // bool alphaBlend;
1974 f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
1975 };
1976
1977 opNoneTests->addChild(new LoadStoreOpNoneTest(
1978 testCtx, "stencil_" + formatName + "_load_op_none_store_op_none_write_off", params));
1979 }
1980
1981 // Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64
1982 // using cmdClearAttachments. Draw a red rectangle using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update
1983 // stencil buffer to 255. After the renderpass the color buffer should have red inside the render area and stencil should have the
1984 // shader updated value of 255.
1985 if (hasStencil)
1986 {
1987 TestParams params{
1988 {// std::vector<AttachmentParams> attachments;
1989 {ATTACHMENT_USAGE_COLOR,
1990 VK_ATTACHMENT_LOAD_OP_LOAD,
1991 VK_ATTACHMENT_STORE_OP_STORE,
1992 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1993 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1994 ATTACHMENT_INIT_PRE,
1995 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1996 {ATTACHMENT_USAGE_STENCIL,
1997 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1998 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1999 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2000 VK_ATTACHMENT_STORE_OP_STORE,
2001 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
2002 {{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit}}}},
2003 {// std::vector<SubpassParams> subpasses;
2004 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u}},
2005 groupParams, // const SharedGroupParams groupParams;
2006 formats[f], // VkFormat depthStencilFormat;
2007 false, // bool alphaBlend;
2008 f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
2009 };
2010
2011 opNoneTests->addChild(
2012 new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_none_store_op_store", params));
2013 }
2014
2015 // Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64
2016 // using cmdClearAttachments. Draw a red rectangle using stencil reference 255 and stencil op 'greater' which will pass.
2017 // After the renderpass the color buffer should have red inside the render area. Stencil buffer contents inside render
2018 // are is undefined because of store op 'don't care', but the outside should have the original value of 128.
2019 if (hasStencil)
2020 {
2021 TestParams params{
2022 {// std::vector<AttachmentParams> attachments;
2023 {ATTACHMENT_USAGE_COLOR,
2024 VK_ATTACHMENT_LOAD_OP_LOAD,
2025 VK_ATTACHMENT_STORE_OP_STORE,
2026 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2027 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2028 ATTACHMENT_INIT_PRE,
2029 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2030 {ATTACHMENT_USAGE_STENCIL,
2031 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2032 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2033 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2034 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2035 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
2036 {{VK_IMAGE_ASPECT_STENCIL_BIT, false, stencilFull, true, stencilInit}}}},
2037 {// std::vector<SubpassParams> subpasses;
2038 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u}},
2039 groupParams, // const SharedGroupParams groupParams;
2040 formats[f], // VkFormat depthStencilFormat;
2041 false, // bool alphaBlend;
2042 f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
2043 };
2044
2045 opNoneTests->addChild(new LoadStoreOpNoneTest(
2046 testCtx, "stencil_" + formatName + "_load_op_none_store_op_dontcare", params));
2047 }
2048
2049 // Preinitialize attachment 0 (color) to green and depth stencil buffer depth aspect to 0.5 and stencil aspect to 128. Draw a red
2050 // rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update depth buffer to 1.0. After the renderpass the
2051 // color buffer should have red inside the render area and depth should have the shader updated value of 1.0. Stencil has load and
2052 // store ops none, and stencil writes are disabled by disabling stencil test. Therefore, stencil should not be modified even when
2053 // the depth aspect is written.
2054 if (hasDepth && hasStencil)
2055 {
2056 TestParams params{
2057 {// std::vector<AttachmentParams> attachments;
2058 {ATTACHMENT_USAGE_COLOR,
2059 VK_ATTACHMENT_LOAD_OP_LOAD,
2060 VK_ATTACHMENT_STORE_OP_STORE,
2061 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2062 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2063 ATTACHMENT_INIT_PRE,
2064 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2065 {ATTACHMENT_USAGE_DEPTH_STENCIL,
2066 VK_ATTACHMENT_LOAD_OP_LOAD,
2067 VK_ATTACHMENT_STORE_OP_STORE,
2068 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2069 VK_ATTACHMENT_STORE_OP_NONE_EXT,
2070 ATTACHMENT_INIT_PRE,
2071 {
2072 {VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit},
2073 {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit},
2074 }}},
2075 {// std::vector<SubpassParams> subpasses;
2076 {{{0u, ATTACHMENT_USAGE_COLOR},
2077 {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_STENCIL_TEST_OFF}},
2078 1u}},
2079 groupParams, // const SharedGroupParams groupParams;
2080 formats[f], // VkFormat depthStencilFormat;
2081 false, // bool alphaBlend;
2082 f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
2083 };
2084
2085 opNoneTests->addChild(new LoadStoreOpNoneTest(
2086 testCtx,
2087 "depthstencil_" + formatName +
2088 "_load_op_depth_load_stencil_none_store_op_depth_store_stencil_none_stencil_test_off",
2089 params));
2090 }
2091
2092 // Preinitialize attachment 0 (color) to green and depth stencil buffer stencil aspect to 128 and depth aspect to 0.5. Draw a red rectangle
2093 // using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update stencil buffer to 255. After the renderpass
2094 // the color buffer should have red inside the render area and stencil should have the shader updated value of 255. Depth has load and store
2095 // ops none, and depth writes are disabled by having depth test off. Therefore, depth should not be modified even when the stencil aspect is
2096 // written.
2097 if (hasDepth && hasStencil)
2098 {
2099 TestParams params{
2100 {// std::vector<AttachmentParams> attachments;
2101 {ATTACHMENT_USAGE_COLOR,
2102 VK_ATTACHMENT_LOAD_OP_LOAD,
2103 VK_ATTACHMENT_STORE_OP_STORE,
2104 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2105 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2106 ATTACHMENT_INIT_PRE,
2107 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2108 {ATTACHMENT_USAGE_DEPTH_STENCIL,
2109 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2110 VK_ATTACHMENT_STORE_OP_NONE_EXT,
2111 VK_ATTACHMENT_LOAD_OP_LOAD,
2112 VK_ATTACHMENT_STORE_OP_STORE,
2113 ATTACHMENT_INIT_PRE,
2114 {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit},
2115 {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit}}}},
2116 {// std::vector<SubpassParams> subpasses;
2117 {{{0u, ATTACHMENT_USAGE_COLOR},
2118 {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_DEPTH_TEST_OFF}},
2119 1u}},
2120 groupParams, // const SharedGroupParams groupParams;
2121 formats[f], // VkFormat depthStencilFormat;
2122 false, // bool alphaBlend;
2123 f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
2124 };
2125
2126 opNoneTests->addChild(new LoadStoreOpNoneTest(
2127 testCtx,
2128 "depthstencil_" + formatName +
2129 "_load_op_depth_none_stencil_load_store_op_depth_none_stencil_store_depth_test_off",
2130 params));
2131 }
2132
2133 // Preinitialize attachment 0 (color) to green and depth stencil buffer depth aspect to 0.5 and stencil aspect to 128. Draw a red
2134 // rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update depth buffer to 1.0. After the renderpass the
2135 // color buffer should have red inside the render area and depth should have the shader updated value of 1.0. Stencil has load and
2136 // store ops none, and stencil writes are disabled. Therefore, stencil should not be modified even when the depth aspect is written.
2137 if (hasDepth && hasStencil)
2138 {
2139 TestParams params{
2140 {// std::vector<AttachmentParams> attachments;
2141 {ATTACHMENT_USAGE_COLOR,
2142 VK_ATTACHMENT_LOAD_OP_LOAD,
2143 VK_ATTACHMENT_STORE_OP_STORE,
2144 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2145 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2146 ATTACHMENT_INIT_PRE,
2147 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2148 {ATTACHMENT_USAGE_DEPTH_STENCIL,
2149 VK_ATTACHMENT_LOAD_OP_LOAD,
2150 VK_ATTACHMENT_STORE_OP_STORE,
2151 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2152 VK_ATTACHMENT_STORE_OP_NONE_EXT,
2153 ATTACHMENT_INIT_PRE,
2154 {
2155 {VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit},
2156 {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit},
2157 }}},
2158 {// std::vector<SubpassParams> subpasses;
2159 {{{0u, ATTACHMENT_USAGE_COLOR},
2160 {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_STENCIL_WRITE_OFF}},
2161 1u}},
2162 groupParams, // const SharedGroupParams groupParams;
2163 formats[f], // VkFormat depthStencilFormat;
2164 false, // bool alphaBlend;
2165 f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
2166 };
2167
2168 opNoneTests->addChild(new LoadStoreOpNoneTest(
2169 testCtx,
2170 "depthstencil_" + formatName +
2171 "_load_op_depth_load_stencil_none_store_op_depth_store_stencil_none_stencil_write_off",
2172 params));
2173 }
2174
2175 // Preinitialize attachment 0 (color) to green and depth stencil buffer stencil aspect to 128 and depth aspect to 0.5. Draw a red rectangle
2176 // using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update stencil buffer to 255. After the renderpass
2177 // the color buffer should have red inside the render area and stencil should have the shader updated value of 255. Depth has load and store
2178 // ops none, the depth buffer contents will be undefined and depth test is enabled but op will be 'always' so depth testing will pass. Depth
2179 // writes are disabled, so depth should not be modified even when the stencil aspect is written.
2180 if (hasDepth && hasStencil)
2181 {
2182 TestParams params{
2183 {// std::vector<AttachmentParams> attachments;
2184 {ATTACHMENT_USAGE_COLOR,
2185 VK_ATTACHMENT_LOAD_OP_LOAD,
2186 VK_ATTACHMENT_STORE_OP_STORE,
2187 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2188 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2189 ATTACHMENT_INIT_PRE,
2190 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2191 {ATTACHMENT_USAGE_DEPTH_STENCIL,
2192 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2193 VK_ATTACHMENT_STORE_OP_NONE_EXT,
2194 VK_ATTACHMENT_LOAD_OP_LOAD,
2195 VK_ATTACHMENT_STORE_OP_STORE,
2196 ATTACHMENT_INIT_PRE,
2197 {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit},
2198 {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit}}}},
2199 {// std::vector<SubpassParams> subpasses;
2200 {{{0u, ATTACHMENT_USAGE_COLOR},
2201 {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_DEPTH_WRITE_OFF}},
2202 1u}},
2203 groupParams, // const SharedGroupParams groupParams;
2204 formats[f], // VkFormat depthStencilFormat;
2205 false, // bool alphaBlend;
2206 f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
2207 };
2208
2209 opNoneTests->addChild(new LoadStoreOpNoneTest(
2210 testCtx,
2211 "depthstencil_" + formatName +
2212 "_load_op_depth_none_stencil_load_store_op_depth_none_stencil_store_depth_write_off",
2213 params));
2214 }
2215 } // for over DS formats
2216 }
2217 return opNoneTests.release();
2218 }
2219
2220 } // namespace renderpass
2221 } // namespace vkt
2222