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 DE_NULL, // 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({DE_NULL, 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({DE_NULL, 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({DE_NULL, 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({DE_NULL, ref.idx, layout, aspectMask});
317 hasInputAttachment = true;
318 }
319 }
320
321 const SubpassDesc subpassDescription = {
322 DE_NULL,
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 DE_NULL :
329 refs.inputAttachmentRefs.data(), // const VkAttachmentReference* pInputAttachments
330 (uint32_t)refs.colorAttachmentRefs.size(), // uint32_t colorAttachmentCount
331 refs.colorAttachmentRefs.empty() ?
332 DE_NULL :
333 refs.colorAttachmentRefs.data(), // const VkAttachmentReference* pColorAttachments
334 refs.resolveAttachmentRefs.empty() ?
335 DE_NULL :
336 refs.resolveAttachmentRefs.data(), // const VkAttachmentReference* pResolveAttachments
337 refs.depthStencilAttachmentRefs.empty() ?
338 DE_NULL :
339 refs.depthStencilAttachmentRefs.data(), // const VkAttachmentReference* pDepthStencilAttachment
340 0u, // uint32_t preserveAttachmentCount
341 DE_NULL // 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 DE_NULL, // 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 DE_NULL, // 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 : DE_NULL, // const VkSubpassDependency* pDependencies
370 0u, // uint32_t correlatedViewMaskCount
371 DE_NULL // 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(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
578 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
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 DE_NULL, // 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 DE_NULL // 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 DE_NULL, // const void* pNext;
611 DE_NULL, // VkImageView imageView;
612 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
613 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
614 DE_NULL, // 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 DE_NULL, // const void* pNext;
624 DE_NULL, // VkImageView imageView;
625 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, // VkImageLayout imageLayout;
626 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
627 DE_NULL, // 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 DE_NULL, // 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 DE_NULL, // const void* pNext;
674 *imageViews[i], // VkImageView imageView;
675 imageLayout, // VkImageLayout imageLayout;
676 VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode;
677 DE_NULL, // 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 DE_NULL, // 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 DE_NULL, // 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 DE_NULL,
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 : DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment;
730 useStencil ? &stencilAttachment : DE_NULL // 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, DE_NULL, 0u, DE_NULL);
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.cmdSetRenderingAttachmentLocationsKHR(cmdBuffer, &renderingAttachmentLocationInfo);
860 vk.cmdSetRenderingInputAttachmentIndicesKHR(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, DE_NULL);
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 DE_NULL, // 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 DE_NULL, // 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 DE_NULL, // 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 DE_NULL, // 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 DE_NULL // 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 DE_NULL, // const void* pNext
1157 0u, // VkDescriptorSetLayoutCreateFlags flags
1158 (uint32_t)layoutBindings.size(), // uint32_t bindingCount
1159 layoutBindings.empty() ? DE_NULL :
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 DE_NULL, // 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 DE_NULL, // 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 DE_NULL, // 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 DE_NULL, // const VkDescriptorBufferInfo* pBufferInfo
1207 DE_NULL // const VkBufferView* pTexelBufferView
1208 };
1209 vk.updateDescriptorSets(vkDevice, 1u, &descriptorWrite, 0u, DE_NULL);
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 DE_NULL, // 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 = (*m_renderPass == DE_NULL) ? static_cast<uint32_t>(colorVector.size()) : 1u;
1276 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentState(
1277 attachmentCount,
1278 {
1279 false, // VkBool32 blendEnable
1280 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor
1281 VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA, // VkBlendFactor dstColorBlendFactor
1282 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp
1283 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor
1284 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor
1285 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp
1286 writeMask // VkColorComponentFlags colorWriteMask
1287 });
1288
1289 if (m_testParams.alphaBlend)
1290 {
1291 uint32_t attachmentIndex = (*m_renderPass == DE_NULL) ? (uint32_t)pipelines.size() : 0u;
1292 colorBlendAttachmentState[attachmentIndex].blendEnable = true;
1293 }
1294
1295 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams{
1296 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType
1297 DE_NULL, // const void* pNext
1298 0u, // VkPipelineColorBlendStateCreateFlags flags
1299 VK_FALSE, // VkBool32 logicOpEnable
1300 VK_LOGIC_OP_CLEAR, // VkLogicOp logicOp
1301 attachmentCount, // uint32_t attachmentCount
1302 colorBlendAttachmentState.data(), // const VkPipelineColorBlendAttachmentState* pAttachments
1303 {0.0f, 0.0f, 0.0f, 0.0f} // float blendConstants[4]
1304 };
1305
1306 const VkStencilOpState stencilOpState = {
1307 VK_STENCIL_OP_KEEP, // VkStencilOp failOp
1308 stencilWrite ? VK_STENCIL_OP_REPLACE : VK_STENCIL_OP_KEEP, // VkStencilOp passOp
1309 VK_STENCIL_OP_KEEP, // VkStencilOp depthFailOp
1310 stencilCompareOp, // VkCompareOp compareOp
1311 0xff, // uint32_t compareMask
1312 0xff, // uint32_t writeMask
1313 0xff // uint32_t reference
1314 };
1315
1316 const VkPipelineDepthStencilStateCreateInfo depthStencilStateParams = {
1317 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
1318 DE_NULL, // const void* pNext
1319 0u, // VkPipelineDepthStencilStateCreateFlags flags
1320 depthTest, // VkBool32 depthTestEnable
1321 depthWrite ? VK_TRUE : VK_FALSE, // VkBool32 depthWriteEnable
1322 depthCompareOp, // VkCompareOp depthCompareOp
1323 VK_FALSE, // VkBool32 depthBoundsTestEnable
1324 stencilTest, // VkBool32 stencilTestEnable
1325 stencilOpState, // VkStencilOpState front
1326 stencilOpState, // VkStencilOpState back
1327 0.0f, // float minDepthBounds
1328 1.0f, // float maxDepthBounds
1329 };
1330
1331 const VkPipelineMultisampleStateCreateInfo multisampleStateParams = {
1332 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType
1333 DE_NULL, // const void* pNext
1334 0u, // VkPipelineMultisampleStateCreateFlags flags
1335 multisample ? VK_SAMPLE_COUNT_4_BIT :
1336 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples
1337 VK_FALSE, // VkBool32 sampleShadingEnable
1338 1.0f, // float minSampleShading
1339 DE_NULL, // const VkSampleMask* pSampleMask
1340 VK_FALSE, // VkBool32 alphaToCoverageEnable
1341 VK_FALSE // VkBool32 alphaToOneEnable
1342 };
1343
1344 const std::vector<VkViewport> viewports(1, makeViewport(m_imageSize));
1345 const std::vector<VkRect2D> scissors(1, makeRect2D(m_renderSize));
1346 ShaderWrapper *fragShader = &fragmentShaderModule;
1347
1348 if (numInputAttachments > 0u)
1349 fragShader = &fragmentShaderModuleInput;
1350 else if (uintColorBuffer)
1351 fragShader = &fragmentShaderModuleUint;
1352 else if (m_testParams.alphaBlend)
1353 fragShader = &fragmentShaderModuleBlend;
1354
1355 VkRenderingAttachmentLocationInfoKHR renderingAttachmentLocationInfo = initVulkanStructure();
1356 VkRenderingInputAttachmentIndexInfoKHR renderingInputAttachmentIndexInfo = initVulkanStructure();
1357 PipelineRenderingCreateInfoWrapper renderingCreateInfoWrapper;
1358 RenderingAttachmentLocationInfoWrapper renderingAttachmentLocationInfoWrapper;
1359 RenderingInputAttachmentIndexInfoWrapper renderingInputAttachmentIndexInfoWrapper;
1360 std::vector<uint32_t> colorAttachmentLocations(colorVector.size(), VK_ATTACHMENT_UNUSED);
1361 std::vector<uint32_t> colorAttachmentInputs(colorVector.size(), VK_ATTACHMENT_UNUSED);
1362
1363 if (isDynamicRendering)
1364 {
1365 renderingCreateInfo.colorAttachmentCount = static_cast<uint32_t>(colorVector.size());
1366 renderingCreateInfo.pColorAttachmentFormats = colorVector.data();
1367 renderingCreateInfoWrapper.ptr = &renderingCreateInfo;
1368
1369 if (numInputAttachments > 0u)
1370 {
1371 uint32_t locationIndex = 0u;
1372 uint32_t inputIndex = 0u;
1373 for (uint32_t i = 0; i < (uint32_t)subpass.attachmentRefs.size(); ++i)
1374 {
1375 if (subpass.attachmentRefs[i].usage == ATTACHMENT_USAGE_COLOR)
1376 colorAttachmentLocations[i] = locationIndex++;
1377 else if (subpass.attachmentRefs[i].usage == ATTACHMENT_USAGE_INPUT)
1378 colorAttachmentInputs[i] = inputIndex++;
1379 }
1380
1381 renderingAttachmentLocationInfo.colorAttachmentCount = renderingCreateInfo.colorAttachmentCount;
1382 renderingAttachmentLocationInfo.pColorAttachmentLocations = colorAttachmentLocations.data();
1383 renderingAttachmentLocationInfoWrapper.ptr = &renderingAttachmentLocationInfo;
1384 renderingInputAttachmentIndexInfo.colorAttachmentCount = renderingCreateInfo.colorAttachmentCount;
1385 renderingInputAttachmentIndexInfo.pColorAttachmentInputIndices = colorAttachmentInputs.data();
1386 renderingInputAttachmentIndexInfoWrapper.ptr = &renderingInputAttachmentIndexInfo;
1387 }
1388 }
1389
1390 const auto &pipelineLayout = pipelineLayouts[subpassIdx];
1391 pipelines.emplace_back(m_context.getInstanceInterface(), vk, m_context.getPhysicalDevice(), vkDevice,
1392 m_context.getDeviceExtensions(), m_testParams.groupParams->pipelineConstructionType);
1393 pipelines.back()
1394 .setDefaultRasterizationState()
1395 .setupVertexInputState(&vertexInputStateParams)
1396 .setupPreRasterizationShaderState(viewports, scissors, pipelineLayout, *m_renderPass, subpassIdx,
1397 vertexShaderModule, 0u, ShaderWrapper(), ShaderWrapper(),
1398 ShaderWrapper(), DE_NULL, DE_NULL, renderingCreateInfoWrapper)
1399 .setupFragmentShaderState(pipelineLayout, *m_renderPass, subpassIdx, *fragShader,
1400 &depthStencilStateParams, &multisampleStateParams, 0, 0, {},
1401 renderingInputAttachmentIndexInfoWrapper)
1402 .setupFragmentOutputState(*m_renderPass, subpassIdx, &colorBlendStateParams, &multisampleStateParams, 0,
1403 {}, renderingAttachmentLocationInfoWrapper)
1404 .setMonolithicPipelineLayout(pipelineLayout)
1405 .buildPipeline();
1406 }
1407 }
1408
1409 // Create vertex buffer.
1410 {
1411 const VkBufferCreateInfo vertexBufferParams = {
1412 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType
1413 DE_NULL, // const void* pNext
1414 0u, // VkBufferCreateFlags flags
1415 (VkDeviceSize)(sizeof(Vertex4RGBA) * m_vertices.size()), // VkDeviceSize size
1416 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage
1417 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode
1418 1u, // uint32_t queueFamilyIndexCount
1419 &queueFamilyIndex // const uint32_t* pQueueFamilyIndices
1420 };
1421
1422 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
1423 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer),
1424 MemoryRequirement::HostVisible);
1425
1426 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(),
1427 m_vertexBufferAlloc->getOffset()));
1428
1429 // Upload vertex data.
1430 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), m_vertices.size() * sizeof(Vertex4RGBA));
1431 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
1432 }
1433
1434 // Create command pool.
1435 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
1436
1437 // Create command buffer.
1438 if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS_LEGACY)
1439 createCommandBuffer<RenderpassSubpass1>(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines);
1440 else if (m_testParams.groupParams->renderingType == RENDERING_TYPE_RENDERPASS2)
1441 createCommandBuffer<RenderpassSubpass2>(vk, vkDevice, descriptorSets, pipelineLayouts, pipelines);
1442 else
1443 createCommandBuffer(vk, vkDevice, imageViews, descriptorSets, pipelineLayouts, pipelines);
1444
1445 // Submit commands.
1446 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1447
1448 bool pass = true;
1449
1450 // Verify selected attachments.
1451 for (size_t i = 0; i < m_testParams.attachments.size(); i++)
1452 {
1453 bool transitioned = false;
1454 for (const auto &verify : m_testParams.attachments[i].verifyAspects)
1455 {
1456 de::MovePtr<tcu::TextureLevel> textureLevelResult;
1457
1458 SimpleAllocator allocator(
1459 vk, vkDevice,
1460 getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
1461 VkFormat format = getFormat(m_testParams.attachments[i].usage, m_testParams.depthStencilFormat);
1462
1463 if (verify.aspect == VK_IMAGE_ASPECT_DEPTH_BIT)
1464 {
1465 VkImageLayout layout = (isDynamicRendering && !transitioned) ?
1466 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
1467 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1468 textureLevelResult = pipeline::readDepthAttachment(
1469 vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i],
1470 m_testParams.depthStencilFormat, m_imageSize, layout);
1471 transitioned = true;
1472 }
1473 else if (verify.aspect == VK_IMAGE_ASPECT_STENCIL_BIT)
1474 {
1475 VkImageLayout layout = (isDynamicRendering && !transitioned) ?
1476 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
1477 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1478 textureLevelResult = pipeline::readStencilAttachment(
1479 vk, vkDevice, queue, queueFamilyIndex, allocator, *attachmentImages[i],
1480 m_testParams.depthStencilFormat, m_imageSize, layout);
1481 transitioned = true;
1482 }
1483 else
1484 {
1485 DE_ASSERT(verify.aspect == VK_IMAGE_ASPECT_COLOR_BIT);
1486 VkImageLayout layout = VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL;
1487 if (isDynamicRendering && !transitioned)
1488 layout = (m_testParams.attachments[i].usage & ATTACHMENT_USAGE_INPUT) ?
1489 VK_IMAGE_LAYOUT_RENDERING_LOCAL_READ_KHR :
1490 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1491 textureLevelResult = pipeline::readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, allocator,
1492 *attachmentImages[i], format, m_imageSize, layout);
1493 transitioned = true;
1494 }
1495
1496 const tcu::ConstPixelBufferAccess &access = textureLevelResult->getAccess();
1497
1498 // Log attachment contents
1499 m_context.getTestContext().getLog()
1500 << tcu::TestLog::ImageSet("Attachment " + de::toString(i), "")
1501 << tcu::TestLog::Image("Attachment " + de::toString(i), "", access) << tcu::TestLog::EndImageSet;
1502
1503 for (int y = 0; y < access.getHeight(); y++)
1504 for (int x = 0; x < access.getWidth(); x++)
1505 {
1506 const bool inner = x < (int)m_renderSize.x() && y < (int)m_renderSize.y();
1507
1508 if (inner && !verify.verifyInner)
1509 continue;
1510 if (!inner && !verify.verifyOuter)
1511 continue;
1512
1513 const tcu::Vec4 ref = inner ? verify.innerRef : verify.outerRef;
1514 const tcu::Vec4 p = access.getPixel(x, y);
1515
1516 for (int c = 0; c < 4; c++)
1517 if (fabs(p[c] - ref[c]) > 0.01f)
1518 pass = false;
1519 }
1520 }
1521 }
1522
1523 if (pass)
1524 return tcu::TestStatus::pass("Pass");
1525 else
1526 return tcu::TestStatus::fail("Fail");
1527 }
1528
1529 } // namespace
1530
createRenderPassLoadStoreOpNoneTests(tcu::TestContext & testCtx,const SharedGroupParams groupParams)1531 tcu::TestCaseGroup *createRenderPassLoadStoreOpNoneTests(tcu::TestContext &testCtx, const SharedGroupParams groupParams)
1532 {
1533 de::MovePtr<tcu::TestCaseGroup> opNoneTests(new tcu::TestCaseGroup(testCtx, "load_store_op_none"));
1534
1535 const tcu::Vec4 red(1.0f, 0.0f, 0.0f, 1.0f);
1536 const tcu::Vec4 green(0.0f, 1.0f, 0.0f, 1.0f);
1537 const tcu::Vec4 magenta(1.0f, 0.0f, 1.0f, 1.0f);
1538 const tcu::Vec4 darkBlue(0.0f, 0.0f, 0.5f, 1.0f);
1539 const tcu::Vec4 blend(0.5f, 0.0f, 0.25f, 0.5f);
1540 const tcu::Vec4 depthInit(0.5f, 0.0f, 0.0f, 1.0f);
1541 const tcu::Vec4 depthFull(1.0f, 0.0f, 0.0f, 1.0f);
1542 const tcu::Vec4 stencilInit(128.0f, 0.0f, 0.0f, 1.0f);
1543 const tcu::Vec4 stencilFull(255.0f, 0.0f, 0.0f, 1.0f);
1544 const tcu::Vec4 redUint(255.0f, 0.0f, 0.0f, 255.0f);
1545 const tcu::Vec4 greenUint(0.0f, 255.0f, 0.0f, 255.0f);
1546
1547 // Preinitialize attachments 0 and 1 to green.
1548 // Subpass 0: draw a red rectangle inside attachment 0.
1549 // Subpass 1: use the attachment 0 as input and add blue channel to it resulting in magenta. Write the results to
1550 // attachment 1.
1551 // After the render pass attachment 0 has undefined values inside the render area because of the shader writes with
1552 // store op 'none', but outside should still have the preinitialized value of green. Attachment 1 should have the
1553 // preinitialized green outside the render area and magenta inside.
1554 if (!groupParams->useSecondaryCmdBuffer)
1555 {
1556 TestParams params{
1557 {// std::vector<AttachmentParams> attachments;
1558 {ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT,
1559 VK_ATTACHMENT_LOAD_OP_LOAD,
1560 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1561 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1562 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1563 ATTACHMENT_INIT_PRE,
1564 {{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}}},
1565 {ATTACHMENT_USAGE_COLOR,
1566 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1567 VK_ATTACHMENT_STORE_OP_STORE,
1568 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1569 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1570 ATTACHMENT_INIT_PRE,
1571 {{VK_IMAGE_ASPECT_COLOR_BIT, true, magenta, true, green}}}},
1572 {// std::vector<SubpassParams> subpasses;
1573 {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u},
1574 {{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u}},
1575 groupParams, // const SharedGroupParams groupParams;
1576 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1577 false, // bool alphaBlend;
1578 ExtensionPreference::KHR,
1579 };
1580
1581 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_load_store_op_none", params));
1582 }
1583
1584 // Preinitialize color attachment to green. Use a render pass with load and store ops none, but
1585 // disable color writes using an empty color mask. The color attachment image should have the original
1586 // preinitialized value after the render pass.
1587 if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1588 {
1589 TestParams params{
1590 {// std::vector<AttachmentParams> attachments;
1591 {ATTACHMENT_USAGE_COLOR,
1592 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1593 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1594 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1595 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1596 ATTACHMENT_INIT_PRE,
1597 {{VK_IMAGE_ASPECT_COLOR_BIT, true, green, true, green}}}},
1598 {// std::vector<SubpassParams> subpasses;
1599 {{{0u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_COLOR_WRITE_OFF}}, 1u}},
1600 groupParams, // const SharedGroupParams groupParams;
1601 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1602 false, // bool alphaBlend;
1603 ExtensionPreference::EXT,
1604 };
1605
1606 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none_write_off", params));
1607 }
1608
1609 // Preinitialize color attachment to green. Use a render pass with load and store ops none, and
1610 // write a rectangle to the color buffer. The render area is undefined, but the outside area should
1611 // still have the preinitialized color.
1612 if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1613 {
1614 TestParams params{
1615 {// std::vector<AttachmentParams> attachments;
1616 {ATTACHMENT_USAGE_COLOR,
1617 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1618 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1619 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1620 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1621 ATTACHMENT_INIT_PRE,
1622 {{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}}}},
1623 {// std::vector<SubpassParams> subpasses;
1624 {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}},
1625 groupParams, // const SharedGroupParams groupParams;
1626 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1627 false, // bool alphaBlend;
1628 ExtensionPreference::KHR,
1629 };
1630
1631 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none", params));
1632 }
1633
1634 // Preinitialize color attachment to green. Use a subpass with no draw calls but instead
1635 // do an attachment clear command using dark blue color. Using load op none preserves the preinitialized
1636 // data and store op store causes the cleared blue render area to be present after the render pass.
1637 if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1638 {
1639 TestParams params{
1640 {// std::vector<AttachmentParams> attachments;
1641 {ATTACHMENT_USAGE_COLOR,
1642 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1643 VK_ATTACHMENT_STORE_OP_STORE,
1644 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1645 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1646 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1647 {{VK_IMAGE_ASPECT_COLOR_BIT, true, darkBlue, true, green}}}},
1648 {// std::vector<SubpassParams> subpasses;
1649 {{{0u, ATTACHMENT_USAGE_COLOR}}, 0u}},
1650 groupParams, // const SharedGroupParams groupParams;
1651 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1652 false, // bool alphaBlend;
1653 ExtensionPreference::EXT,
1654 };
1655
1656 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store", params));
1657 }
1658
1659 // Preinitialize color attachment to green. Use a subpass with a dark blue attachment clear followed
1660 // by an alpha blender draw. Load op none preserves the preinitialized data and store op store
1661 // keeps the blended color inside the render area after the render pass.
1662 if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1663 {
1664 TestParams params{
1665 {// std::vector<AttachmentParams> attachments;
1666 {ATTACHMENT_USAGE_COLOR,
1667 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1668 VK_ATTACHMENT_STORE_OP_STORE,
1669 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1670 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1671 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1672 {{VK_IMAGE_ASPECT_COLOR_BIT, true, blend, true, green}}}},
1673 {// std::vector<SubpassParams> subpasses;
1674 {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u}},
1675 groupParams, // const SharedGroupParams groupParams;
1676 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1677 true, // bool alphaBlend;
1678 ExtensionPreference::KHR,
1679 };
1680
1681 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_store_alphablend", params));
1682 }
1683
1684 // Preinitialize attachments 0 and 1 to green. Attachment 0 contents inside render area is undefined because load op 'none'.
1685 // Subpass 0: draw a red rectangle inside attachment 0 overwriting all undefined values.
1686 // Subpass 1: use the attachment 0 as input and add blue to it resulting in magenta. Write the results to attachment 1.
1687 // After the render pass attachment 0 contents inside the render area are undefined because of store op 'don't care',
1688 // but the outside area should still have the preinitialized content.
1689 // Attachment 1 should have the preinitialized green outside render area and magenta inside.
1690 if (!groupParams->useSecondaryCmdBuffer)
1691 {
1692 TestParams params{
1693 {// std::vector<AttachmentParams> attachments;
1694 {ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_INPUT,
1695 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1696 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1697 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1698 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1699 ATTACHMENT_INIT_PRE,
1700 {{VK_IMAGE_ASPECT_COLOR_BIT, false, green, true, green}}},
1701 {ATTACHMENT_USAGE_COLOR,
1702 VK_ATTACHMENT_LOAD_OP_LOAD,
1703 VK_ATTACHMENT_STORE_OP_STORE,
1704 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1705 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1706 ATTACHMENT_INIT_PRE,
1707 {{VK_IMAGE_ASPECT_COLOR_BIT, true, magenta, true, green}}}},
1708 {// std::vector<SubpassParams> subpasses;
1709 {{{0u, ATTACHMENT_USAGE_COLOR}}, 1u},
1710 {{{0u, ATTACHMENT_USAGE_INPUT}, {1u, ATTACHMENT_USAGE_COLOR}}, 1u}},
1711 groupParams, // const SharedGroupParams groupParams;
1712 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1713 false, // bool alphaBlend;
1714 ExtensionPreference::EXT,
1715 };
1716
1717 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_dontcare", params));
1718 }
1719
1720 // Preinitialize color attachment to green. Use a render pass with load and store ops none for a multisample color
1721 // target. Write a red rectangle and check it ends up in the resolved buffer even though the multisample attachment
1722 // doesn't store the results.
1723 if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1724 {
1725 TestParams params{
1726 {// std::vector<AttachmentParams> attachments;
1727 {ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_MULTISAMPLE | ATTACHMENT_USAGE_INTEGER,
1728 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1729 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1730 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1731 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1732 ATTACHMENT_INIT_PRE,
1733 {}},
1734 {ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_RESOLVE_TARGET | ATTACHMENT_USAGE_INTEGER,
1735 VK_ATTACHMENT_LOAD_OP_LOAD,
1736 VK_ATTACHMENT_STORE_OP_STORE,
1737 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1738 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1739 ATTACHMENT_INIT_PRE,
1740 {{VK_IMAGE_ASPECT_COLOR_BIT, true, redUint, true, greenUint}}}},
1741 {// std::vector<SubpassParams> subpasses;
1742 {{{0u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_MULTISAMPLE | ATTACHMENT_USAGE_INTEGER},
1743 {1u, ATTACHMENT_USAGE_COLOR | ATTACHMENT_USAGE_RESOLVE_TARGET}},
1744 1u}},
1745 groupParams, // const SharedGroupParams groupParams;
1746 VK_FORMAT_UNDEFINED, // VkFormat depthStencilFormat;
1747 false, // bool alphaBlend;
1748 ExtensionPreference::KHR,
1749 };
1750
1751 opNoneTests->addChild(new LoadStoreOpNoneTest(testCtx, "color_load_op_none_store_op_none_resolve", params));
1752 }
1753
1754 if (groupParams->pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
1755 {
1756 std::vector<VkFormat> formats = {VK_FORMAT_D16_UNORM, VK_FORMAT_D32_SFLOAT,
1757 VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT,
1758 VK_FORMAT_D32_SFLOAT_S8_UINT, VK_FORMAT_S8_UINT};
1759
1760 for (uint32_t f = 0; f < formats.size(); ++f)
1761 {
1762 const auto tcuFormat = mapVkFormat(formats[f]);
1763 const bool hasDepth = tcu::hasDepthComponent(tcuFormat.order);
1764 const bool hasStencil = tcu::hasStencilComponent(tcuFormat.order);
1765 const std::string formatName = getFormatCaseName(formats[f]);
1766
1767 // Preinitialize attachment 0 (color) to green and attachment 1 (depth) to 0.5.
1768 // Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update
1769 // depth buffer to 1.0.
1770 // This is followed by another draw with a blue rectangle using the same depth of 1.0. This time
1771 // the depth test fails and nothing is written.
1772 // After the renderpass the red color should remain inside the render area of the color buffer.
1773 // Store op 'none' for depth buffer makes the written values undefined, but the pixels outside
1774 // render area should still contain the original value of 0.5.
1775 if (hasDepth)
1776 {
1777 TestParams params{
1778 {// std::vector<AttachmentParams> attachments;
1779 {ATTACHMENT_USAGE_COLOR,
1780 VK_ATTACHMENT_LOAD_OP_LOAD,
1781 VK_ATTACHMENT_STORE_OP_STORE,
1782 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1783 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1784 ATTACHMENT_INIT_PRE,
1785 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1786 {ATTACHMENT_USAGE_DEPTH,
1787 VK_ATTACHMENT_LOAD_OP_LOAD,
1788 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1789 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1790 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1791 ATTACHMENT_INIT_PRE,
1792 {{VK_IMAGE_ASPECT_DEPTH_BIT, false, depthInit, true, depthInit}}}},
1793 {// std::vector<SubpassParams> subpasses;
1794 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 2u}},
1795 groupParams, // const SharedGroupParams groupParams;
1796 formats[f], // VkFormat depthStencilFormat;
1797 false, // bool alphaBlend;
1798 f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
1799 };
1800
1801 opNoneTests->addChild(
1802 new LoadStoreOpNoneTest(testCtx, "depth_" + formatName + "_load_op_load_store_op_none", params));
1803 }
1804
1805 // Preinitialize depth attachment to 0.5. Use a render pass with load and store ops none for the depth, but
1806 // disable depth test which also disables depth writes. The depth attachment should have the original
1807 // preinitialized value after the render pass.
1808 if (hasDepth)
1809 {
1810 TestParams params{
1811 {// std::vector<AttachmentParams> attachments;
1812 {ATTACHMENT_USAGE_COLOR,
1813 VK_ATTACHMENT_LOAD_OP_LOAD,
1814 VK_ATTACHMENT_STORE_OP_STORE,
1815 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1816 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1817 ATTACHMENT_INIT_PRE,
1818 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1819 {ATTACHMENT_USAGE_DEPTH,
1820 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1821 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1822 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1823 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1824 ATTACHMENT_INIT_PRE,
1825 {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit}}}},
1826 {// std::vector<SubpassParams> subpasses;
1827 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH | ATTACHMENT_USAGE_DEPTH_TEST_OFF}},
1828 1u}},
1829 groupParams, // const SharedGroupParams groupParams;
1830 formats[f], // VkFormat depthStencilFormat;
1831 false, // bool alphaBlend;
1832 f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
1833 };
1834
1835 opNoneTests->addChild(new LoadStoreOpNoneTest(
1836 testCtx, "depth_" + formatName + "_load_op_none_store_op_none_write_off", params));
1837 }
1838
1839 // Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25
1840 // using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update
1841 // depth buffer to 1.0. After the renderpass the color buffer should have red inside the render area and depth should have the
1842 // shader updated value of 1.0.
1843 if (hasDepth)
1844 {
1845 TestParams params{
1846 {// std::vector<AttachmentParams> attachments;
1847 {ATTACHMENT_USAGE_COLOR,
1848 VK_ATTACHMENT_LOAD_OP_LOAD,
1849 VK_ATTACHMENT_STORE_OP_STORE,
1850 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1851 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1852 ATTACHMENT_INIT_PRE,
1853 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1854 {ATTACHMENT_USAGE_DEPTH,
1855 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1856 VK_ATTACHMENT_STORE_OP_STORE,
1857 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1858 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1859 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1860 {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit}}}},
1861 {// std::vector<SubpassParams> subpasses;
1862 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u}},
1863 groupParams, // const SharedGroupParams groupParams;
1864 formats[f], // VkFormat depthStencilFormat;
1865 false, // bool alphaBlend;
1866 f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
1867 };
1868
1869 opNoneTests->addChild(
1870 new LoadStoreOpNoneTest(testCtx, "depth_" + formatName + "_load_op_none_store_op_store", params));
1871 }
1872
1873 // Preinitialize attachment 0 (color) to green and depth buffer to 0.5. During the render pass initialize attachment 1 (depth) to 0.25
1874 // using cmdClearAttachments. Draw a red rectangle using depth 1.0 and depth op 'greater' which will pass.
1875 // After the renderpass the color buffer should have red inside the render area. Depth buffer contents inside render
1876 // area is undefined because of store op 'don't care', but the outside should have the original value of 0.5.
1877 if (hasDepth)
1878 {
1879 TestParams params{
1880 {// std::vector<AttachmentParams> attachments;
1881 {ATTACHMENT_USAGE_COLOR,
1882 VK_ATTACHMENT_LOAD_OP_LOAD,
1883 VK_ATTACHMENT_STORE_OP_STORE,
1884 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1885 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1886 ATTACHMENT_INIT_PRE,
1887 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1888 {ATTACHMENT_USAGE_DEPTH,
1889 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1890 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1891 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1892 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1893 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
1894 {{VK_IMAGE_ASPECT_DEPTH_BIT, false, depthFull, true, depthInit}}}},
1895 {// std::vector<SubpassParams> subpasses;
1896 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_DEPTH}}, 1u}},
1897 groupParams, // const SharedGroupParams groupParams;
1898 formats[f], // VkFormat depthStencilFormat;
1899 false, // bool alphaBlend;
1900 f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
1901 };
1902
1903 opNoneTests->addChild(new LoadStoreOpNoneTest(
1904 testCtx, "depth_" + formatName + "_load_op_none_store_op_dontcare", params));
1905 }
1906
1907 // Preinitialize attachment 0 (color) to green and attachment 1 (stencil) to 128.
1908 // Draw a red rectangle using stencil testing with compare op 'greater' and reference of 255. The stencil test
1909 // will pass. This is followed by another draw with a blue rectangle using the same stencil settings. This time
1910 // the stencil test fails and nothing is written.
1911 // After the renderpass the red color should remain inside the render area of the color buffer.
1912 // Store op 'none' for stencil buffer makes the written values undefined, but the pixels outside
1913 // render area should still contain the original value of 128.
1914 if (hasStencil)
1915 {
1916 TestParams params{
1917 {// std::vector<AttachmentParams> attachments;
1918 {ATTACHMENT_USAGE_COLOR,
1919 VK_ATTACHMENT_LOAD_OP_LOAD,
1920 VK_ATTACHMENT_STORE_OP_STORE,
1921 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1922 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1923 ATTACHMENT_INIT_PRE,
1924 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1925 {ATTACHMENT_USAGE_STENCIL,
1926 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1927 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1928 VK_ATTACHMENT_LOAD_OP_LOAD,
1929 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1930 ATTACHMENT_INIT_PRE,
1931 {{VK_IMAGE_ASPECT_STENCIL_BIT, false, stencilInit, true, stencilInit}}}},
1932 {// std::vector<SubpassParams> subpasses;
1933 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 2u}},
1934 groupParams, // const SharedGroupParams groupParams;
1935 formats[f], // VkFormat depthStencilFormat;
1936 false, // bool alphaBlend;
1937 f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
1938 };
1939
1940 opNoneTests->addChild(
1941 new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_load_store_op_none", params));
1942 }
1943
1944 // Preinitialize stencil attachment to 128. Use a render pass with load and store ops none for the stencil, but
1945 // disable stencil test which also disables stencil writes. The stencil attachment should have the original
1946 // preinitialized value after the render pass.
1947 if (hasStencil)
1948 {
1949 TestParams params{
1950 {// std::vector<AttachmentParams> attachments;
1951 {ATTACHMENT_USAGE_COLOR,
1952 VK_ATTACHMENT_LOAD_OP_LOAD,
1953 VK_ATTACHMENT_STORE_OP_STORE,
1954 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1955 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1956 ATTACHMENT_INIT_PRE,
1957 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1958 {ATTACHMENT_USAGE_STENCIL,
1959 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1960 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1961 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1962 VK_ATTACHMENT_STORE_OP_NONE_EXT,
1963 ATTACHMENT_INIT_PRE,
1964 {{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit}}}},
1965 {// std::vector<SubpassParams> subpasses;
1966 {{{0u, ATTACHMENT_USAGE_COLOR},
1967 {1u, ATTACHMENT_USAGE_STENCIL | ATTACHMENT_USAGE_STENCIL_TEST_OFF |
1968 ATTACHMENT_USAGE_DEPTH_TEST_OFF}},
1969 1u}},
1970 groupParams, // const SharedGroupParams groupParams;
1971 formats[f], // VkFormat depthStencilFormat;
1972 false, // bool alphaBlend;
1973 f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
1974 };
1975
1976 opNoneTests->addChild(new LoadStoreOpNoneTest(
1977 testCtx, "stencil_" + formatName + "_load_op_none_store_op_none_write_off", params));
1978 }
1979
1980 // Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64
1981 // using cmdClearAttachments. Draw a red rectangle using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update
1982 // stencil buffer to 255. After the renderpass the color buffer should have red inside the render area and stencil should have the
1983 // shader updated value of 255.
1984 if (hasStencil)
1985 {
1986 TestParams params{
1987 {// std::vector<AttachmentParams> attachments;
1988 {ATTACHMENT_USAGE_COLOR,
1989 VK_ATTACHMENT_LOAD_OP_LOAD,
1990 VK_ATTACHMENT_STORE_OP_STORE,
1991 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1992 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1993 ATTACHMENT_INIT_PRE,
1994 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
1995 {ATTACHMENT_USAGE_STENCIL,
1996 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
1997 VK_ATTACHMENT_STORE_OP_DONT_CARE,
1998 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
1999 VK_ATTACHMENT_STORE_OP_STORE,
2000 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
2001 {{VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit}}}},
2002 {// std::vector<SubpassParams> subpasses;
2003 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u}},
2004 groupParams, // const SharedGroupParams groupParams;
2005 formats[f], // VkFormat depthStencilFormat;
2006 false, // bool alphaBlend;
2007 f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
2008 };
2009
2010 opNoneTests->addChild(
2011 new LoadStoreOpNoneTest(testCtx, "stencil_" + formatName + "_load_op_none_store_op_store", params));
2012 }
2013
2014 // Preinitialize attachment 0 (color) to green and stencil buffer to 128. During the render pass initialize attachment 1 (stencil) to 64
2015 // using cmdClearAttachments. Draw a red rectangle using stencil reference 255 and stencil op 'greater' which will pass.
2016 // After the renderpass the color buffer should have red inside the render area. Stencil buffer contents inside render
2017 // are is undefined because of store op 'don't care', but the outside should have the original value of 128.
2018 if (hasStencil)
2019 {
2020 TestParams params{
2021 {// std::vector<AttachmentParams> attachments;
2022 {ATTACHMENT_USAGE_COLOR,
2023 VK_ATTACHMENT_LOAD_OP_LOAD,
2024 VK_ATTACHMENT_STORE_OP_STORE,
2025 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2026 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2027 ATTACHMENT_INIT_PRE,
2028 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2029 {ATTACHMENT_USAGE_STENCIL,
2030 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2031 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2032 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2033 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2034 ATTACHMENT_INIT_PRE | ATTACHMENT_INIT_CMD_CLEAR,
2035 {{VK_IMAGE_ASPECT_STENCIL_BIT, false, stencilFull, true, stencilInit}}}},
2036 {// std::vector<SubpassParams> subpasses;
2037 {{{0u, ATTACHMENT_USAGE_COLOR}, {1u, ATTACHMENT_USAGE_STENCIL}}, 1u}},
2038 groupParams, // const SharedGroupParams groupParams;
2039 formats[f], // VkFormat depthStencilFormat;
2040 false, // bool alphaBlend;
2041 f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
2042 };
2043
2044 opNoneTests->addChild(new LoadStoreOpNoneTest(
2045 testCtx, "stencil_" + formatName + "_load_op_none_store_op_dontcare", params));
2046 }
2047
2048 // Preinitialize attachment 0 (color) to green and depth stencil buffer depth aspect to 0.5 and stencil aspect to 128. Draw a red
2049 // rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update depth buffer to 1.0. After the renderpass the
2050 // color buffer should have red inside the render area and depth should have the shader updated value of 1.0. Stencil has load and
2051 // store ops none, and stencil writes are disabled by disabling stencil test. Therefore, stencil should not be modified even when
2052 // the depth aspect is written.
2053 if (hasDepth && hasStencil)
2054 {
2055 TestParams params{
2056 {// std::vector<AttachmentParams> attachments;
2057 {ATTACHMENT_USAGE_COLOR,
2058 VK_ATTACHMENT_LOAD_OP_LOAD,
2059 VK_ATTACHMENT_STORE_OP_STORE,
2060 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2061 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2062 ATTACHMENT_INIT_PRE,
2063 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2064 {ATTACHMENT_USAGE_DEPTH_STENCIL,
2065 VK_ATTACHMENT_LOAD_OP_LOAD,
2066 VK_ATTACHMENT_STORE_OP_STORE,
2067 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2068 VK_ATTACHMENT_STORE_OP_NONE_EXT,
2069 ATTACHMENT_INIT_PRE,
2070 {
2071 {VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit},
2072 {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit},
2073 }}},
2074 {// std::vector<SubpassParams> subpasses;
2075 {{{0u, ATTACHMENT_USAGE_COLOR},
2076 {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_STENCIL_TEST_OFF}},
2077 1u}},
2078 groupParams, // const SharedGroupParams groupParams;
2079 formats[f], // VkFormat depthStencilFormat;
2080 false, // bool alphaBlend;
2081 f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
2082 };
2083
2084 opNoneTests->addChild(new LoadStoreOpNoneTest(
2085 testCtx,
2086 "depthstencil_" + formatName +
2087 "_load_op_depth_load_stencil_none_store_op_depth_store_stencil_none_stencil_test_off",
2088 params));
2089 }
2090
2091 // Preinitialize attachment 0 (color) to green and depth stencil buffer stencil aspect to 128 and depth aspect to 0.5. Draw a red rectangle
2092 // using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update stencil buffer to 255. After the renderpass
2093 // 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
2094 // ops none, and depth writes are disabled by having depth test off. Therefore, depth should not be modified even when the stencil aspect is
2095 // written.
2096 if (hasDepth && hasStencil)
2097 {
2098 TestParams params{
2099 {// std::vector<AttachmentParams> attachments;
2100 {ATTACHMENT_USAGE_COLOR,
2101 VK_ATTACHMENT_LOAD_OP_LOAD,
2102 VK_ATTACHMENT_STORE_OP_STORE,
2103 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2104 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2105 ATTACHMENT_INIT_PRE,
2106 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2107 {ATTACHMENT_USAGE_DEPTH_STENCIL,
2108 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2109 VK_ATTACHMENT_STORE_OP_NONE_EXT,
2110 VK_ATTACHMENT_LOAD_OP_LOAD,
2111 VK_ATTACHMENT_STORE_OP_STORE,
2112 ATTACHMENT_INIT_PRE,
2113 {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit},
2114 {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit}}}},
2115 {// std::vector<SubpassParams> subpasses;
2116 {{{0u, ATTACHMENT_USAGE_COLOR},
2117 {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_DEPTH_TEST_OFF}},
2118 1u}},
2119 groupParams, // const SharedGroupParams groupParams;
2120 formats[f], // VkFormat depthStencilFormat;
2121 false, // bool alphaBlend;
2122 f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
2123 };
2124
2125 opNoneTests->addChild(new LoadStoreOpNoneTest(
2126 testCtx,
2127 "depthstencil_" + formatName +
2128 "_load_op_depth_none_stencil_load_store_op_depth_none_stencil_store_depth_test_off",
2129 params));
2130 }
2131
2132 // Preinitialize attachment 0 (color) to green and depth stencil buffer depth aspect to 0.5 and stencil aspect to 128. Draw a red
2133 // rectangle using depth 1.0 and depth op 'greater'. Depth test will pass and update depth buffer to 1.0. After the renderpass the
2134 // color buffer should have red inside the render area and depth should have the shader updated value of 1.0. Stencil has load and
2135 // store ops none, and stencil writes are disabled. Therefore, stencil should not be modified even when the depth aspect is written.
2136 if (hasDepth && hasStencil)
2137 {
2138 TestParams params{
2139 {// std::vector<AttachmentParams> attachments;
2140 {ATTACHMENT_USAGE_COLOR,
2141 VK_ATTACHMENT_LOAD_OP_LOAD,
2142 VK_ATTACHMENT_STORE_OP_STORE,
2143 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2144 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2145 ATTACHMENT_INIT_PRE,
2146 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2147 {ATTACHMENT_USAGE_DEPTH_STENCIL,
2148 VK_ATTACHMENT_LOAD_OP_LOAD,
2149 VK_ATTACHMENT_STORE_OP_STORE,
2150 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2151 VK_ATTACHMENT_STORE_OP_NONE_EXT,
2152 ATTACHMENT_INIT_PRE,
2153 {
2154 {VK_IMAGE_ASPECT_DEPTH_BIT, true, depthFull, true, depthInit},
2155 {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilInit, true, stencilInit},
2156 }}},
2157 {// std::vector<SubpassParams> subpasses;
2158 {{{0u, ATTACHMENT_USAGE_COLOR},
2159 {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_STENCIL_WRITE_OFF}},
2160 1u}},
2161 groupParams, // const SharedGroupParams groupParams;
2162 formats[f], // VkFormat depthStencilFormat;
2163 false, // bool alphaBlend;
2164 f % 2 == 0 ? ExtensionPreference::EXT : ExtensionPreference::KHR,
2165 };
2166
2167 opNoneTests->addChild(new LoadStoreOpNoneTest(
2168 testCtx,
2169 "depthstencil_" + formatName +
2170 "_load_op_depth_load_stencil_none_store_op_depth_store_stencil_none_stencil_write_off",
2171 params));
2172 }
2173
2174 // Preinitialize attachment 0 (color) to green and depth stencil buffer stencil aspect to 128 and depth aspect to 0.5. Draw a red rectangle
2175 // using stencil reference of 255 and stencil op 'greater'. Stencil test will pass and update stencil buffer to 255. After the renderpass
2176 // 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
2177 // 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
2178 // writes are disabled, so depth should not be modified even when the stencil aspect is written.
2179 if (hasDepth && hasStencil)
2180 {
2181 TestParams params{
2182 {// std::vector<AttachmentParams> attachments;
2183 {ATTACHMENT_USAGE_COLOR,
2184 VK_ATTACHMENT_LOAD_OP_LOAD,
2185 VK_ATTACHMENT_STORE_OP_STORE,
2186 VK_ATTACHMENT_LOAD_OP_DONT_CARE,
2187 VK_ATTACHMENT_STORE_OP_DONT_CARE,
2188 ATTACHMENT_INIT_PRE,
2189 {{VK_IMAGE_ASPECT_COLOR_BIT, true, red, true, green}}},
2190 {ATTACHMENT_USAGE_DEPTH_STENCIL,
2191 VK_ATTACHMENT_LOAD_OP_NONE_EXT,
2192 VK_ATTACHMENT_STORE_OP_NONE_EXT,
2193 VK_ATTACHMENT_LOAD_OP_LOAD,
2194 VK_ATTACHMENT_STORE_OP_STORE,
2195 ATTACHMENT_INIT_PRE,
2196 {{VK_IMAGE_ASPECT_DEPTH_BIT, true, depthInit, true, depthInit},
2197 {VK_IMAGE_ASPECT_STENCIL_BIT, true, stencilFull, true, stencilInit}}}},
2198 {// std::vector<SubpassParams> subpasses;
2199 {{{0u, ATTACHMENT_USAGE_COLOR},
2200 {1u, ATTACHMENT_USAGE_DEPTH_STENCIL | ATTACHMENT_USAGE_DEPTH_WRITE_OFF}},
2201 1u}},
2202 groupParams, // const SharedGroupParams groupParams;
2203 formats[f], // VkFormat depthStencilFormat;
2204 false, // bool alphaBlend;
2205 f % 2 == 0 ? ExtensionPreference::KHR : ExtensionPreference::EXT,
2206 };
2207
2208 opNoneTests->addChild(new LoadStoreOpNoneTest(
2209 testCtx,
2210 "depthstencil_" + formatName +
2211 "_load_op_depth_none_stencil_load_store_op_depth_none_stencil_store_depth_write_off",
2212 params));
2213 }
2214 } // for over DS formats
2215 }
2216 return opNoneTests.release();
2217 }
2218
2219 } // namespace renderpass
2220 } // namespace vkt
2221