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