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