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