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